问题描述
我正在使用 milo 0.5.4 来设置我自己的 Opcua 服务器。
现在我尝试使用一个复杂的数据类型,它应该在一个结构中包含一个结构。
UaBsdReader::evaluateTypeName: 无法确定 TypeName ua: Structure 的数据类型
BsdReader 无法在字段状态中解释类型 ua:Structure
我猜这个问题与 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);
}
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())