Put all tags in a table (Ignition Perspective)

Hi all,
I’m using ignition perspective and want to put all my tags (/internal values) on display in a table. To do so, I have referenced a basic script that takes the info from the tags. This occurs on startup for a view.

However, the script uses the ‘system.gui.getWindow()’ function to put the data into the table, which is not available in perspective. I am not sure how to divert it onto a table inside this view.

I have also tried to point it with another method, however it is not recognized in perspective:
table = event.source.parent.getComponent(“Table”)
table.data = data

Try something like self.getChild("Table") You may also want to use the property browser to drill into where you want to go, it will do most of the work for you.
https://docs.inductiveautomation.com/display/DOC80/Perspective+Component+Methods

1 Like

Fixed, thank you!

Adding onto this, I was wondering if its possible to access data inside the tags from the script? For example, pulling the status/units, which is stored under the tag itself.

system.tag.browse only returns the name, path etc. Wondering if I can use the path and or name to look internally at the tag?

Sure:

engUnit = system.tag.readBlocking(['path/to/your/tag.EngUnit'])[0].value

You can read more than one tag at once as well:

tagQVs = system.tag.readBlocking(['path/to/tag1','path/to/tag2'])

system.tag.readBlocking() returns a list of QualifiedValues, where the index of the qualified value will be the same as the index of the path in the supplied tagPaths list.

https://docs.inductiveautomation.com/display/DOC81/system.tag.readBlocking

Not sure what you mean by status, perhaps you’re referring to the Quality?

1 Like

Sorry, it was another subtag, just like the EngUnit, I should have been more clear. I will try this out and hopefully be able to make some progress.

Additionally, when pointing to the table self.getChild(“Table”), I then pointed and put my info into the table. Is it possible to specifically put it in the first column and point something else at the second column with like data[0] and data[1]?

I'm not entirely sure what is your going for here, but you'll have to build the dataset yourself to accomplish this.

There are multiple ways, the first and probably the simplest would be to build a dataset.

tagQVs = system.tag.readBlocking(['path/to/tag.EngHigh','path/to/tag.EngLow','path/to/tag.EngUnit'])
headers = ['Eng High','Eng Low','Eng Unit']

self.getChild("Table").data = system.dataset.toDataset(headers,[[tag.value for tag in tagQVs]])

This would yield one row with 3 columns. Not knowing what it is you're going for makes it difficult to produce a good example.

Another approach is to use the object model (this is what you get when you add a table component to a view).

tagQVs = system.tag.readBlocking(['path/to/tag.EngHigh','path/to/tag.EngLow','path/to/tag.EngUnit'])
headers = ['Eng High','Eng Low','Eng Unit']

