Как установить правильный тип данных при записи на узел OPC-UA в Milo?

Я новичок в OPC-UA, интегрирую систему без OPC-UA с сервером OPC-UA с использованием стека Milo. Частично это включает запись значений в узлы на сервере OPC-UA. Одна из моих проблем заключается в том, что значения из другой системы поступают в виде строки Java и, следовательно, должны быть преобразованы в правильный тип данных узла. Мое первое доказательство концепции методом грубой силы использует приведенный ниже код для создания варианта, который я могу использовать для записи в узел (как в WriteExample.java). Переменная значение - это строка Java, содержащая данные для записи, например «123» для целого числа или «32,3» для двойного. Решение теперь включает жесткое кодирование «типов» из класса идентификаторов (org.eclipse.milo.opcua.stack.core, см. Оператор switch), что не очень красиво, и я уверен, что есть лучший способ сделать это? Кроме того, как мне действовать, если я хочу преобразовать и записать «123» в узел, например UInt64?

       try {
            VariableNode node = client.getAddressSpace().createVariableNode(nodeId);
            Object val = new Object();
            Object identifier = node.getDataType().get().getIdentifier();
            UInteger id = UInteger.valueOf(0);

            if(identifier instanceof UInteger) {
                id = (UInteger) identifier;
            }

            System.out.println("getIdentifier: " + node.getDataType().get().getIdentifier());
            switch (id.intValue()) {
                // Based on the Identifiers class in org.eclipse.milo.opcua.stack.core; 
                case 11: // Double
                    val = Double.valueOf(value);
                    break;
                case 6: //Int32
                    val = Integer.valueOf(value);
                    break;
            }

            DataValue data = new DataValue(new Variant(val),StatusCode.GOOD, null);
            StatusCode status = client.writeValue(nodeId, data).get();
            System.out.println("Wrote DataValue: " + data + " status: " + status);
            returnString = status.toString();
        } catch (Exception e) {
            System.out.println("ERROR: " + e.toString());
        }

Я просмотрел ответ Кевина на эту тему: Как Надежно ли я пишу на сервер OPC UA? Но я все еще немного потерялся ... Небольшой пример кода был бы действительно полезен.


person Nenovrak    schedule 27.11.2019    source источник


Ответы (1)


Вы не так уж и далеко. Каждая значительная кодовая база в конечном итоге имеет один или несколько классов TypeUtilities, и здесь вам понадобится один.

Невозможно обойти тот факт, что вам нужно иметь возможность отображать типы в вашей системе на типы OPC UA и наоборот.

Для неподписанных типов вы будете использовать классы UShort, UInteger и ULong из пакета org.eclipse.milo.opcua.stack.core.types.builtin.unsigned. Есть удобные статические фабричные методы, которые делают их использование менее многословным:

UShort us = ushort(foo);
UInteger ui = uint(foo);
ULong ul = ulong(foo);

Я исследую эту идею включения какой-то утилиты преобразования типов в предстоящий выпуск, но даже с учетом того, как работает OPC UA, вы должны знать DataType узла, чтобы писать в него, и в большинстве случаев вы хотите также знать ValueRank и ArrayDimensions.

Вы либо заранее знаете эти значения атрибутов, либо получаете их через какой-либо другой внешний механизм, либо читаете их с сервера.

person Kevin Herron    schedule 28.11.2019