今天研究了一下OPC UA milo中有关数组数据的写入,算是对之前的数据写入的一个补充。
首先我们先定义一个数组的节点
这里是通过opcua-modeler来建立节点对象。主要是设置ValueRank为OneDimension,然后AccessLevel的读写都要圈上。
启动Server。至于结点解析可以看我上一篇。
我们在官方的WriteExample中修改一点:
public class WriteExample implements ClientExample {
public static void main(String[] args) throws Exception {
WriteExample example = new WriteExample();
// 这里改成false表示用本地Server运行
new ClientExampleRunner(example, false).run();
}
private final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void run(OpcUaClient client, CompletableFuture<OpcUaClient> future) throws Exception {
// synchronous connect
client.connect().get();
//这个是节点的NodeId
List<NodeId> nodeIds = ImmutableList.of(new NodeId(2, 139));
for (int i = 0; i < 10; i++) {
// 这里是需要写入的数据,注意要把集合转换成对应类型的数组
String[] array = ImmutableList.of(String.valueOf(i), String.valueOf(i + 1)).toArray(new String[0]);
//milo的所有类型数据都用Variant包装
Variant v = new Variant(array);
// 再转换成DataValue
// 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));
}
}
future.complete(client);
}
}
总结:
- 最主要的是要设置正确数据的数组范围,即ValueRank
- 传入的数据必须是数组,然后类型要与OPC 结点的数据类型匹配