Fifo array of controllogix UDT to flattened dataset

I brought in a controllogix fifo array of a UDT to the tag database. This mapped as Fifo_Array (folder) with sub folders -> Fifo_Array[0]...[n] (folder) with atomic tags in each sub folder in the tag database.

I'd like to flatten this structure into a dataset tag (memory, reference, derived?) to use as a data source for various controls. Is there a practical way to achieve this such that it updates cleanly with data changes in the underlying fifo array?

I was able to somewhat achieve the desired 'view' for a single (perspective) table control with a system.tag.query() transform script. However I had to point it at a single atomic tag within (the first) udt folder of the array to get the script to fire on a change to the fifo, and associated had to add a significant time.sleep(2) to the script (which could lead to synchronicity issues as well?) to allow for the opc data to fully update before the script fired so that the perspective control wouldn't be only partially correct.

I'd prefer to have it packaged nicely in a dataset tag for replication, maintenance, and hopefully visual concurrency in the perspective control views. Functionally the end goal I'm trying to achieve is to display an up to date look at the FIFO in various perspective views with a few of the udt attributes displayed. (Fifo Index, timestamp, value)

Why is this unacceptable? It's fairly straight foreword to convert a set of tags, particularly when the names are very similar, into a list of values or a dataset if you prefer, there really is no need to convert this to dataset tag, you are really only adding load to the gateway for not a whole lot of gain. There are potentially ways around that, but I'm interested in why this structure is unfavorable.

As an example, if I wanted to turn the example of tags into a single column dataset the following code would accomplish that task.

tagPaths = ['[default]Fifo_Array/Fifo_Array[{}]'.format(index) for index in range(fifoLength)]
fifoDs = system.dataset.toDataSet(['Fifo'],[qv.value for qv in system.tag.readBlocking(tagPaths)])

Obviously, not too much work to add other attributes depending on where they are coming from.

Generally, anytime you are using time.sleep() in Ignition you are doing something that is better done another way. So I would agree, you don't want to do this this way.

If each Fifo Item will have attributes that are unique to it, why not use Ignition's UDT's to build a structure that makes since for use in the HMI? Ignition's UDT's do not have to match the controllers.

3 Likes

@lrose, thanks for the quick response!
I appreciate the code example and will test it out. I was unaware of the toDataSet function.

I'm very new to Ignition, so please forgive my ignorance if I'm approaching things illogically.

I didn't say the import structure was unacceptable or unfavorable. In fact it was quite expected based on similar systems. Having used a query tag returning a dataset it was easy to just drop the tag path into a perspective table control, and have data show up as intended. I was just looking to create similar entity for the FIFO data that would maintain state with the controller.

My intent is not to generate extra load however, so if a reference dataset isn't a viable approach, then that is ok.

I do intend to use the Ignition UDTs wherever practical. Mapping the UDTs to the base tags for each instance seems like it might be easily done from a parameter and some clever paths. However, I expect I will still have to code in some transform for display in a (e.g. perspective table) control as intended, so I'm not certain it makes a whole lot of difference vs the existing folder structure in this case. I'll give it a try though.