Determine if any tag in folder is in alarm

Been years since I've touched Ignition. Working on big Perspective project. I need to know if there is an "easy" way to determine if any tag within a tag folder is in an alarm state. Example is a structure like "Filters/Filter1/INF_VLV". In that folder there may be a UDT with several possible alarms, as well as individual tags that could be alarmed. Is there any sort of script/function that would return a boolean if any of the alarm states are active for just that folder? Reasoning is I want a yellow border around my screen badge, but want it to be universal to fit folders with any number of alarms rather than scripting a bunch of "or this or that or..." that has to be changed for multiple items. Any assistance greatly appreciated.

Tags do have an HasActive boolean in the Alarms property:
image

But I'm not sure you can reach it through scripting.

Another solution would be to pass the results of a tag browse to system.alarm.queryStatus

You can filter system.alarm.queryStatus() based on source and state. Unless I am missing something I think the it should work in your case. The following returns a list of all active alarm within the folder Pumps.

system.alarm.queryStatus(state = [2,3], source = "prov:default:/tag:Pumps/*")

You could then perform a check to see if it returns anything and use that to determine whether or not to show the border and badge.

1 Like

I think you could do one better with expression.

isAlarmActive("[default]Pumps/*")

Seems to do the same thing.

3 Likes

There are some exchange resources that may be helpful, here is one:

Thank you so much! I will give that a try.

I've tested this function successfully. Problem now is how do I make it "Dynamic". Have fullscreen view which calculates parameter "TagPath" based in a filter number (i.e. [default]Filters/Filt1). In that filter are UDT's for valves, say INF_VLV. Have smaller view with badge for each valve that looks for parameters based on "TagPath" and appends "/INF_VLV". Can I pass a calculated strings into the isAlarmActive script function to dynamically change the style of the badge view (like draw a red border around it). Just can't seem to figure out how to "parameterize" this without creating a new "tag" within each UDT (which would be a big hassle).
Again, any assistance greatly appreciated.

You should definitely be able to accomplish this. You should be able to bind to the TagPath parameter on the subviews isAlarmActive({this.params.TagPath}) within the smaller valve view. You will probably have to add a /* to the end of the path that way you are checking all tags within the valve UDT for an alarm. isAlarmActive({this.custom.TagPath+'/*'})

Thank you. I have been trying that. Ignition is giving me grief! I am testing with a memory tag. Created a label and bound the text to "isAlarmActive({view.custom.AlarmPath})". [created custome property of AlarmPath which is TagPath " "/*"]. If I toggle an alarm bit, the Binding Preview updates correctly (true or false). However the View label does not update until I check the binding. Toggling the bit does not change the label, but if I toggle the bit, check the binding preview and close it, the label updates.
However, if I create a memory discrete tag bound to the isAlarmActive expression it updates in realtime.

I've experienced difficulties doing what I wanted with isAlarmActive() a while ago, though I can't recall exactly what they were.

If you do decide to go the Python route, this post contains a great example of how to get more mileage out of system.alarm.queryStatus().

I think the issue you are facing is that isAlarmActive() does not poll in perspective and if you use /* it does not detect the tag change.
I am not sure if this is the most elegant solution but you could spoof polling.
if(now(1000)>0,isAlarmActive({this.view.AlarmPath}),isAlarmActive({this.view.AlarmPath}))
If the alarm paths are consistent it may be easier to try and avoid using /* that way it refreshes on tag change.

Thank you. I figured it had something to do with polling. I may just add an expression tag to each UDT that uses the isAlarmActive([.]/* and reference that, since that is a polled tag.
Thanks again for your assistance!

1 Like

I don't think that works.
I just tried with now(3000) and it still triggers more than every 3 seconds.

edit: I'm a bit surprised at what I'm seeing, using now(poll_rate) in a binding...
I'm kinda sure I've used now(x) to trigger something every x seconds before, but I can't get that to work anymore...

You can vote on this feature:

The poll rate to now() is milliseconds, but only works in an event-driven context. Expression tags have many execution modes, and event driven is just one of them. (Same is true for the poll rate argument to runScript().)

I did my tests on a component custom properties, not on tags.
But that would explain why I got different results than what I thought I'd get.

It appeared to be working correctly for me. Maybe you had another event causing it to execute. If you leave off the /* it will reevaluate on tag change.