OPC UA struct data type?


I am new to Ignition and to OPC UA so I have a bit of a n00b-ish question. I have read that OPC UA performance can be optimized by subscribing to arrays and structs rather than individual tags. I’ve created some arrays in my PLC (I’m using an S7-1500 with its built-in OPC UA Server, firmware V2.6) and created OPC tags for elements in that array, so I’m hoping that Ignition is creating subscriptions for arrays for those items. However, I am stumped when it comes to structs. I’ve defined a UDT in my Siemens PLC and created an array of that UDT. However, in Ignition designer the UDT doesn’t show up as an atomic tag itself, it shows up as a list of the elements inside the UDT (i.e. if the UDT had a string, a float, an int, and a bool, then Ignition’s OPC browser shows me a list of those items instead of the entire UDT as one item). But my question is whether Ignition is reading these values as an OPC UA struct (which should be more optimized from my understanding) or as individual elements (which would be less optimized)?

Again, I apologize if this is a stupid question or if I’ve posted in the wrong place. Any help or information that you can provide would be greatly appreciated.

You can take advantage of reading whole structs in OPC UA servers as of Ignition 7.9.12 and 8.0.0.

When you bring the tag in you’ll notice Ignition presents a JSON value. The strategy here is a little involved but it works.

For each of the UDTs you’ll be subscribing to in the PLC you make a corresponding UDT in Ignition. It should have a “Source” OPC tag member that will correspond to the Node with the struct value in the server and as a result have a JSON value in Ignition. Then for each member of the UDT you have a Derived Tag member that references the “Source” tag using the jsonGet and jsonSet expression functions to get/set the member value out of the JSON value.

1 Like

Kevin, thank you so much for your helpful response. I think that answers my question perfectly.

Hi Kevin,

Where struggling with the same issues here. But we can’t find any documentation on how to a “sibling”-tag within the UDT for the derived tag.
E.G. We have a struct called CamPreset in de the PLC with pan, Tilt, zoom en focus integer values and float values.
We created a UDT called CamPreset and created a tag called “Source” in the UDT which is a OPC tag pointing to the PLC-struct. From here we thought to created derived tags Pan, Tilt, Zoom en Focus to delve into the Source-tag details… But how to reference the Source tag… Any suggestions?

Derived tags have some “magic variables” you can access.

In the Read Expression it’s {source} and in the Write Expression it’s {source} and {value}.


I know, but I’m looking into the Source parameter of the derived tag. How to reference the UDT member with the OPC-configuration… Then when we have an exact copy, I can further specify the details I want to use in my derived tag with de Read-expression…

Was this what you’re looking for?


Exactly this!! So simple… :unamused:

I am trying to use a derived tag in a UDT as well (Ignition 8.0.4). When the source tag is buried more than 1 level deep inside a folder it does not work. For example, if the source tag location is “[.]Folder/SubFolder/SourceTag”, the value comes back as blank. Same result if i browse the UDT tags to select the tag as the source, resulting in the path “[default]types/Ex1/Folder/SubFolder/SourceTag”. Maybe a bug, or is there something I am missing here?

Where’s your derived tag in the tree?
If the derived tag is in a folder as well you may need […] for the sourcetag reference

Thanks! I was having problems using the Sources/SourceTag as the source for DerivedTags/DerivedTag (in image below). Seeing your post made me look for the relative tag path documentation which explained that i need the following syntax in the source for DerivedTags/DerivedTag.




1 Like


Image above shows the UDT instance with good values :slight_smile:


Path is actually above. 2 dots instead of 3.

1 Like

Is there an example of what the “SourceTag” setup looks like in that above picture? I get that I’m going to read a document data type but what do I put as OPC Item Path? I have a Siemens DB1 with multiple instances of a UDT called DigitalInput where a DigitalInput is made of a Bool, Bool, Time, Int, Int, Bool.

I’m using this link https://docs.inductiveautomation.com/display/DOC79/Siemens#Siemens-ConfiguringSiemensAddressing as a reference for how addressing should occur. It doesn’t address documents. I realize this is DOC79, I’m using version 8.

You’ll want to ignore the directions of using the Siemens driver to connect to the PLC.

My example used a memory tag for source tag to simulate.

If your Siemens PLC has the firmware that includes a built-in opc ua server, you can go under Ignition’s OPC connections, and create a connection to the PLC from there.

From there you will be able to browse the OPC server (from the designer) and actually pull the struct as a tag into Ignition. This tag will appear as a JSON formatted string of key value pairs.

Hope this helps a bit.

If you can indulge me as I’m very unfamiliar with Siemens… The DB, *.xls, has several tabs that seemed to describe the STRUCT you’re referring to. Only one tab has ref. to ‘UDT’… Can you subscribe to the STRUCT in the same way? Or, is the UDT a special way to create a subscribing source?


i’m also using the onboard opcua of siemens for one of my project.

I’m trying to use the method of @Kevin.Herron but when importing a udt with a special type (Like Toff_Time) i get a bad quality in ignition. When deleted it works fine.

Also if you need to get some data into a folder or struct into the udt. How to you need to syntax this properly into the source and value of the derived tag?


I have found why it’s not working.

Iven if you put the ToF_Time as writable, SIemens activate only a part of the sub properties. :triumph:


You cannot have a timer in the struct if you want to read it with OPC UA. Only other structs, atomic member or other UDTs (which also don’t contain timers or other illegal types).

See this thread: