Java Milo OPC-UA 添加节点
Java Milo OPC-UA add node
我正在使用 Milo 及其示例服务器和客户端。我正在向服务器添加节点,但我不知道如何添加 EuInformation
,即单元和描述。我考虑过使用 ExtensionObject
,但由于 EuInformation
没有实现 Serializable
,我不知道如何将它传递给 ExtensionObject
。我还想知道如何在客户端获取命名空间 ID 和 URI。到目前为止,我只是静态设置它们,因为我可以访问 classes.
我已经在服务器端实现了 AddNodes。我可以添加节点、读取节点和写入节点。
这是我在客户端所做的:
// Should somehow get the namespace ID and namespace dynamically.
// Maybe by iterating through all nodes??
ExpandedNodeId parentNodeId = new ExpandedNodeId(
new nodeId(2,DatatypeNamespace.NODE_IDENTIFIER),
datatypeNamespace.NAMESPACE_URI, 0);
NodeId referenceTypeId = Identifiers.String;
// Define the new node.
ExpandedNodeId requestedNewNodeId = new ExpandedNodeId(new NodeId(2, "NewNode"),
DatatypeNamespace.NAMESPACE_URI, 0);
QualifiedName browseName = new QualifiedName(2, "NewNode");
// How to get this to the server??
EUInformation euinfo = new EUInformation(null,-1,LocalizedText.english("MyUnit"),
LocalizedText.english("My Description"));
ExpandedNodeId typeDef = new ExpandedNodeId(Identifiers.BaseVariableType,
DatatypeNamespace.NAMESPACE_URI, 0);
AddNodesItem newItem = new AddNodesItem(parentNodeId, referenceTypeId,
requestedNewNodeId,rowseName,NodeClass.VariableType, null, typeDef);
List<AddNodesItem> items = new ArrayList<AddNodesItem>();
items.add(newItem);
client.addNodes(items).get();
编辑
在 Kevin Herron 的回答的帮助下,我解决了一些问题:我调整了命名空间 class 中的 write()
。我现在可以使用 EUInformation 的值修改节点的显示名称和描述。这是我的 write()
方法:
@Override
public void write(WriteContext context, List<WriteValue> writeValues) {
List<StatusCode> results = Lists.newArrayListWithCapacity(writeValues.size());
for (WriteValue writeValue : writeValues) {
ServerNode node = server.getNodeMap().get(writeValue.getNodeId());
if (node != null) {
// Get the type of the variant thats about to be written to the node
NodeId variantType = writeValue.getValue().getValue().getDataType().get();
if (variantType.equals(Identifiers.Structure)) {
ExtensionObject o = (ExtensionObject) writeValue.getValue().getValue().getValue();
if (o.getEncodingTypeId().equals(Identifiers.EUInformation_Encoding_DefaultBinary)) {
EUInformation euInformation = (EUInformation) o.decode();
node.setDescription(euInformation.getDescription());
node.setDisplayName(euInformation.getDisplayName());
System.out.println("Wrote EUInformation " + euInformation);
results.add(StatusCode.GOOD);
context.complete(results);
return;
}
}
try {
node.writeAttribute(new AttributeContext(context), writeValue.getAttributeId(),
writeValue.getValue(), writeValue.getIndexRange());
results.add(StatusCode.GOOD);
System.out.println(String.format("Wrote value %s to %s attribute of %s",
writeValue.getValue().getValue(),
AttributeId.from(writeValue.getAttributeId()).map(Object::toString).orElse("unknown"),
node.getNodeId()));
} catch (UaException e) {
System.out.println(String.format("Unable to write %s", writeValue.getValue()));
results.add(e.getStatusCode());
}
} else {
results.add(new StatusCode(StatusCodes.Bad_NodeIdUnknown));
}
}
context.complete(results);
}
好的,所以您将添加一个 TypeDefinition 为 属性 (Identifiers.PropertyType
) 的新 VaribleNode。
然后您将写入其 Value 属性,使其包含 EUInformation 对象:
EUInformation euInformation = ...
Variant v = new Variant(ExtensionObject.encode(euInformation));
...write the value to the node you created...
我正在使用 Milo 及其示例服务器和客户端。我正在向服务器添加节点,但我不知道如何添加 EuInformation
,即单元和描述。我考虑过使用 ExtensionObject
,但由于 EuInformation
没有实现 Serializable
,我不知道如何将它传递给 ExtensionObject
。我还想知道如何在客户端获取命名空间 ID 和 URI。到目前为止,我只是静态设置它们,因为我可以访问 classes.
我已经在服务器端实现了 AddNodes。我可以添加节点、读取节点和写入节点。 这是我在客户端所做的:
// Should somehow get the namespace ID and namespace dynamically.
// Maybe by iterating through all nodes??
ExpandedNodeId parentNodeId = new ExpandedNodeId(
new nodeId(2,DatatypeNamespace.NODE_IDENTIFIER),
datatypeNamespace.NAMESPACE_URI, 0);
NodeId referenceTypeId = Identifiers.String;
// Define the new node.
ExpandedNodeId requestedNewNodeId = new ExpandedNodeId(new NodeId(2, "NewNode"),
DatatypeNamespace.NAMESPACE_URI, 0);
QualifiedName browseName = new QualifiedName(2, "NewNode");
// How to get this to the server??
EUInformation euinfo = new EUInformation(null,-1,LocalizedText.english("MyUnit"),
LocalizedText.english("My Description"));
ExpandedNodeId typeDef = new ExpandedNodeId(Identifiers.BaseVariableType,
DatatypeNamespace.NAMESPACE_URI, 0);
AddNodesItem newItem = new AddNodesItem(parentNodeId, referenceTypeId,
requestedNewNodeId,rowseName,NodeClass.VariableType, null, typeDef);
List<AddNodesItem> items = new ArrayList<AddNodesItem>();
items.add(newItem);
client.addNodes(items).get();
编辑
在 Kevin Herron 的回答的帮助下,我解决了一些问题:我调整了命名空间 class 中的 write()
。我现在可以使用 EUInformation 的值修改节点的显示名称和描述。这是我的 write()
方法:
@Override
public void write(WriteContext context, List<WriteValue> writeValues) {
List<StatusCode> results = Lists.newArrayListWithCapacity(writeValues.size());
for (WriteValue writeValue : writeValues) {
ServerNode node = server.getNodeMap().get(writeValue.getNodeId());
if (node != null) {
// Get the type of the variant thats about to be written to the node
NodeId variantType = writeValue.getValue().getValue().getDataType().get();
if (variantType.equals(Identifiers.Structure)) {
ExtensionObject o = (ExtensionObject) writeValue.getValue().getValue().getValue();
if (o.getEncodingTypeId().equals(Identifiers.EUInformation_Encoding_DefaultBinary)) {
EUInformation euInformation = (EUInformation) o.decode();
node.setDescription(euInformation.getDescription());
node.setDisplayName(euInformation.getDisplayName());
System.out.println("Wrote EUInformation " + euInformation);
results.add(StatusCode.GOOD);
context.complete(results);
return;
}
}
try {
node.writeAttribute(new AttributeContext(context), writeValue.getAttributeId(),
writeValue.getValue(), writeValue.getIndexRange());
results.add(StatusCode.GOOD);
System.out.println(String.format("Wrote value %s to %s attribute of %s",
writeValue.getValue().getValue(),
AttributeId.from(writeValue.getAttributeId()).map(Object::toString).orElse("unknown"),
node.getNodeId()));
} catch (UaException e) {
System.out.println(String.format("Unable to write %s", writeValue.getValue()));
results.add(e.getStatusCode());
}
} else {
results.add(new StatusCode(StatusCodes.Bad_NodeIdUnknown));
}
}
context.complete(results);
}
好的,所以您将添加一个 TypeDefinition 为 属性 (Identifiers.PropertyType
) 的新 VaribleNode。
然后您将写入其 Value 属性,使其包含 EUInformation 对象:
EUInformation euInformation = ...
Variant v = new Variant(ExtensionObject.encode(euInformation));
...write the value to the node you created...