Как правильно написать массив ExtensionObject на сервере Eclipse Milo OpcUa? - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь написать массив ExtensionObject на сервере Eclipse Milo OpcUa.Я делаю все это в Java 8 и в Milo 0.2.3.

Мой способ проверить то, что я написал на свой сервер, - это клиент UaExpert Unified Automation и небольшой клиент 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());
        }
    }
}

Я пишу такой узел, где узел - это экземпляр 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 я вижу, что значение, включая его метку времени, изменилось, но я не вижу фактического значения.Значение имеет тип Array для ExtensionObject, и я не могу прочитать ни одно из вложенных значений.Но это то, что я видел в других проектах.У них есть пользовательские структуры, а вложенные поля читаются человеком в UaExpert.

Проблема не изменится, если я сделаю это без массива и просто напишу одну MyStructure.

У вас естьидея, что я делаю не так или не делаю вообще?

1 Ответ

0 голосов
/ 27 сентября 2018

В настоящее время пользовательские структуры в Milo работают только в том случае, если клиент, читающий / записывающий их, заранее знает о структуре.

То, что вам не хватает (и еще не реализовано в Milo), представляет собой всю сложностьвокруг создания DataTypeDictionary, регистрации его в адресном пространстве и связывания вашего кодека с записью в этом словаре с помощью DataTypeEncoding.

Если вы должны использовать такой инструмент, как UaModeler, и создать в нем собственную структуру, тоВзглянув на сгенерированный XML, вы увидите, что есть целый ряд других поддерживающих узлов, которые идут вместе с ним.

Когда все это на месте, клиенты могут научиться декодировать пользовательские структуры, не зная оих заранее.Клиент Майло также включает эту функцию.

Кроме того, fwiw, вы должны закодировать свой массив структур, создав ExtensionObject[], где каждый ExtensionObject содержит одно значение скалярной структуры.

...