data = [{name:{'value':tagQVs[idx].value,'editable':True,'style':{'backgroundColor':'#ffffff','classes':'some-class'},'align':'center','justify':'left'} for idx, name in enumerate(headers)]

self.getChild("Table").data = data

Hi Irose, I’ll try to expain my situation a bit more:
I have a list of tags, A,B, C, D etc. Under each of these tags are the subtags (?) where the eng low and eng high are located.

I am then trying to navigate to these subtags and put them into the second column.

These are the tag properties.

You'll still have to build this yourself, it is possible.

tagPaths = ['path/to/tag/A','path/to/tag/B','path/to/tag/C','path/to/tag/D']
tagProps = ['EngHigh','EngLow','EngUnit']

allTags = []
for path in tagPaths:
    allTags.append(path)
    allTags + [path + '.{}'.format(prop) for prop in tagProps]

tagValues = {allTags[path]:tag.value for path,tag in enumerate(system.tag.readBlocking(allTags)}

headers = ['name','value','Eng High','Eng Low','Eng Unit']

rows = []
row = []

for path,value in tagValues.iteritems():
    if '.' not in path:
        if row:
            rows.append(row)
        row = [path,value]
    else:
        row.append(value)

rows.append(row)

self.getChild("Table").props.data = system.dataset.toDataSet(headers,rows)

I'm sure there is a more elegant way to write that code, but that should do what I think you want. Either way, you just have to build the dataset and then set the tables props.data property to that dataset. How you arrive at that really depends on what you want. Try to work it out, if you run into an issue, start a new post, show your code and any error you're getting and someone will try to help.

1 Like

Thank you! Yep, definitely need to go over this and scratch my head for a while but seems like the community is pretty helpful. Cheers

A modified form of @lrose’ solution to be a bit more idiomatic to both Ignition and Python conventions:

paths = ['Ramp/Ramp0','Ramp/Ramp1']
properties = ['Name', 'Value', 'EngHigh','EngLow','EngUnit']

allTags = [
    path + '.' + prop
    for path in paths
    for prop in properties
]

tagValues = system.tag.readBlocking(allTags)

# https://stackoverflow.com/a/434328
def chunker(seq, size):
    return (seq[pos:pos + size] for pos in xrange(0, len(seq), size))

data = [
	[qv.value for qv in chunk]
	for chunk in chunker(tagValues, len(properties))
]

ds = system.dataset.toDataSet(properties, data)
print ds
1 Like

Knew there was a more elegant way. :joy:

Should have thought of the name and value also being properties. :man_facepalming:

I’ll file that chunker function away, it seems useful.

I'm getting an error for this. I was able to get it to change, but now I get this error...

Error running action 'system.onStartup' on Demand Dashboard/nav/GE-MTRs@D/root/Table: Traceback (most recent call last): File "function:runAction", line 28, in runAction AttributeError: 'NoneType' object has no attribute 'props'

Here is my code...
def runAction(self):

tagPaths = ['_RSF1-RS910-x127_/UnitId 10/SerNum']
tagProps = ['name','value']

allTags = []
for path in tagPaths:
    allTags.append(path)
    allTags + [path + '.{}'.format(prop) for prop in tagProps]

tagValues = {allTags[path]:tag.value for path,tag in enumerate(system.tag.readBlocking(allTags))}

headers = ['name','value']

rows = []
row = []

for path,value in tagValues.iteritems():
    if '.' not in path:
        if row:
            rows.append(row)
        row = [path,value]
    else:
        row.append(value)

rows.append(row)

self.getChild("Table").props.data = system.dataset.toDataSet(headers,rows)

My guess is that self.getChild('Table') is returning none, instead of what you expect. Make sure that whatever self is, it actually does have a child component named 'Table'.

1 Like

Goodness, I was trying to apply the script to the table itself. Once in the "root" the script works. Thanks for helping clarify this @lrose

@lrose - for the example yielding one row and 3 columns, I am getting the following error. Any help would be greatly appreciated. My goal is to pull in multiple tags, each row will represent those tags. Then, each column will represent several tag properties.

Error running action 'system.onStartup' on Demand Dashboard/nav/GE-MTRs (1)@D/root: Traceback (most recent call last): File "function:runAction", line 6, in runAction AttributeError: 'com.inductiveautomation.ignition.common.script.Imm' object has no attribute 'toDataset'

Here is my Code:
def runAction(self):

tagQVs = system.tag.readBlocking(['_RSF1-RS910-x127_/UnitId 10/SerNum.name','_RSF1-RS910-x127_/UnitId 10/SerNum.value'])
headers = ['name','value']

self.getChild("Table").data = system.dataset.toDataset(headers,[[tag.value for tag in tagQVs]])

The function is toDataSet, with a capital S. On my list to fix, someday...
https://docs.inductiveautomation.com/display/DOC81/system.dataset.toDataSet

1 Like

Same error, different variable...

Error running action 'system.onStartup' on Demand Dashboard/nav/GE-MTRs (1)@D/root: Traceback (most recent call last): File "function:runAction", line 6, in runAction AttributeError: 'com.inductiveautomation.perspective.gateway.script' object has no attribute 'data'

Well, it's an attribute error still, but pay attention to the details.

The error is now with the requested access to the data attribute. That's because Perspective components don't have a direct .data attribute, they have different property scopes (props, custom, meta, etc) with types under those. You probably want self.getChild("Table").props.data. I would highly encourage you to get familiar with the property selector tool available to you when editing scripts in Perspective.

2 Likes