Eclipse Milo: чтение и декодирование узла пользовательского типа данных из Simatic S7-1500

Проблема и то, что я подозреваю, идет не так: я пытаюсь прочитать узел настраиваемого типа данных из Siemens Simatic S7-1500, и декодирование не выполняется с помощью:

Error running client example: max string length exceeded (length=1819042152, max=2097152)
org.eclipse.milo.opcua.stack.core.UaSerializationException: max string length exceeded (length=1819042152, max=2097152)

Что я сделал на данный момент: Прежде всего, я прочитал и опробовал ReadWriteCustomDataTypeNodeExample из модуля клиентских примеров. Я в основном скопировал этот пример и заменил CustomStructType новым настраиваемым типом под названием Status, содержащим 10 логических значений. Как и в классе CustomStructType, я добавил статический кодек в Status, который считывает логические значения из ByteString с помощью decoder.readBoolean (). Это прекрасно работает. Мне удалось прочитать узлы, изменить их и записать обратно на сервер OPC UA. Все идет нормально.

    NodeId binaryEncodingId = new NodeId(3, "TE_\"DB_FUNCTION_STATUS\".\"TEST\"");
// Register codec with the client DataTypeManager instance
client.getDataTypeManager().registerCodec(
        binaryEncodingId,
        new TestNode.Codec().asBinaryCodec()
);

// synchronous read request via VariableNode
NodeId nodeId = new NodeId(3, "\"DB_FUNCTION_STATUS\".\"TEST\"");
UaVariableNode node = client.getAddressSpace().getVariableNode(nodeId);
DataValue value = node.readValue();

logger.info("====== Reading value from OPC UA Server =======");
logger.info("Value={}", value);

Variant variant = value.getValue();
ExtensionObject xo = (ExtensionObject) variant.getValue();

TestNode decoded = (TestNode) xo.decode(
        client.getSerializationContext()
);
logger.info("Decoded={}", decoded);

Далее я хочу сделать то же самое, что и выше, но с другим настраиваемым типом TestNode, содержащим String и целое число. Я создал класс с кодеком, который использует decoder.readString () и decoder.readInt16 (). Когда я пытаюсь прочитать и декодировать ByteString для этого узла, появляются две проблемы:

  • readInt16 () считывает значение, отличное от значения, которое я вижу, когда читаю этот узел с помощью UaExpert.
  • readString () вызывает исключение, указанное выше.

В этот момент я начал проводить исследования и обнаружил следующее:

Какие у меня варианты в этой ситуации?


person Jordy    schedule 26.11.2020    source источник


Ответы (1)


У меня была такая же проблема, и мне потребовалось два дня, чтобы выяснить причину. Фактически, я наткнулся на ветку https://www.eclipse.org/lists/milo-dev/msg00890.html в списке рассылки milo-dev, и это наконец дало мне нужную подсказку.

В вашей функции декодирования порядок вызовов функций чтения имеет значение. Это немного неинтуитивно, так как поля уже адресованы своим именем.

Итак, если ваша функция выглядит как-то так:

@Override
public TestNode decode(SerializationContext context, UaDecoder reader) {
    String str = reader.readString("String");
    short integer = reader.readInt16("Integer");
    return TestNode(str, integer);
}

то, что касается порядка вызовов функций чтения, вы должны придерживаться порядка, отображаемого в UaExpert (на вашем рисунке слева, в разделе Value - ›Value).

Надеюсь, это решит вашу проблему.

person horle    schedule 28.04.2021