如何解决OPCUA Java milo 结构在UAEExpert 中的结构错误
我正在使用 milo 0.5.4 来设置我自己的 OpCUA 服务器。
现在我尝试使用一个复杂的数据类型,它应该在一个结构中包含一个结构。
但是当连接到UAExpert客户端时,显示如下错误信息:
UaBsdReader::evaluateTypeName: 无法确定 TypeName ua: Structure 的数据类型
BsdReader 无法在字段状态中解释类型 ua:Structure
下面我添加了UAExpert结果的图片
我猜这个问题与 registerToxStructType() 中的 Identifiers.Structure 有关。但我不知道这里还应该使用什么。 我希望那里的任何人都可以给我提示?
new StructureField("status",LocalizedText.NULL_VALUE,Identifiers.Structure,ValueRanks.Scalar,null,uint(0),false) };
这是我第一次注册结构:
private void registerStatusStructType() throws Exception {
// Get the NodeId for the DataType and encoding Nodes.
NodeId dataTypeId = StatusStructType.TYPE_ID.toNodeIdOrThrow(getServer().getNamespaceTable());
NodeId binaryEncodingId = StatusStructType.BINARY_ENCODING_ID.toNodeIdOrThrow(getServer().getNamespaceTable());
dictionaryManager.registerStructureCodec(new StatusStructType.Codec(),"StatusStructType",dataTypeId,binaryEncodingId ); ///,parentTypeId);
StructureField[] fields = new StructureField[] { new StructureField("type",Identifiers.String,false),new StructureField("text",new StructureField("source",false) };
StructureDefinition definition = new StructureDefinition(binaryEncodingId,StructureType.Structure,fields);
StructureDescription description = new StructureDescription(dataTypeId,new QualifiedName(getNamespaceIndex(),"StatusStructType"),definition);
dictionaryManager.registerStructureDescription(description,binaryEncodingId);
}
这是我想包含第一个结构的注册:
private void registerToxStructType() throws Exception {
// Get the NodeId for the DataType and encoding Nodes.
NodeId dataTypeId = ToxStructType.TYPE_ID.toNodeIdOrThrow(getServer().getNamespaceTable());
NodeId binaryEncodingId = ToxStructType.BINARY_ENCODING_ID.toNodeIdOrThrow(getServer().getNamespaceTable());
dictionaryManager.registerStructureCodec(new ToxStructType.Codec(),"ToxStructType",binaryEncodingId);
StructureField[] fields = new StructureField[] {
new StructureField("foo",getServer().getConfig().getLimits().getMaxStringLength(),new StructureField("bar",Identifiers.Int32,new StructureField("baz",Identifiers.Boolean,//};
new StructureField("status","ToxStructType"),binaryEncodingId);
}
这是添加ToxStructType的函数
private void addToxStructTypeVariable(UaFolderNode rootFolder) throws Exception {
NodeId dataTypeId = ToxStructType.TYPE_ID.toNodeIdOrThrow(getServer().getNamespaceTable());
NodeId binaryEncodingId = ToxStructType.BINARY_ENCODING_ID.toNodeIdOrThrow(getServer().getNamespaceTable());
UaVariableNode ToxStructTypeVariable = UaVariableNode.builder(getNodeContext())
.setNodeId(newNodeId("ThisIsMyPart/ToxStructTypeVariable"))
.setAccessLevel(AccessLevel.READ_WRITE)
.setUserAccessLevel(AccessLevel.READ_WRITE)
.setBrowseName(newQualifiedName("ToxStructTypeVariable"))
.setDisplayName(LocalizedText.english("ToxStructTypeVariable"))
.setDataType(dataTypeId)
.setTypeDefinition(Identifiers.BaseDataVariableType)
.build();
StatusStructType statestruct = new StatusStructType("Error 0010","Error 0010 occured! 0x0F","Device 0010?");
ToxStructType value = new ToxStructType("foo",42,true,statestruct );
ExtensionObject xo = ExtensionObject.encodeDefaultBinary(getServer().getSerializationContext(),value,binaryEncodingId);
ToxStructTypeVariable.setValue(new DataValue(new Variant(xo)));
getNodeManager().addNode(ToxStructTypeVariable);
ToxStructTypeVariable.addReference(new Reference(ToxStructTypeVariable.getNodeId(),Identifiers.Organizes,rootFolder.getNodeId().expanded(),false));
}
结构 ToxStructType.java:
package com.toxware.export.opcua.communication.server.util;
import org.eclipse.milo.opcua.stack.core.UaSerializationException;
import org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamDecoder;
import org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder;
import org.eclipse.milo.opcua.stack.core.serialization.SerializationContext;
import org.eclipse.milo.opcua.stack.core.serialization.UaStructure;
import org.eclipse.milo.opcua.stack.core.serialization.codecs.OpcUaBinaryDataTypeCodec;
import org.eclipse.milo.opcua.stack.core.types.builtin.ExpandedNodeId;
import com.toxware.export.opcua.communication.server.ToxNamespaceDRX;
public class ToxStructType implements UaStructure {
public static final ExpandedNodeId TYPE_ID = ExpandedNodeId.parse(String.format("nsu=%s;s=%s",ToxNamespaceDRX.NAMESPACE_URI,"DataType.ToxStructType"));
public static final ExpandedNodeId BINARY_ENCODING_ID = ExpandedNodeId.parse(String.format("nsu=%s;s=%s","DataType.ToxStructType.BinaryEncoding"));
private final String foo;
private final Integer bar;
private final boolean baz;
private final StatusStructType status;
@Override
public ExpandedNodeId getTypeId() {
return TYPE_ID;
}
public ToxStructType(String foo,Integer bar,boolean baz,StatusStructType status) {
this.foo = foo;
this.bar = bar;
this.baz = baz;
this.status = status;
}
public ToxStructType() {
this(null,false,new StatusStructType());
}
public static class Codec implements OpcUaBinaryDataTypeCodec<ToxStructType> {
@Override
public Class<ToxStructType> getType() {
return ToxStructType.class;
}
@Override
public ToxStructType decode(SerializationContext context,OpcUaBinaryStreamDecoder reader) throws UaSerializationException {
String foo = reader.readString("foo");
Integer bar = reader.readInt32("bar");
boolean baz = reader.readBoolean("baz");
Object statusStruct = reader.readStruct("status",new StatusStructType.Codec());
StatusStructType statusStructure = new StatusStructType();
if (statusStruct.getClass().isAssignableFrom(StatusStructType.class)) {
statusStructure = (StatusStructType) statusStruct;
}
return new ToxStructType(foo,bar,baz,statusStructure);
}
@Override
public void encode(SerializationContext context,OpcUaBinaryStreamEncoder writer,ToxStructType value) throws UaSerializationException {
writer.writeString("foo",value.foo);
writer.writeInt32("bar",value.bar);
writer.writeBoolean("baz",value.baz);
writer.writeStruct("status",value.status,StatusStructType.TYPE_ID);
}
}
}
StatusStructType.java:
package com.toxware.export.opcua.communication.server.util;
import org.eclipse.milo.opcua.stack.core.UaSerializationException;
import org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamDecoder;
import org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder;
import org.eclipse.milo.opcua.stack.core.serialization.SerializationContext;
import org.eclipse.milo.opcua.stack.core.serialization.UaStructure;
import org.eclipse.milo.opcua.stack.core.serialization.codecs.OpcUaBinaryDataTypeCodec;
import org.eclipse.milo.opcua.stack.core.types.builtin.ExpandedNodeId;
import com.toxware.export.opcua.communication.server.ToxNamespaceDRX;
public class StatusStructType implements UaStructure {
public static final ExpandedNodeId TYPE_ID = ExpandedNodeId.parse(String.format("nsu=%s;s=%s","DataType.StatusStructType"));
public static final ExpandedNodeId BINARY_ENCODING_ID = ExpandedNodeId.parse(String.format("nsu=%s;s=%s","DataType.StatusStructType.BinaryEncoding"));
String type = "txt_0";
String text = "txt_1";
String source = "txt_2";
@Override
public ExpandedNodeId getTypeId() {
return TYPE_ID;
}
public StatusStructType(String type,String text,String source) {
this.type = type;
this.text = text;
this.source = source;
}
public StatusStructType() {
this("","","");
}
public static class Codec implements OpcUaBinaryDataTypeCodec<StatusStructType> {
@Override
public Class<StatusStructType> getType() {
return StatusStructType.class;
}
@Override
public StatusStructType decode(SerializationContext context,OpcUaBinaryStreamDecoder reader) throws UaSerializationException {
String type = reader.readString("type");
String text = reader.readString("text");
String source = reader.readString("source");
return new StatusStructType(type,text,source);
}
@Override
public void encode(SerializationContext context,StatusStructType value) throws UaSerializationException {
writer.writeString("type",value.type);
writer.writeString("text",value.text);
writer.writeString("source",value.source);
}
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
}
UAExpert Result / ErrorMessage
解决方法
我猜这个问题与 registerToxStructType() 中的 Identifiers.Structure 有关。但我不知道这里还应该使用什么。我希望那里的任何人都可以给我提示?
您应该使用标识 StatusStructType (StatusStructType.TYPE_ID
) 的 NodeId。
我不知道这是否能完全解决您的问题,但这是一个很好的第一步。
,现在可以了。解决方案是: 在 StructureField[] 字段定义中的函数 registerToxStructType() 中,我必须替换 标识符.结构 经过 StatusStructType.TYPE_ID.toNodeIdOrThrow(getServer().getNamespaceTable())
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。