UADriver - Subscribed item quality after driver restart

When a driver is restarted, all the subscribed items have ‘Unknown’ quality until the driver is connected. They only get updated after any client executes a read on the item.
For example, i implemented a diagnostic ‘IsConnected’ tag for my driver. If this tag is subscribed, i want it to show the correct value after a restart, even before the driver is connected.
What i currently do is calling VariableNode#setValue immediately after adding the node to the NodeManager. This way, the subscriptions are updated.

Is it safe/reliable to do it this way, or is there any other method to get subscriptions updated before the driver enters the connected state for the first time?

This is safe to do.

VariableNode#setValue(DataValue) is actually what ends up getting called any time your driver answers a read call (ReadItem#setValue(DataValue)) or updates a SubscriptionItem (extends ReadItem, same call).

The only clarification I want to make is that, assuming the client is subscribed to a tag, they get updated once the driver starts up and receives the current SubscriptionItems from the server, not necessarily when the client executes a read call (although that would update it as well). It’s just important to note that there is a distinction between read calls and being subscribed to something.

Thank you for this information.

Just a little comment:

That is exactly my problem. The subscriptions do not get updated because the driver does only receive the Driver#subscriptionChanged call after the state changes to 'Connected' for the first time. If any client executes a Read in this state, the subscriptions get updated, which makes now sense to me, when the Read calls VariableNode#setValue and triggers a subscription update. (I just checked with your Siemens driver, that behaves the same way. A subscription to 'Is Connected' is updated from 'UncertainInitialValue - Null' to 'Good - False' if any client Reads the value).

p.s. Can you please add my account for module signing?

The behavior of AbstractDriver is to basically do nothing with calls to read, write, or subscribe until the driver is in the connected state. This decision made sense at the time, as the meta/status tags didn’t exist yet. If I get some time soon I’ll see if this can be changed without much risk.

I’ll talk to Travis about adding your account for module signing, I’m not sure where that actually gets done at!

I don’t think this is much of a problem, but if you’ll really get time soon™: This seems to happen at a deeper level than AbstractDriver (i finally ended with my own implementation of the Driver interface and Driver#subscriptionChanged).

You’re right, there’s another piece higher up in the server where it doesn’t give a device its SubscriptionItem’s until it moves into the connected state. This is even trickier to change, since there’s no way to determine which items are meta/status tags and which aren’t at this point.

Has there been any changes to this lately? In 7.5.2, i observe that my device receives a subscription change independent from the connection state when a client adds a subscription or after the gateway is restarted. I not sure is this is the same behaviour as in older version.
Now, when the device state changes to ‘Connected’, all active subscriptions are added a second time, resulting in two subscription items for any client item. When the client disconnects, only one of the subscription items is removed from the driver, and it keeps updating an unused subscription for ever. This doesn’t seem to cause any problems, but i can imagine that it will noticable increase memory usage when there are a lot of subscriptions.

Just as a side note: The Unified Automation Client doesn’t like your trial mode. When a item is subscribed from this client and the trial expires, it will start a new connection every few seconds. After a few hours doing so, the gateways heap memory usage grows really laaaaarge…

Are you still extending from AbstractDriver?

No, i finally implemented the Driver interface myself. I bypass the subscription system when not connected by working directly with the VariableNode. I have internal data buffering in the driver that should be available to cleints even if the driver is not connected. Maybe i will make the whole thing public if finally everything passes my stress tests.
But your Siemens driver shows the same behaviour (visible when SubscriptionModel logging set to Trace).

Sorry, there’s a number of subscription model’s in Ignition, what’s the full name of the one you’re talking about? I want to try and reproduce this.

I think used drivers.S7300Driver[xxx].BasicSubscriptionModel and drivers.S7300Driver[xxx].BatchingSubscriptionModel. One of them shows in the log the count of tags in the AggregateSubscriptionItem.

If you’re not extending AbstractDriver there is no logic preventing read/write/subscribe calls from reaching your driver before you’ve gone into CONNECTED state.

There is, however, one piece of logic that WILL wait until you’re CONNECTED, and that’s the subscription model for your driver that the server is keeping track of. It tracks all the monitored items that are targeting your driver, and whenever your driver is removed and then added or restarted (basically, if your driver needs to know what to subscribe to but you can’t count on a UA client to go and make those calls because it thinks it has already made a subscribe call to the server) it calls subscribes all the items once you go CONNECTED state.

I realize this stuff is confusing, undocumented, and a bit inconsistent. I have plans to do some major “cleanup” in the driver API to smooth out some of the rough parts like this, but I won’t be getting time to work on it until after we release 7.6.

Oh, the system is not so bad, once one understands how it works. Nevertheless it would make sense to give the driver an opportunity to check for subscriptions on startup.

My post above was basically about the second subscription added to each driver on connect and never removed. As i said, it does not cause any problems, but i feel always a bit concerned if something is created in Java and never removed. Looks like there is some listener waiting for the driver to connect the first time and then simply adds all subscriptions again instead of replacing the old ones.

One more thing about subscriptions: In the gateway, there is a setting for a stale timeout (multiplier of the subscription rate). Is this implemented? Im asking because everything works fine even if my driver never calls setValue for SubscriptionItems.

This is one of the changes I am going to introduce. You'll be able to get your subscription model at any time from the DriverContext you're given during initialization.

[quote="chi"]
One more thing about subscriptions: In the gateway, there is a setting for a stale timeout (multiplier of the subscription rate). Is this implemented? Im asking because everything works fine even if my driver never calls setValue for SubscriptionItems.[/quote]

It was actually broken in 7.4, but works again for 7.5. It looks at the UA Nodes in question, not the SubscriptionItems, and it sounds like you are updating the nodes directly.