New Alarm Alert as a Popup

Hello All. I am new to the Ignition and I have a scenario where I would need to show a popup window with a Message saying that there is a new active unack alarm. Let me tell what I am trying in brief. Getting the alarm count in the timer script and trying to do a popup based on the difference in number of alarms. The script seems to work in Script Console but it doesnt work when it is inside action performed of Timer script.
Here is the sample code:

import system
global lastcount

alarms = system.alarm.querystatus(state = Activeunacked)
currentcount = len(alarms)

if lastcount > 0 and currentcount <> lastcount
system.gui.messageBox(“New Alarm”)
lastcount = currentcount.

Please let me know where I am going wrong.

I would start this a different route. It looks like you are polling for changes to alarm states, when really, we should be reacting to events relating to alarm state changes. This is going to be a long winded answer, so hear goes.

  1. Create a new shared script. For this example, create it at shared.alarming. The following will create an object, that extends Ignition’s AlarmListener interface. This is how we get the alarm event from the gateway to the client.

Post the following code:

from com.inductiveautomation.ignition.common.alarming import AlarmListener
class MyAlarmListener(AlarmListener):
	def __init__(self):
		system.util.getLogger("MyAlarmListener").info("Constructing Object")
		
	def onAcknowledge(self,evt):
		system.util.getLogger("MyAlarmListener").info("OnAcknowledge")
		system.util.sendMessage(project="prime",messageHandler="onAcknowledge",payload = {"event":evt},scope = "C")
		
	def onActive(self,evt):
		system.util.getLogger("MyAlarmListener").info("OnActive")
		system.util.sendMessage(project="prime",messageHandler="onActive",payload = {"event":evt},scope = "C")
			
	def onClear(self,evt):
		system.util.getLogger("MyAlarmListener").info("OnClear")
		system.util.sendMessage(project="prime",messageHandler="onClear",payload = {"event":evt},scope = "C")

If you dont need one of the event, let’s say onAcknowledge, replace the code with

def onAcknowledge(self,evt):
	pass
  1. Create message handlers in the client scope. You will need onActive, onAcknowledge, and onClear defined, in line with what you put in MyAlarmListener

Hear is some sample code, which may be put into onActive.

	from java.util import Date
	name = payload["event"].getName()
	dPath = payload["event"].getDisplayPathOrSource()
	tStamp = Date(payload["event"].getActiveData().getTimestamp())
	message = "<html>New Alarm <b>%s</b> occurred at %s."%(str(dPath),tStamp)
	system.gui.messageBox(message,"New Alarm")
#	print payload["event"]
  1. Register the alarm listener with the system. This script essentially says “Hey, listen for every alarm, and use MyAlarmListener to figure out what to do”. Put this in the gateway startup script.
from com.inductiveautomation.ignition.gateway import SRContext
from com.inductiveautomation.ignition.common import QualifiedPath
context = SRContext.get()

l = shared.alarming.MyAlarmListener()
system.util.getGlobals()["alarm-listener"] = l

n = context.getSystemProperties().getSystemName()
v = QualifiedPath.Builder()
#	v.setSystem(n)

system.util.getLogger("listener test").info("registering listener")
context.getAlarmManager().addListener(v.build(),l)
  1. Finally, you need this in the gateway shutdown script.
from com.inductiveautomation.ignition.gateway import SRContext
from com.inductiveautomation.ignition.common import QualifiedPath
if "alarm-listener" in system.util.getGlobals():
	context = SRContext.get()
	v = QualifiedPath.Builder()
	
	system.util.getLogger("listener test").info("unregistering listener")
	context.getAlarmManager().removeListener(v.build(),system.util.getGlobals()["alarm-listener"])

If you have any questions, please let me know.

8 Likes

Let me try and update you how it works. Thanks for the reply. Appreciate it.

Hello,

I am interested in trying to achieve something similar, however I have 4 different systems displayed in one central location, so was wondering if we can filter the alarms by display paths, so the popups only show on the appropriate system screen not on all.

Hello. Building on this, can anyone tell if it’s possible and what method to use to get the tag provider for the tag alarm event raised?

For example dPath = evt.getDisplayPathOrSource() gives me the dasplay path attribute, I would like the tag Provider or even the tag name.

1 Like

Hi,

Thanks for this code!
When I tried this code on Ignition 8+ it failed because the following import in the gateway startup/shutdown script is changed in Ignition 8+.

from com.inductiveautomation.ignition.gateway import SRContext

That line of code is changed to:

from com.inductiveautomation.ignition.gateway import IgnitionGateway

Is there a list of all of the available data for the Alarm Payload?

When I use the onClear function in combination with the 'any change' alarm mode setting set to true then this isn't working. When I only change the 'any change' option to 'false' I do receive the message. Does anyone know why this is happening?

EDIT: It's probably because of the following (found in user manual):

Note: This alarm will never be "active" because each active event is paired with a matching clear event, instantly. Available for modes: Above Setpoint, Below Setpoint, Between Setpoints, and Outside Setpoints.

What would be the best way to receive the alarm with the value at his peak before the alarm gets cleared. I want to save this moment.