I'm testing Eclipse Milo (Version 0.1.5) to communicate as a client with the OPC UA server of a TwinCAT PLC. My java program acts as a kind of middleware. It reads structures from a TwinCAT OPC UA server, puts their values into a JSON and sends it to an other server.
For testing I created in the PLC a sample struct with two variables:
stSimpleStruct (Structure definiend in PLC)
- bVar1 (boolean)
- fVar2 (float)
Picture of Struct in TwinCAT
If I read the node, the value is an ExtensionObject encoded as ByteString. The values of the structure variables (bVar1 and fVar2) should be read and put into a JSON object. So the result is something like this:
{
“bVar1” : false,
“fVar2” : 0
}
The structure above is just an example. The structures to be read are only known at runtime. How can I decode the binary ExtensionObject to get access to the values of the structure variables?
Here is my code:
// Get endpoints
String endpointURL = "opc.tcp://172.20.1.1:4840";
EndpointDescription[] endpoints = UaTcpStackClient.getEndpoints(endpointURL).get();
logger.info("Available endpoint:");
for (EndpointDescription endpoint : endpoints)
{
logger.info("{} Security: {}", endpoint.getEndpointUrl(), endpoint.getSecurityPolicyUri());
}
// Chose endpoint
SecurityPolicy securityPolicy = SecurityPolicy.None;
EndpointDescription endpoint = Arrays.stream(endpoints)
.filter(e -> e.getSecurityPolicyUri().equals(securityPolicy.getSecurityPolicyUri()))
.findFirst()
.orElseThrow(() -> new Exception("No desired endpoints returned"));
logger.info("Using endpoint: {} [{}]", endpoint.getEndpointUrl(), SecurityPolicy.None);
// Create client config
OpcUaClientConfig config = OpcUaClientConfig.builder()
.setApplicationName(LocalizedText.english("TestApplication"))
.setEndpoint(endpoint)
.setRequestTimeout(uint(5000))
.build();
OpcUaClient client = new OpcUaClient(config);
// Synchronous connect
client.connect().get();
// Read struct
NodeId nodeId = new NodeId(4, "MAIN.stSimpleStruct");
VariableNode node = client.getAddressSpace().createVariableNode(nodeId);
DataValue value = node.readValue().get();
ExtensionObject extensionObject = (ExtensionObject) value.getValue().getValue();