Tag subscription clarification

I am quite new to the Ignition SDK, and have been playing around with some OPC-UA driver code. What I am interested in is how the flow of a tag subscription works.

From what i have looked at and played with on the example opc-ua driver, you essentially add a bunch of nodes to the opc server and start a timed executor that updates the tags on the opc server.
This works on a small driver, but if we were to scale this to a bigger system, it is obvious that there is a mechanism that is aware of the subscriptions on the opc-ua server and can alert your driver to the list of currently subscribed tags, in order that you can only update those tags.

My confusion is centred around this notification of subscription, as there doesn't seem to be an example of the way you would handle this in the code I have seen.

Is there some sort of function in AbstractDeviceModuleHook that I should know about? Also, why can't I find that in the javadocs?

A non-trivial implementation would implement the Device interface directly, and you would end up having to implement:

  • onDataItemsCreated
  • onDataItemsModified
  • onDataItemsDeleted

from the Milo AddressSpace interface. Once you dig in a little you'll find the Device API is a thin layer on top of just implementing a Milo OPC UA AddressSpace.

ManagedDevice is basically just a ManagedAddressSpace: milo/opc-ua-sdk/sdk-server/src/main/java/org/eclipse/milo/opcua/sdk/server/api/ManagedAddressSpace.java at c6a875c2fa8f65c48815410d6bbf02d43560bcd4 · eclipse-milo/milo · GitHub

1 Like

Ah, and even the example implements these as well: ignition-sdk-examples/opc-ua-device/opc-ua-device-gateway/src/main/java/com/inductiveautomation/ignition/examples/tagdriver/ExampleDevice.java at 276f89239073e2108253716bce7f4ff70d20698d · inductiveautomation/ignition-sdk-examples · GitHub

It just implements them naively, using SubscriptionModel, which just book-keeps and calls read over and over at the requested sampling interval.

I guess my question is more about how the driver knows to run updates on a tag value?
When you register the nodes on the device, they become visible when you browse the OPC server.
How do you know that a client has subscribed to one of the list of registered nodes in order to start that tag updating?
In the ignition-sdk-examples/opc-ua-device example, all the tags are updated all the time, which obviously isn't how something like the Logix driver works, otherwise you would be polling the PLC for every tag at the listed update rate.
How is this performed?

onDataItemsCreated is called when any OPC UA client creates a MonitoredItem.

Dragging a tag from the OPC Browser into the Tag Browser causes a MonitoredItem to be created on the corresponding server.

1 Like

That is starting to make sense now, so I can essentially use that to add and remove the element from my driver's update routines to keep things fast and minimally loaded?

Yeah, the 4 of those methods will inform you when things were added or deleted, the sampling interval has changed, or possibly if sampling should be enabled or disabled (check MonitoredItem::isSamplingEnabled).

1 Like

Why do you think it doesn't (for all monitored items)?

I think he's just talking about how the example just arbitrarily drives the tag update/simulation @ 1s: ignition-sdk-examples/opc-ua-device/opc-ua-device-gateway/src/main/java/com/inductiveautomation/ignition/examples/tagdriver/ExampleDevice.java at 276f89239073e2108253716bce7f4ff70d20698d · inductiveautomation/ignition-sdk-examples · GitHub

@David_Stone some of the drivers, like Logix, also do not create UaNode instances for every tag. They do everything dynamically. The MonitoredItem is the callback, your driver just has to set values on that according to its sampling interval as best it can.

1 Like

Monitored items is the key, an item being in the tag "Browse" list (visible but not subscribed in the ignition tag browser) doesn't get it's tag value updated, but one that has been subscribed to does. I just wasn't seeing the mechanism that differentiates this so you can only update monitored items. As Kevin pointed out, the example updates every simulated tag every cycle, subscribed or not.

@Kevin.Herron Does that mean that the visibility in the OPC Item browser is not totally dependent on nodes being created?

Right, just answer the browse and getReferences calls accordingly.

Here's an example of a "dynamic" address space: modbus-server-driver/msd-gateway/src/main/java/com/kevinherron/ignition/modbus/BrowsableAddressSpace.java at c67e81d7aca2e11cd3a801f0c57b6afda7006ed6 · kevinherron/modbus-server-driver · GitHub

1 Like

Terminology here: do you mean Ignition Tag Browser or Ignition OPC browser?

If you create an OPC tag in Ignition, it will be subscribed and polled (possibly with caveats for leased tag groups). An OPC driver cannot tell if a value changes in the PLC unless it polls it (for common request/response protocols like Modbus/Logix/legacy Siemens).

This is now my understanding based on you and Kevin's explanations.
It does now make sense, and the terminology is a little bit overlapping the way I have used it.

If you create an OPC tag in Ignition, it will be subscribed and polled (possibly with caveats for leased tag groups). An OPC driver cannot tell if a value changes in the PLC unless it polls it (for common request/response protocols like Modbus/Logix/legacy Siemens).