问题描述
我想做一个测试,通过opc ua milo客户端将“1”写入kepware(PLC)地址。我从 GitHub 获取客户端,URL 是 https://github.com/eclipse/milo 。但我总是得到不准确的信息,就像这样:
[main] 信息 o.e.m.examples.client.WriteExample - 状态代码{name=Bad_NodeIdUnkNown,value=0x80340000,quality=bad}
同时,我可以成功地从 kepware(PLC) 读取数据。
我的 opc 标记名是“AFSM010_WriteRFID”,通道名是“FE6”,设备名是“AFSM”。那么,NodeId 的第二个参数是什么? ??
public class WriteExample implements ClientExample {
public static void main(String[] args) throws Exception {
WriteExample example = new WriteExample();
new ClientExampleRunner(example).run();
}
private final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void run(OpcuaClient client,CompletableFuture<OpcuaClient> future) throws Exception {
// synchronous connect
client.connect().get();
// List<NodeId> nodeIds = ImmutableList.of(new NodeId(2,"HelloWorld/ScalarTypes/Int32"));
// NodeId nodeId_Tag1 = new NodeId(3,"FE6.AFSM.AFSM010_WriteRFID");
NodeId nodeId_Tag1 = new NodeId(3,"AFSM010_WriteRFID");
List<NodeId> nodeIds = ImmutableList.of(nodeId_Tag1);
// for (int i = 0; i < 10; i++) {
Variant v = new Variant(5);
// don't write status or timestamps
DataValue dv = new DataValue(v,null,null);
// write asynchronously....
CompletableFuture<List<StatusCode>> f =
client.writeValues(nodeIds,ImmutableList.of(dv));
// ...but block for the results so we write in order
List<StatusCode> statusCodes = f.get();
StatusCode status = statusCodes.get(0);
if (status.isGood()) {
logger.info("Wrote '{}' to nodeId={}",v,nodeIds.get(0));
}
logger.info("this is the end : status " + status.toString());
// }
future.complete(client);
}
}
解决方法
我建议您使用 UaExpert 等客户端连接到 Kepware 并浏览地址空间,找到您感兴趣的节点,并查看 Kepware 如何格式化 NodeId。
每个服务器都有自己的“规则”来说明它如何制作 NodeId。您无法在不知道该服务器的规则的情况下仅通过知道“标签名称”来推导出 NodeId。
您应该通过浏览或通过一些您已经知道格式的带外机制来发现节点和节点 ID。