Trying to extract tag data to make a dataset

I've done this a couple of times now. Here's my approach.

I use a dataset tag to store the data, rather than throwing it directly in a component. Use an expression tag to runScript() and create the dataset from the tags as you have done above.

This script lives in the project library so it can be called from an expression tag.

I've also taken it one step further and allowed the execution rate of the expression tag to be variable based on if the table is being displayed or not. Really, no need to execute it at all if it's not being displayed, but I leave the execution rate at 30 seconds when not displayed and update it to 1 second when it's displayed.

That's what custom properties are for. You can store the dataset in a custom property, and then if you need to later convert it back into a list of dicts just use that.

Though if this is perspective and you need it as a list of dicts, then just generate a list of dicts (Array of Objects in the world of perspective).

Thank you!

Good to know, am I able to get assign the custom property in the script editor after creating the first dataset? How do I access this in the second dataset creation script editor so I can do the appending?

Yes.

Is this vision or perspective?

Vision. Thank you.

Wait, what ?
There's a second dataset now ?

You should throw an eyeball or two at this thing: https://xyproblem.info/

Let's make things crystal clear:
You want to read a set of tags, make a dataset out of them where the header is their names and the single row contains their values, to append this to another dataset with matching columns.

Where is this second dataset coming from ?

In any case, this will make one of the datasets:

tag_paths = [...]

header = [p.split('/')[-1] for p in tag_paths]
values = [qval.value for qval in system.tag.readBlocking(tag_paths)]

ds = system.dataset.toDataSet(header, [values])

I see where @Irose is going with this. You can just create a custom dataset property on each button and populate it with the onActionPerformed script. Then, use a binding to combine the two sets of data for display.

Okay, so on some component, usually where ever you going to display the final dataset right click and select Customizers -> Custom Properties.

In that popup you can click the + icon to add a new property. Give it a name and select the type to be dataset.

https://docs.inductiveautomation.com/display/DOC81/Vision+Component+Customizers

Then in the script area for the button's actionPerformed event add a script like this:

paths = ['path/to/tag1','path/to/tag2','path/to/tag3']

tagValues = [qv.v for qv in system.tag.readBlocking(paths)]
headers = [path.split('/')[-1:] for path in paths]
event.source.someProperty = system.dataset.toDataSet(headers,[tagValues])

Note that the path to the custom property (event.source.someProperty) will change based on where you chose to create the property. Use the property selector to get the correct path.

You can use system.dataset.appendDataset() in the second button script to append the two datasets and set the data property of the table (I presume) you are using to display the values.

Won't this throw an error, since values is already a list?

Nevermind, I'm an idiot.

Fixed my code. :man_facepalming:

values should be a list containing as many lists as there are rows in the dataset, each of those lists containing as many values as there are columns.

2 Likes

Thank you!