java - 如何可靠地写入 OPC UA 服务器?
问题描述
我正在尝试将一些值写入 OPC UA 服务器。为了可靠地做到这一点,我可能需要知道我正在尝试写入的节点的数据类型,否则我似乎很容易出现数据类型不匹配的情况。
假设我的服务器有一个数据类型为 Int16 的节点 TestNodeOne
我的 API 被告知将值 3 写入该节点。现在我需要做出决定:我将 3 作为 Integer 还是作为 UShort 处理?为此,我似乎需要节点的数据类型。
我试过的
我的方法是浏览服务器并使用相应的数据类型创建所有节点的缓存。看起来是这样的:
// Recursively browse entire server
@SuppressWarnings("deprecation")
private HashMap<String, NodeId> browseNode(String indent, OpcUaClient client, NodeId browseRoot, HashMap<String, NodeId> nodesMap) {
BrowseDescription browse = new BrowseDescription(
browseRoot,
BrowseDirection.Forward,
Identifiers.References,
true, uint(NodeClass.Object.getValue() | NodeClass.Variable.getValue()),
uint(BrowseResultMask.All.getValue()));
try {
BrowseResult browseResult = client.browse(browse).get();
List<ReferenceDescription> references = toList(browseResult.getReferences());
for (ReferenceDescription rd : references) {
UShort namespaceIndex = rd.getNodeId().getNamespaceIndex();
String identifier = rd.getNodeId().getIdentifier().toString();
NodeId node = new NodeId(namespaceIndex, identifier);
nodesMap.put(rd.getNodeId().getIdentifier().toString(), node);
logger.info("----------------------------------------------------------------");
logger.info(identifier);
logger.info("TYPE " + rd.getTypeDefinition()); // Not the right node
logger.info("TYPE " + rd.getTypeId().getIdentifier().toString()); // Not the right node
logger.info("TYPE " + rd.getReferenceTypeId().getIdentifier().toString()); // Not the right node
rd.getNodeId().local().ifPresent(nodeId -> {
browseNode(indent + " ", client, nodeId, nodesMap);
});
}
} catch (InterruptedException | ExecutionException e) {
logger.error("Browsing nodeId={} failed: {}", browseRoot, e.getMessage(), e);
}
return nodesMap;
}
我不知道如何获取节点的数据类型。我想我在这里走错了路。如何找出节点的数据类型?
解决方案
最简单的方法是在每次写入之前读取 DataType 属性,这样您就知道要发送什么样的值。
一旦你有了这个工作,你可以尝试一些更棘手的事情,比如缓存 DataType 以便后续写入同一个节点不需要再次读取 DataType 属性,然后如果写入失败并出现 Bad_TypeMismatch 你可以使条目无效在该节点的缓存中,然后重试读+写。
推荐阅读
- c++ - 为什么 ofstream << 重载在作为成员函数调用时会产生不同的结果?
- jquery - 如何让jquery比较运算符工作
- c++ - 删除二叉树的节点
- menu - 如何阻止菜单在不同缩放级别上分成不同的行?
- c++ - 识别整数并用 X 替换数字
- python - python: logging:: 获取自定义时区的当前时间
- java - 如何让通知声音持续播放并仅在单击通知的“取消通知”按钮时停止
- javascript - 带有里程碑的引导进度条
- terminal - 纳米错误中的光标用于更长的行
- java - Spring Boot 审计 - 将当前用户映射到 @CreatedBy、@LastModifiedBy