问题
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:
- I assume readString() uses the OPC UA String type node ns0;i=12, while, according to https://support.industry.siemens.com/cs/document/109780313/under-which-node-ids-do-you-find-the-type-descriptions-of-the-simatic-data-types-in-the-opc-ua-server-of-a-simatic-s7-1200-s7-1500-?dti=0&lc=en-GB, the Siemens OPC UA server uses ns=3;i=3014. This is probably where it goes wrong, but I'm not sure.
- Also, I don't understand why readInt16() reads a different value than the actual value. I have added a screenshot that show the node in UaExpert with the value and data types. Image: TestNode in UaExpert
What are my options in this situation?
回答1:
I came from this topic
Could you provide code for your structure in java? I have same PLC so I could test it.
BTW I was able to read Int32 and String without any problem. This is how the types looks on my side string, int32. I checked the link you provided above and ours ints are similar so I don't see any problem there but my String is different.
来源:https://stackoverflow.com/questions/65022527/eclipse-milo-reading-and-decoding-a-custom-data-type-node-from-a-simatic-s7-150