我正在测试 Eclipse Milo(版本 0.1.5)作为客户端与 TwinCAT PLC 的 OPC UA 服务器进行通信。我的 java 程序充当一种中间件。它从 TwinCAT OPC UA 服务器读取结构,将它们的值放入 JSON 并将其发送到其他服务器。
为了进行测试,我在 PLC 中创建了一个带有两个变量的示例结构:
stSimpleStruct(PLC 中的结构定义)
-bVar1(布尔)
-fVar2(浮点)
TwinCAT 中的结构图片
如果我读取节点,则该值是编码为 ByteString 的 ExtensionObject。应该读取结构变量(bVar1 和 fVar2)的值并将其放入 JSON 对象中。所以结果是这样的:
{
“bVar1” : false,
“fVar2” : 0
}
上面的结构只是一个例子。要读取的结构仅在运行时已知。如何解码二进制 ExtensionObject 以访问结构变量的值?
这是我的代码:
// 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();