繁体   English   中英

如何在Eclipse Milo OpcUa服务器上正确编写ExtensionObject数组?

[英]How do I properly write an ExtensionObject Array on an Eclipse Milo OpcUa Server?

我正在尝试在Eclipse Milo OpcUa服务器上编写一个ExtensionObject数组。 我正在Java 8和Milo 0.2.3。上完成所有这些工作。

测试写入服务器的内容的方法是Unified Automation UaExpert客户端和一个小的Python客户端。 两者显示相同的结果。

我具有以下结构(在这种情况下,我将其命名为MyStructure)。 它已经作为数组存在,我想将其写入相应的节点。

@Getter
@Setter
@AllArgsConstructor
public class MyStructure implements UaStructure {
    private String name;
    private Integer dataType;
    private String stringValue;
    private Integer intValue;
    private Float floatValue;

    public static final String Description = "MyStructure ";

    public static NodeId getNodeId() {
        return new NodeId(2, 3081);
    }

    @Override
    public NodeId getTypeId() {
        return getNodeId();
    }

    @Override
    public NodeId getBinaryEncodingId() {
        return getNodeId();
    }

    @Override
    public NodeId getXmlEncodingId() {
        return getNodeId();
    }

    public static class Codec extends GenericDataTypeCodec<MyStructure > {

        @Override
        public Class<MyStructure > getType() {
            return MyStructure .class;
        }

        @Override
        public MyStructure decode(SerializationContext context, UaDecoder reader) {
            return new MyStructure (
                reader.readString("Name"),
                reader.readInt32("DataType"),
                reader.readString("StringValue"),
                reader.readInt32("IntValue"),
                reader.readFloat("FloatValue")
            );
        }

        @Override
        public void encode(SerializationContext context, MyStructure myStructure, UaEncoder writer) {
            writer.writeString("Name", myStructure.getName());
            writer.writeInt32("DataType", myStructure.getDataType());
            writer.writeString("StringValue", myStructure.getStringValue());
            writer.writeInt32("IntValue", myStructure.getIntValue());
            writer.writeFloat("FloatValue", myStructure.getFloatValue());
        }
    }
}

我这样写节点,其中node是UaVariableNode的实例,并数组我的Array对象,我是这样创建的:

node.setValue(new DataValue(new Variant(array)));

Object array = Array.newInstance(MyStructure.class, myStructureList.size());
for (int i = 0; i < myStructureList.size(); i++) {
    Array.set(array, i,myStructureList.get(i));
}

我这样预先注册了MyStructure定义:

OpcUaBinaryDataTypeDictionary dictionary = new OpcUaBinaryDataTypeDictionary("mynamespace");
dictionary.registerStructCodec(
        new MyStructure.Codec().asBinaryCodec(),
        "MyStructure",
        new NodeId(2, 3081)
    );
OpcUaDataTypeManager.getInstance().registerTypeDictionary(dictionary);

每当我设置节点时,服务器都不会抱怨。 它实际上设置了一些内容,确切地说,它设置了42个扩展对象。 在UaExpert中,我看到该值(包括其时间戳记)已更改,但看不到实际值。 该值只是ExtensionObject的Array类型,我无法读取任何嵌套值。 但这就是我在其他项目中看到的。 它们具有自定义结构,并且嵌套字段在UaExpert中是人类可读的。

如果我不使用Array而只编写一个MyStructure,则问题不会改变。

您有想法吗,我做错了什么还是根本没有做?

现在,只有在读/写客户端的客户事先知道该结构的情况下,Milo中的自定义结构才起作用。

您缺少的(并且尚未由Milo实现)是创建DataTypeDictionary,将其注册在地址空间中以及将编解码器通过DataTypeEncoding链接到该字典中的条目的所有复杂性。

如果要使用UaModeler之类的工具并在其中创建自定义结构,然后看一下生成的XML,就会发现还有很多其他支持节点。

当这些事情准备就绪时,客户可以学习如何解码自定义结构,而无需事先了解它们。 Milo的客户端也包括此功能。

同样,首先,您应该通过制作一个ExtensionObject[]对结构数组进行编码,每个ExtensionObject保存一个标量结构值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM