A colleague is trying to use a Siemens PLC via onboard OPC-UA to read a nested UDT within a datablock. He’s reading the top level datablock in as a Document tag and then using a derived tag with jsonGet to read the nested UDT, then a derived integer tag with jsonGet to read a key from this tag. Essentially it’s doing jsonGet(jsonGet({source}, "Seq"), "Command")
.
Example tag JSON below which is in the format:
base tag = opc tag, the root datablock tag
seq tag = get “Seq” object from base tag
cmd tag = get “Command” integer tag from seq tag (essentially, get Seq.Command
from base tag)
When trying to write to the cmd tag, he’s seeing this error:
INFO | jvm 1 | 2022/08/11 15:58:20 | W [o.e.m.o.s.c.s.OpcUaBinaryStreamEncoder] [05:58:19]: Not a built-in type: class com.inductiveautomation.ignition.common.document.Document
INFO | jvm 1 | 2022/08/11 15:58:20 | E [o.e.m.o.s.c.t.u.UascClientMessageHandler] [05:58:19]: Error serializing WriteRequest(requestHeader=RequestHeader(authenticationToken=NodeId{ns=0, id=217572643}, timestamp=DateTime{utcTime=133046710999830000, javaDate=Thu Aug 11 15:58:19 AEST 2022}, requestHandle=6617, returnDiagnostics=0, auditEntryId=null, timeoutHint=60000, additionalHeader=null), nodesToWrite=[WriteValue(nodeId=NodeId{ns=3, id="SQ110_WM5"."SQ110_WM5"}, attributeId=13, indexRange=null, value=DataValue{value=Variant{value={
INFO | jvm 1 | 2022/08/11 15:58:20 | "Seq":{\n "\"Command\": 30\n}"
INFO | jvm 1 | 2022/08/11 15:58:20 | }}, status=null})]): unknown builtin type: -1
INFO | jvm 1 | 2022/08/11 15:58:20 | org.eclipse.milo.opcua.stack.core.UaSerializationException: unknown builtin type: -1
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeBuiltinType(OpcUaBinaryStreamEncoder.java:736)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeValue(OpcUaBinaryStreamEncoder.java:654)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeVariant(OpcUaBinaryStreamEncoder.java:637)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeDataValue(OpcUaBinaryStreamEncoder.java:323)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeDataValue(OpcUaBinaryStreamEncoder.java:879)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.types.structured.WriteValue$Codec.encode(WriteValue.java:106)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.types.structured.WriteValue$Codec.encode(WriteValue.java:86)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.codecs.GenericDataTypeCodec$GenericBinaryDataTypeCodec.encode(GenericDataTypeCodec.java:54)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeStruct(OpcUaBinaryStreamEncoder.java:941)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.lambda$writeStructArray$3(OpcUaBinaryStreamEncoder.java:1107)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeArray(OpcUaBinaryStreamEncoder.java:83)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeStructArray(OpcUaBinaryStreamEncoder.java:1107)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeStructArray(OpcUaBinaryStreamEncoder.java:1123)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.types.structured.WriteRequest$Codec.encode(WriteRequest.java:85)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.types.structured.WriteRequest$Codec.encode(WriteRequest.java:69)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.codecs.GenericDataTypeCodec$GenericBinaryDataTypeCodec.encode(GenericDataTypeCodec.java:54)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder.writeMessage(OpcUaBinaryStreamEncoder.java:918)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.client.transport.uasc.UascClientMessageHandler.lambda$encode$9(UascClientMessageHandler.java:334)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.channel.SerializationQueue.lambda$encode$0(SerializationQueue.java:52)
INFO | jvm 1 | 2022/08/11 15:58:20 | at org.eclipse.milo.opcua.stack.core.util.ExecutionQueue$Task.run(ExecutionQueue.java:119)
INFO | jvm 1 | 2022/08/11 15:58:20 | at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
INFO | jvm 1 | 2022/08/11 15:58:20 | at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
If he converts the base opc tag into a memory tag and writes the same document object to the memory tag, then the write to the cmd tag works fine.
JSON for the OPC tag and derived tags where the cmd tag write fails:
{
"tags": [
{
"valueSource": "memory",
"opcItemPath": "nsu\u003dhttp://www.siemens.com/simatic-s7-opcua;s\u003d\"SQ110_WM5\".\"SQ110_WM5\"",
"dataType": "Document",
"name": "base",
"value": {
"Seq": {
"Command": 5
},
"tagType": "AtomicTag",
"opcServer": "BBD_PLC2"
},
{
"valueSource": "derived",
"deriveExpressionGetter": "jsonGet({source}, \u0027Command\u0027)",
"dataType": "Int4",
"deriveExpressionSetter": "jsonSet({source}, \"Command\", {value})",
"sourceTagPath": "[.]seq",
"name": "cmd",
"tagType": "AtomicTag"
},
{
"valueSource": "derived",
"deriveExpressionGetter": "jsonGet({source}, \u0027Seq\u0027)",
"dataType": "Document",
"deriveExpressionSetter": "jsonSet({source}, \"Seq\", {value})",
"sourceTagPath": "[.]base",
"name": "seq",
"tagType": "AtomicTag"
}
]
}
JSON for the memory tag + derived tags where the cmd tag writes successfully
{
"tags": [
{
"valueSource": "memory",
"dataType": "Document",
"name": "base",
"value": {
"Seq": "{\n \"Command\": 8}"
},
"tagType": "AtomicTag"
},
{
"valueSource": "derived",
"deriveExpressionGetter": "jsonGet({source}, \u0027Command\u0027)",
"dataType": "Int4",
"deriveExpressionSetter": "jsonSet({source}, \"Command\", {value})",
"sourceTagPath": "[.]seq",
"name": "cmd",
"tagType": "AtomicTag"
},
{
"valueSource": "derived",
"deriveExpressionGetter": "jsonGet({source}, \u0027Seq\u0027)",
"dataType": "Document",
"deriveExpressionSetter": "jsonSet({source}, \"Seq\", {value})",
"sourceTagPath": "[.]base",
"name": "seq",
"tagType": "AtomicTag"
}
]
}