FORUM CTRLX AUTOMATION
ctrlX World Partner Apps for ctrlX AUTOMATION
Dear Community User! We are updating our platform to a new
system.
Read more: Important
information on the platform change.
11-11-2022 06:09 PM
I would like to control the OPC UA Client App connect/disconnect from the PLC. I also want to read the client state to verify that the connect/disconnect occured. I have tried various fbs like DL_ReadNode, DL_ReadNodeValue, etc. but the data types are not correct and I get errors. When I try to write, to trigger the connect or disconnect commands, I get an error, 16#0D0A0201 that I cannot find in the documentation:
Are there any examples of how to do this? I have seen some other examples in the forum but they are associated with other function blocks that exist, like motion function blocks. How can I read/write objects (they look like JSON objects) in the datalayer from the PLC?
Solved! Go to Solution.
11-14-2022 02:09 AM
Although I have not tested, I see the document R911403768_ 06. There are related contents and cases for your reference.
11-14-2022 09:34 AM
After adding a client, in my case done via ctrlX CORE WebUI using:
{
"name":"Test",
"endpointUrl":"opc.tcp://127.0.0.1",
"sessionConfiguration":{
"userToken":{"userIdentityToken_type":"TokenAnonymous",
"userIdentityToken":{}},
"messageSecurityMode":{
"messageSecurityMode":"BESTAVAILABLE"},
"securityPolicy":{"securityPolicy":"BESTAVAILABLE"},
"localeIds":["en-US"]}
}
You can see for each method which data type needs to send to this node and how it is structured. For "Connect" and "Disconnect" it is just an empty write. See "Operations" = "write" and "References" = "":
Declaration:
PROGRAM OPCUa_Client
VAR
fbDL_WriteNode : DL_WriteNode;
bExecute: BOOL;
bDone: BOOL;
bActive: BOOL;
bError: BOOL;
ErrorID: CXA_Datalayer.ERROR_CODE;
ErrorIdent: CXA_Datalayer.ERROR_STRUCT;
strNodeName: STRING(255) := 'opcuaclient/Test/connect'; //'opcuaclient/Test/disconnect'
END_VAR
Implementation:
fbDL_WriteNode(
Execute:= bExecute,
Done=> bDone,
Active=> bActive,
Error=> bError,
ErrorID=> ErrorID,
ErrorIdent=> ErrorIdent,
ClientId:= ,
NodeName:= strNodeName,
Value:= );
Reading the state means reading an object of the type "types/opcuaclient/state". This is done via a flatbuffer:
Declaration:
PROGRAM OPCUa_Client
VAR
fbClientState: CXA_OpcUaClient_fbs.comm_opcua_client_State; //Flatbuffer function out of CXA_Automationcore_fbs
fbDL_ReadNodeValue: DL_ReadNodeValue; //Funktion block to read an flatbuffer out of CXA_Datalayer
bReadExecute: BOOL;
bReadDone: BOOL;
bReadActive: BOOL;
bReadError: BOOL;
ReadErrorID: CXA_Datalayer.ERROR_CODE;
ReadErrorIdent: CXA_Datalayer.ERROR_STRUCT;
DataRead: CXA_Datalayer.DL_NodeValue;
strState: CXA_OpcUaClient_fbs.comm_opcua_client_ConnectionState;
END_VAR
Implementation:
fbDL_ReadNodeValue(
Execute:= bReadExecute,
Done=> bReadDone,
Active=> bReadActive,
Error=> bReadError,
ErrorID=> ReadErrorID,
ErrorIdent=> ReadErrorIdent,
ClientId:= ,
NodeName:= 'opcuaclient/Test/state',
NodeValue:= DataRead);
IF fbDL_ReadNodeValue.Done THEN
fbClientState.getRootAsState(data:= DataRead.GetData(), size:= DataRead.GetSize());
strState := fbClientState.getState();
END_IF
01-18-2023 09:06 PM
The read of the state works well. Thank you!
I am still having a problem with the Write of the Connect or Disconnect. It seems from your example that there is no value needed for the "Value" input, that simply writing to 'opcuaclient/xxxx/connect' is enough. But when this did not work, I tried a boolean value. This resulted in the same errors displayed below. The error codes, 0D0A0201 with 80E50000, are not documented that I can find. This is the same problem I had in my previous attempt though the error codes are now different.
Can you suggest what is wrong here? I attached an XML export of my POU.
01-18-2023 09:50 PM
This error stopped occurring after a power cycle. I cannot explain it past that. The system had been powered on for months and this was probably the first power cycle in some time. The original code in the solution above works now and the "write" to 'connect' or 'disconnect' does not require an actual value or variable in the "Value" input of the function block.