ANSI C Based OPC UA Client/Server/PubSub SDK  1.9.3.467
Lesson 3: Write Values

This lesson describes how to use Write Service.

Files used in this lesson:

Step 1: Write Service Call

To call Write Service, the parameters for the Write Service as defined in the OPC UA Specification are passed to UaClient_Session_BeginWrite. The Request Header is omitted because it is handled by the SDK. To influence its values, the UaClient_ServiceSettings can be given as an argument. Additional arguments are the session, the callback function to call upon completion, and user data. The user data is passed only to the callback of this particular service invocation, allowing to distinguish multiple concurrent calls to the same service using the same callback function. This Sample Client does not need to pass user data this way, as it only requires the user data attached to the session available in the callback.

OpcUa_StatusCode Sample_Write(UaClient_Session* a_pSession)
{
OpcUa_Int32 numNodesToWrite = 1;
OpcUa_WriteValue nodesToWrite[1];
OpcUa_InitializeStatus(OpcUa_Module_Client, "Sample_Write");
OpcUa_WriteValue_Initialize(&nodesToWrite[0]);
nodesToWrite[0].AttributeId = OpcUa_Attributes_Value;
nodesToWrite[0].NodeId.NamespaceIndex = 4;
OpcUa_String_StrnCpy(&nodesToWrite[0].NodeId.Identifier.String, OpcUa_String_FromCString("Demo.Static.Scalar.Int32"), OPCUA_STRING_LENDONTCARE);
nodesToWrite[0].Value.Value.Datatype = OpcUaType_Int32;
nodesToWrite[0].Value.Value.ArrayType = OpcUa_VariantArrayType_Scalar;
nodesToWrite[0].Value.Value.Value.Int32 = 6789;
uStatus = UaClient_Session_BeginWrite(a_pSession, /* Session */
OpcUa_Null, /* ServiceSettings */
numNodesToWrite, /* NoOfNodesToWrite */
nodesToWrite, /* NodesToWrite */
Sample_Write_CB, /* Callback Function */
OpcUa_Null); /* Callback UserData */
OpcUa_GotoErrorIfBad(uStatus);
OpcUa_WriteValue_Clear(&nodesToWrite[0]);
OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;
OpcUa_WriteValue_Clear(&nodesToWrite[0]);
OpcUa_FinishErrorHandling;
}

Step 2: Write Service Callback

Sample_Write_CB implements the callback for the Write service and gets called with the results of the service call.

OpcUa_Void Sample_Write_CB(const UaClient_Session *a_pSession,
OpcUa_ResponseHeader *a_pResponseHeader,
OpcUa_Int32 a_NoOfResults,
OpcUa_StatusCode *a_pResults,
OpcUa_Int32 a_NoOfDiagnosticInfos,
OpcUa_DiagnosticInfo *a_pDiagnosticInfos,
OpcUa_Void *a_pUserData)
{
SampleClientContext *pClientContext = a_pSession->pUserData;
OpcUa_ReferenceParameter(a_NoOfDiagnosticInfos);
OpcUa_ReferenceParameter(a_pDiagnosticInfos);
OpcUa_ReferenceParameter(a_pUserData);
if (OpcUa_IsGood(a_pResponseHeader->ServiceResult))
{
OpcUa_Int32 i;
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Sample_Write_CB:\n");
for (i = 0; i < a_NoOfResults; i++)
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " [%i]:\n", i);
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, " Status: 0x%08x\n", a_pResults[i]);
}
if (pClientContext->State == State_Write)
pClientContext->State = State_WriteDone;
else
pClientContext->State = State_Error;
}
else
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Sample_Write_CB failed (0x%08x)\n", a_pResponseHeader->ServiceResult);
pClientContext->State = State_Error;
}
}

Step 3: Integration in Main loop

while (!(bComplete && pSession->ConnectionStatus == UaClient_ConnectionStatus_Disconnected))
{
/* process sample state machine */
switch (clientContext.State)
{
case State_Idle:
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "UA Client: Connecting to %s ...\n", SERVER_ENDPOINT_URL);
uStatus = UaClient_Session_BeginConnect(pSession);
OpcUa_GotoErrorIfBad(uStatus);
clientContext.State = State_Connect;
break;
case State_Connected:
uStatus = Sample_Browse(pSession, OpcUa_Null);
OpcUa_GotoErrorIfBad(uStatus);
clientContext.State = State_Browse;
break;
case State_BrowseDone:
uStatus = Sample_Write(pSession);
OpcUa_GotoErrorIfBad(uStatus);
clientContext.State = State_Write;
break;
case State_WriteDone:
uStatus = UaClient_Session_BeginDisconnect(pSession, OpcUa_False);
OpcUa_GotoErrorIfBad(uStatus);
clientContext.State = State_Disconnect;
break;
case State_Disconnected:
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "Sample successfully completed. Terminating now.\n");
bComplete = OpcUa_True;
break;
case State_Error:
uStatus = UaClient_Session_BeginDisconnect(pSession, OpcUa_True);
if (OpcUa_IsBad(uStatus) && uStatus != OpcUa_BadInvalidState) {OpcUa_GotoError;}
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "An error occured. Terminating now.\n");
bComplete = OpcUa_True;
break;
default:
break;
}
/* Process Ua Client events */
uStatus = UaBase_DoCom();
if (OpcUa_IsBad(uStatus))
{
OpcUa_Trace(OPCUA_TRACE_LEVEL_WARNING, "UaBase_DoCom failed (0x%08x)\n", uStatus);
bComplete = OpcUa_True;
}
}