Multiple tag groups for one modbus device

I’m looking to validate my understanding of how tag groups work when you have different tag groups on tags looking at the same device (in my case, a modbus TCP device). I feel like I’m missing something pretty fundamental about how Ignition groups up these requests for execution behind the scenes, so it would be great if someone could give me a rundown of how it works (couldn’t find it in the docs, IU, etc)

What I want to do is to have tag groups with different history logging parameters, so I might have “My Device Slow History” and “My Device Fast History.” If I set both tag groups to have a direct execution rate of say 1 second, would Ignition be guaranteed to group them up into one batch of requests and fire it off every second - or could it end up staggered so some of the read requests might go off at 300ms past the second and some might go off at 700ms past the second?

The desireable outcome for me is for them all to be grouped up and execute together, so that the same number of requests are always hitting my device every time period. I also am heavily reliant on the only one concurrent request option, so it’s important to retain that functionality.

Once I’ve got my head around that one, I’d also like to understand what happens if I set half of the tags for my modbus device to 1 second and half to 3 seconds. Would it do a full poll every 3 seconds, then just do whatever polling it needs to on the other 2 cycles to collect just that group of tags? i.e. if I have span gaps on it would grab some smaller subset of tags, but if I don’t have span gaps on it would send many requests since some of my tags are only on the 3 second cycle?

Hopefully that made sense! Sorry for the wall of text.

I can’t give you a direct answer to your query but might give some food for thought.

Firstly, are you confusing the actual polling of the tag by the ModbusTCP device driver, with a scan class setting, and the history stored on the tag? If you have a tag with a scan class of 1s, and a ‘default’ (not ‘default historical’) history option enabled on that tag - well, you can only set the history option once, so to have it at both 1 second and 10 seconds you’d need two separate tags, both pointed at the same Modbus register, with two different history settings.

I’ve read a bit about what goes on behind the scenes, a quick search for anything by @k.herron or @p.turmel is always good reading (there are others too of course :slight_smile: )

e.g. Using runScript, any effects on Heap Memory - #6 by Kevin.Herron

I feel the answer you may get to this is, there is some level of asynchronous nature, so to guarantee interval specific logging, use transaction groups not historian.

Another on scan class optimisation

I’m definitely confusing the actual modbus polling with the scan class on the tag and still can’t separate them out in my head.

They don’t have to all log at the exact same time like transaction groups give us; I’m totally fine with logging being asynchronous. I just need to be sure that using different transaction groups with the same execution rate doesn’t affect how the Modbus driver is polling (my limitation is that I can’t afford to poll the device any more often than planned or it may be overloaded).

An explanation on your span gaps query:

I’ll try and give a clearer example of what I want to do:

  • My first 5 holding holding registers are HR0, HR1, HR2, HR3, HR4
  • I want to do a read multiple registers request once per second to collect all 5 registers from the device
  • I want to use tag groups to define history parameters for tags, so my slow moving HR3 tag might only need to be logged once per 3 seconds, but HR0, 1, 2 and 4 need to be logged every second
  • To solve this I put HR3 in a tag group “Slow History” with an execution rate of 1000ms and a 3 second history logging rate. I put the other registers in a different tag group “Fast History” with a rate of 1000ms and a 1 second history logging rate

My concern here is that this happens:

  • On second 1 it requests HRs 0-5
  • On second 2 it requests HRs 0-5
  • On second 3 it requests HRs 0-5
  • Somewhere between second 3 and second 4 it separately requests HR3 rather than combining it with the other request

(Span gaps being off would make it worse since it would end up sending three requests in second 3.

This won’t happen. The OPC/driver layer knows nothing about your history rates. It sees them all as having a 1000ms sampling interval and will put them into the same request.

1 Like

Woo, thanks!

What does it do if you have weird sampling intervals? Like 500ms and 1000ms with the same device? Will it look at these configurations and know to do the 500ms batch by itself, then both batches in one go every 1000ms? Or will it not realise they’re linked because they had different timings on them and execute them separately?

The sampling interval is the key by which requests are grouped. If you request HR1 at both 500ms and 1000ms you’ll have 2 separate requests executing, one running at 500ms the other at 1000ms.

Individual requests are the “unit” that is created, scheduled, and executed, not any kind of “request group”. When a subscription is created or modified optimization of all the individual items into some number of requests occurs. First they are grouped by sampling interval, then optimization of each group into requests happens. The optimization strategy depends on the protocol.

The old set of scheduled requests is then cleared and all of the new ones are queued for execution. After each request executes it schedules itself to be queued and executed again the future. Each request is its own island, it doesn’t know about the timing of any other requests. Initially everything will execute “all at once”, depending on the concurrency settings, and then after that they will slowly settle into their own self-scheduled rhythm.

If a driver has a concurrency setting it is always honored. The “request executor” that things are scheduled and queued to execute with always ensures this. There are varying implementations of it, but basically when concurrency == 1 it’s acting like a MPSC queue and when concurrency > 1 it’s acting like a MPMC queue, where the number of consumers is equal to the concurrency, resulting in multiple requests executing at once.

1 Like

When a subscription is created or modified optimization of all the individual items into some number of requests occurs. First they are grouped by sampling interval, then optimization of each group into requests happens. The optimization strategy depends on the protocol

Ah right, so once subscriptions are made, the driver will pool all of the subscriptions and decide what it thinks the most efficient actual requests to the device are to deliver on those subscriptions. At that point, the initial subscriptions have all been unpacked and it doesn’t matter if 1 or 200 subscriptions delivered that set of data collection requirements. Did I get that right?

So in my example above, I’ve subscribed to various tags at 500ms and 1000ms, so the optimisation algorithm (for modbus specifically), will do something like…set up a request every 500ms for that subset of the tags, then a request every 1000ms for all of the tags?

It will request only the tags belonging to the 500ms group every 500ms and only the tags belonging to the 1000ms group every 1000ms.

There would only be overlap in what is read if you have tags with the same Modbus address belonging to both groups or if a request from each group happens to span the same register gap (e.g. you read register HR1 and HR5 @ 500ms and HR3 and HR 7 @ 1000ms - that results in a request for HR1 through HR5 @ 500ms and a request for HR3 through HR7 @ 1000ms, with HR3/4/5 being read by both requests. The Span Gaps setting controls enables or disables this gap behavior).

So if I have span gaps on, I’d have 1 request being sent to the device at (or around) t=500ms, then two requests being sent to the device at t=1000ms (one for the 500ms group and one for the 1000ms group), right?

Never mind you actually just exactly wrote that above - sorry!

What if both of my tag groups have a 1000ms scan rate? Will I still get two requests?

The number of requests will depend only on what addresses are being requested. The driver doesn’t care they are from different tag groups, it just sees they both have the 1000ms rate so it groups them together in that first optimization step. You won’t end up with requests doing duplicate work this way.


Perfect! Thanks for sticking with me on this - it looks like having slightly different tag group execution rates would have been a disaster for me, but having the same tag group execution rates will be a significant time saver. :ok_hand:

1 Like