opcua java milo结构

ggazkfy8  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(395)

我正在使用milo 0.5.4来设置我自己的opcua服务器。
现在我尝试使用一个复杂的数据类型,它应该在结构中包含一个结构。
但当连接到uaexpert客户端时,会显示以下错误消息:
UABSDRADER::evaluatetypename:无法确定typename ua:结构的数据类型
BSR无法解释字段状态中的类型ua:结构
下面我添加了一张Maven结果的图片
我想问题与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",   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);

    }

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

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的函数

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));
    }

StructType.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", 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:

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结果/错误消息

jjhzyzn0

jjhzyzn01#

我想问题与registertoxstructtype()中的identifiers.structure有关。但我不知道这里还应该用什么。我希望外面有人能给我一个提示?
您应该使用标识statusstructtype的nodeid( StatusStructType.TYPE_ID ).
我不知道这是否能完全解决您的问题,但这是一个良好的第一步。

相关问题