首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UAExpert中的结构错误中的OPCUA Java milo结构

UAExpert中的结构错误中的OPCUA Java milo结构
EN

Stack Overflow用户
提问于 2021-07-08 20:51:33
回答 2查看 151关注 0票数 0

我正在使用milo 0.5.4来设置我自己的OpCUA服务器。

现在我尝试使用复杂的数据类型,它应该在结构中包含一个结构。

但是当连接到UAExpert客户端时,会显示以下错误消息:

UaBsdReader::evaluateTypeName:无法确定TypeName ua: Structure的数据类型

BsdReader无法解释类型ua:处于字段状态的结构

下面我添加了UAExpert结果的图片

我猜这个问题与registerToxStructType()中的Identifiers.Structure有关。但我不知道这里还应该使用什么。我希望外面的任何人能给我一个提示?

代码语言:javascript
复制
new StructureField("status", LocalizedText.NULL_VALUE, Identifiers.Structure, ValueRanks.Scalar, null, uint(0), false) };

这是我的第一个结构注册:

代码语言:javascript
复制
    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",   LocalizedText.NULL_VALUE, Identifiers.String, ValueRanks.Scalar, null, uint(0), false), 
                                                         new StructureField("text",   LocalizedText.NULL_VALUE, Identifiers.String, ValueRanks.Scalar, null, uint(0), false), 
                                                         new StructureField("source", LocalizedText.NULL_VALUE, Identifiers.String, ValueRanks.Scalar, null, uint(0), false) };

        StructureDefinition definition = new StructureDefinition(binaryEncodingId, Identifiers.Structure, StructureType.Structure, fields);

        StructureDescription description = new StructureDescription(dataTypeId, new QualifiedName(getNamespaceIndex(), "StatusStructType"), definition);

        dictionaryManager.registerStructureDescription(description, binaryEncodingId);

    }

这是我想要包括第一个结构的结构的注册:

代码语言:javascript
复制
    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", dataTypeId, binaryEncodingId);
        
        StructureField[] fields = new StructureField[] { 
                new StructureField("foo",    LocalizedText.NULL_VALUE, Identifiers.String,    ValueRanks.Scalar, null, getServer().getConfig().getLimits().getMaxStringLength(), false), 
                new StructureField("bar",    LocalizedText.NULL_VALUE, Identifiers.Int32,     ValueRanks.Scalar, null, uint(0), false), 
                new StructureField("baz",    LocalizedText.NULL_VALUE, Identifiers.Boolean,   ValueRanks.Scalar, null, uint(0), false),  //};
                new StructureField("status", LocalizedText.NULL_VALUE, Identifiers.Structure, ValueRanks.Scalar, null, uint(0), false) };

        StructureDefinition definition = new StructureDefinition(binaryEncodingId, Identifiers.Structure, StructureType.Structure, fields);

        StructureDescription description = new StructureDescription(dataTypeId, new QualifiedName(getNamespaceIndex(), "ToxStructType"), definition);

        dictionaryManager.registerStructureDescription(description, binaryEncodingId);
    }

这是添加ToxStructType的函数

代码语言:javascript
复制
    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:

代码语言:javascript
复制
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", ToxNamespaceDRX.NAMESPACE_URI, "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, 0, 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:

代码语言:javascript
复制
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", ToxNamespaceDRX.NAMESPACE_URI, "DataType.StatusStructType"));

    public static final ExpandedNodeId BINARY_ENCODING_ID = ExpandedNodeId.parse(String.format("nsu=%s;s=%s", ToxNamespaceDRX.NAMESPACE_URI, "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, OpcUaBinaryStreamEncoder writer, 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

EN

回答 2

Stack Overflow用户

发布于 2021-07-08 21:12:44

我猜这个问题与registerToxStructType()中的Identifiers.Structure有关。但我不知道这里还应该使用什么。我希望外面的任何人能给我一个提示?

您应该使用标识StatusStructType的NodeId (StatusStructType.TYPE_ID)。

我不知道这是否能完全解决你的问题,但这是很好的第一步。

票数 0
EN

Stack Overflow用户

发布于 2021-07-12 15:40:30

现在它起作用了。解决方案是:在定义StructureField[]字段的函数registerToxStructType()中,我必须用StatusStructType.TYPE_ID.toNodeIdOrThrow(getServer().getNamespaceTable())替换identifiers.structure

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68302016

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档