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.
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?
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).
@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.
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?
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).