Eclipse Milo: Reading and decoding a custom data type node from a Simatic S7-1500

1.1k views Asked by At

The problem and what I suspect goes wrong: I am trying to read a custom data type node from a Siemens Simatic S7-1500 and decoding fails with:

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)

What I did so far: First of all, I've read and tried out the ReadWriteCustomDataTypeNodeExample from the client examples module. I've basically copied this example and replaced CustomStructType for a new custom type called Status containing 10 booleans. Like in the CustomStructType class, I've added a static codec to Status that reads the boolean values from the ByteString by using decoder.readBoolean(). This works perfectly. I have managed to read nodes, modify them and write them back to the OPC UA server. So far so good.

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

Next up, I want to do the same as above, but with another custom type TestNode containing a String and an integer. I created the class with a codec that uses decoder.readString() and decoder.readInt16(). When I try to read and decode the ByteString for this node, two issues appear:

  • readInt16() reads a different value than the value I see when I read this node with UaExpert.
  • readString() throws the exception stated above.

At this moment, I started doing research and found the following:

What are my options in this situation?

1

There are 1 answers

0
thoth On

I had the exact same issue and it took me two days to figure out the reason. In fact, I stumbled over the thread https://www.eclipse.org/lists/milo-dev/msg00890.html in the milo-dev mailing list and that finally gave me the hint I needed.

In your decode function, the order of read function calls does matter. This is a bit unintuitive, since the fields are addressed with their name already.

So, if your function looks somehow like this:

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

then, concerning the order of the read function calls, you must adhere to the order displayed in UaExpert (in your picture on the left, under Value -> Value).

I hope that solves your problem.