Passing a structure (ExtensionObject) argument
Some methods take a structure, not a number or a string. In OPC UA such a value travels as an ExtensionObject. This page shows the three ways to pass one, and the mistake that accounts for most of the reports we get.
The rule
msg.payload holds one property per input argument, named exactly as the server declares it.
msg.payload = {
Setting: { // the name of the argument, from the server
Duration: 23,
Cycles: 10,
DataAvailable: true
}
};
The name is not yours to choose. Setting and Settings are two different properties, and the
second one never reaches the method. Press Check in the node, read the names the server
reports, and use the copy button to get a template.
A plain object is enough. The Call node reads the data type of the argument from the server and builds the ExtensionObject itself, so you do not have to write the type.
Without an ExtensionObject node
For most methods this is all you need: an inject or a function node that sets the payload.
// Function node, in front of the Call node
msg.payload = {
Setting: { Duration: 23, Cycles: 10, DataAvailable: true }
};
return msg;
Flow: inject → function → Call
With an ExtensionObject node
The ExtensionObject node builds a structure and puts it in msg.payload. That payload is the
structure itself, not a map of arguments, so one step has to move it under the argument's name:
// Function node, between the ExtensionObject node and the Call node
msg.payload = { Setting: msg.payload };
return msg;
Flow: inject → ExtensionObject → function → Call
Leave that step out and the Call node has no property named Setting. It then tells you so, and
names the arguments the method expects.
Use this route when you want the node's editor to build the structure for you, when the same structure feeds several nodes, or when a value of the structure comes from elsewhere in the flow.
The explicit forms
If you already hold an encoded structure, pass it as it is. Both OPC UA JSON forms are
accepted — 1.05, with UaTypeId and UaBody:
msg.payload = {
Setting: {
UaTypeId: "ns=2;i=1001",
UaBody: { Duration: 23, Cycles: 10, DataAvailable: true }
}
};
and 1.04, with TypeId and Body:
msg.payload = {
Setting: {
TypeId: "ns=2;i=1001",
Body: { Duration: 23, Cycles: 10, DataAvailable: true }
}
};
Prefer the plain object of the first section. A type you write by hand is a type that can be wrong; a type read from the server cannot.
An array of structures
An argument whose value rank is 1 takes an array. Each element follows the same rules:
msg.payload = {
Settings: [
{ Duration: 23, Cycles: 10, DataAvailable: true },
{ Duration: 42, Cycles: 1, DataAvailable: false }
]
};
When it does not work
| What you see | What it means |
|---|---|
msg.payload carries no input argument "X" | the property is missing or misspelled. The message lists the arguments the method expects and the properties your payload holds — compare the two. |
| a warning that an argument was sent as its default | the same mistake on a number or a string argument. The call went through with 0 or "". |
Cannot read properties of undefined (reading 'Value') | the same mistake, on a version released before this page. Check the property names. |
BadInvalidArgument from the server | the names match, but a field inside the structure does not, or has the wrong type. Compare the fields with the type definition in the address space. |