Summation of all values within Tag Folder

I have several Tag Folders with multiple tags within. These tags are individually shown in a bar chart (ie one bar chart per tag folder). What I would like to do is take the summations of these individual tag folders and show them in a pie chart. Thanks for your help.

What version of Ignition are you using?

Hi, it’s version 7.9.9.

Try using system.tag.readAll I’ve never tried this but it should work.

tags = ["Tags/T1", "Tags/T2", "Tags/T3", "Tags/T4", "Tags/T5"]
values = system.tag.readAll(tags)
system.math.sum(values)

EDIT: Also try using an expression tag to sum the tag values, this might be easier

You can’t sum qualified values, which is what you get from system.tag.read*() functions. You need something like this:

tags = ["Tags/T1", "Tags/T2", "Tags/T3", "Tags/T4", "Tags/T5"]
values = [x.value for x in system.tag.readAll(tags)]
print system.math.sum(values)
2 Likes

Ah, that makes sense. Good point.

Thanks for your help. I’m new to Ignition so am probably doing it wrong, but I can’t seem to get the above code to work (in a new expression tag that is). I used the exact same syntax, but substituted the tag folders with my own.

In an expression tag, all you have to do is add the tags together like below. You can insert your tags by browsing for them. Just click on the little tag icon on the right. The code referenced is if you want to write script to sum the values.

{[~]Tags/T1} + {[~]Tags/T2} + {[~]Tags/T3}

Thanks. Only problem with this method is it’s not dynamic. I have like ~60 tag values to sum already in one of my folders, and I would like it to include new tags if they are added in the future.

here is some code that I got to work, it probably isn’t the best way to do what you want. However, it did work. You could run this in an expression tag using runScript(), or use it in an event handler of a component. SumTest is my tag folder name, and “asc” sorts ascending. Here is a link to Ignition scripting functions that is really handy to look up syntax etc.

list1 = []
tags = system.tag.browseTagsSimple("SumTest", "ASC")
for tag in tags:
	 list1.append(system.tag.read(str(tag)).value)
print sum(list1)
2 Likes

Only thing I’d suggest here is including @pturmel’s code

list1 = []
tags = system.tag.browseTagsSimple("SumTest", "ASC")
print sum([x.value for x in system.tag.readAll(tags)])

A lot of single read() calls takes longer than one readAll.

I tried using the readAll() but I couldn’t get it to work

Keep in mind there are two different text-based coding languages in Ignition: Python and Expression. Python scripts can’t be used on Expression tags. The easiest (and maybe only) way to make your summation method dynamic is to use a python script. You can put the python code into your project scripts, and then call it from your expression tag using the expression command runscript() . If you do it that then you should make sure to use the “pollrate” argument so that the script runs only once per time-period, and doesn’t bog down your computer.

Next thing to consider: @dkhayes117 (and a couple of others) gave a really great examples using browseTagsSimple. But I’m pretty sure browsetag returns everything, including folders. So if you have a lot of tags in other folders that you don’t want to include in your summation, then you should be careful to make your browse exclude things you don’t want it to sum. So, your project script might look something like this:

def sumFolder(folderPath):
	 list1 = []
	 tags = system.tag.browseTagsSimple(folderPath, "ASC")
	 for tag in tags:
	 	 if not tag.isFolder():
	 	 	 list1.append(system.tag.read(str(tag)).value)
	 return sum(list1)

and then your expression in your expression tag might be like this:

int(runScript(project.sumFolder, 5000, "folder1")) + int(runScript(project.sumFolder, 5000, "folder2")) + int(runScript(project.sumFolder, 5000, "folder3")) + ...
4 Likes

Oh my bad, there would be a bit more to it

list1 = []
tags = system.tag.browseTagsSimple("SumTest", "ASC")
print sum([x.value for x in [y.fullPath for system.tag.readAll(tags)] ])

As for the browseTagsSimple returning folders, I think those probably evaluate as None when read, so the last line becomes:

print sum([x.value for x in [y.fullPath for system.tag.readAll(tags)] if x.value is not None])
1 Like

Thanks for everyone’s help! I’m slowly getting to grips with Ignition / Python etc I think…

One more thing to figure out: how to only include tags which contain a specific sub-string (for example, only include tags ending in “_AMPS”).

I’m massively impressed by the help I’ve received so far by the way. Seems like a great community!

You add something like

for tag in tags:
	if "_AMPS" in tag and not tag.isFolder():
		list1.append(system.tag.read(str(tag)).value)
return sum(list1)

Bingo! I managed to get it to work like this:

if (filt in tag.name) and (not tag.isFolder()):

I've set up a new 10 second scan class and set the expression tag to poll every 10 seconds. I'm still seeing quite high CPU usage though (probably due to the high number of tags in the folder I'm querying. I will monitor it, and if it becomes a problem, may look to do it another way (sum a table from historical tag data for example).

Thanks everyone again for your help. Very much appreciated.

Nice, Like @pturmel and @mrogers mentioned, if you can get the system.tag.readAll() to work, that should cut down on the CPU usage

@mrogers I've tried that code 50 ways and I can't get it to work

Today must not be my day, I got it wrong. It should be tags that has .fullPath done on each member, not the result of readAll()

tags = system.tag.browseTagsSimple("SumTest", "ASC")
print sum([x.value for x in system.tag.readAll([y.fullPath for y in tags])])
1 Like