Active alarm in area?

I would like to have a way of knowing if any PLC tag in a particular process area has an active alarm so that I can show in the HMI which areas have or do not have an active alarm. This could be used in a process overview display to show several process areas, and those with active alarms could have blinking red or something like that.

I think I would have to make use of the system.alarm.queryStatus function in a Python script. If tags for each process area are in separate folders, I could use this to return alarms in the specified folder.

Is there a better way to do this?

I do all such in the PLC(s) that generate the alarms, only using SCADA to combine across PLCs that cannot coordinate themselves.

2 Likes

I completely agree with and support that approach, but I would still like to know if there is a better Ignition solution than what I presented.

By the way, I have a Rockwell AOI called NewAlarm that does the PLC implementation of this; it is on my resource page https://dpas-inc.com/resources. However, there are times when circumstances make the SCADA solution the required or best approach

I use a UDT for this in Ignition that gets a summary of alarms based on where the UDT is located.

UDT json is attached Area Alarms.json (2.7 KB).

You’ll need this script as well to summarise the alarms, put under a script library called shared.alarms:

def getAlarmSummary(filterPath='*'):
	if filterPath.find(']') != -1:
		filterPath = filterPath.split(']')[1]
	alarms = system.alarm.queryStatus(priority=[1,2,3,4],
								 state=['ActiveAcked','ClearUnacked','ActiveUnacked'],
								 path=['*:/tag:%s' % filterPath])
	almCounts = {'ActiveAcked':0, 'ActiveUnacked':0, 'ClearUnacked':0}
	for alarm in alarms:
		if str(alarm.state) == 'Cleared, Unacknowledged':
			almCounts['ClearUnacked'] += 1
		if str(alarm.state) == 'Active, Unacknowledged':
			almCounts['ActiveUnacked'] += 1
		if str(alarm.state) == 'Active, Acknowledged':
			almCounts['ActiveAcked'] += 1
	
	json = system.util.jsonEncode(almCounts)
	return json

Then, simply instantiate the UDT anywhere you want a summary of alarms. Make sure to name it “Area Alarms”.

Edit:
This has a couple of dependencies:

  1. put the the script library into the gateway scripting project
  2. either change the expression tags’ tag group, or add a new tag group called Area Alarms, subscribed at a rate of x seconds (I set to 5s)
6 Likes

Thanks for the script. I have something wrong. Are there other steps to make this work?

I think I narrowed it down to the Alarm Summary expression

Sorry, I should have mentioned that the script library should be put into the project that is set to your gateway’s scripting project (if you’re upgrading from v7 then that’s your “global” project). Also, you can always double click on the alarm summary tag to edit it, then go to the diagnostics tab to check more details in the error. It’ll probably say something like “shared” scripting library doesn’t have element “alarms”

I fixed the scripting project so that the Alarm Summary tag works, but the jsonGet functions on Active Ack and Active Unack are not working.

D’oh, one last thing: I have a custom tag group for those two expression tags called “Area Alarms”
image

That’s one of the issues with posting something from a project which has multiple dependencies… I’ve updated my original post with these dependencies as well

Got it, it works. Thanks!

Hey @nminchin what were you using “Area PLCs for Alarm Reset” for?

Just curious. Thanks for posting this by the way.

1 Like

I store the names of devices (plcs) in there for more of the general areas (ie for area alarms instances in each area folder 1 level from the root) and use the list to write to the general alarm reset tag in each of those plcs. E.g. In all of our plcs we have a tag: HMI.AlarmResetPB which will reset all alarms in the PLC.

Worth mentioning that I’ve actually moved to a slightly different method of doing this now. It’s still fine if you’ve only got a few of these area alarms instances, but I was getting up to 60+ and my tag expressions threads were using about 7.5% CPU which I wanted to reduce. Nowadays I only call the alarm query status function once at the root level which stores the dictionary of all alarms inside a library variable. Then in all of the sub folder levels, I filter on the library variable and collect the alarms that way

3 Likes

Thanks @nminchin

I know this thread is old but wanted to jump in and say thanks for sharing the script, sir. I’m new to scripting and this was a huge help with trying to accomplish the same thing.

1 Like

@nminchin Hey Nick, how did you store the alarm results in a library variable?
I've tried using system.util.getGlobals() from a library function called on a Gateway Timer Script, but the variable doesn't update with new results.
If I use this same method inside the script console it updates with the latest alarm info.

Where did you confirm this from? Note the script console and gateway timer scripts are different scopes and have independent scripting environments

Just curious, why not use the built in Display Path for alarm sorting, filtering, groups, etc. I have a client tag that holds a selected display path to dynamically filter alarm presentation or query the current active alarms in an area.

For one, you can't call alarm.queryStatus from vision so you need a solution for that (you technically can call it at the expense of your operators' sanity - calling this from the gui frequently will create lag since it's slow and gui events/scripts etc in vision run in the one thread (the edt) )

Re perspective, it may not matter. I'm interested to time the function though compared to looking up the libaray dict

Hmmm....I run it in a client script and have never experienced any lag. Its literally included as a template in a new Ignition project for alarm count, so if it is that intensive, would seem not a grand idea by IA to include it as a default template. Ill be the first to admit, I'm very much still in the learning stage in regards to optimization and am continuously picking up tidbits in the forums from the more experienced users. Which quite honestly should be the last place I should have to look. IA really needs a best practices document that should be "Do this, not that" 101. Most of these are not even discussed in the various Ignition university tutorials or the paid courses. Without this forum and users like yourself, not sure where Id gather info. But then again, maybe ignorance is bliss :slight_smile: