This is how we currently handle alarm summaries.
Call this from a gateway timer script:
def getAlarmSummaryAll():
global alarmSummaryGlobal
alarmSummary = {}
state = ["ActiveUnacked", "ActiveAcked", "ClearUnacked"]
alarms = system.alarm.queryStatus(state=state)
for alarm in alarms:
source = str(alarm.source)
tagPath = str(alarm.source).split(':')[3]
name = str(alarm.name)
state = alarm.state.name()
priority = alarm.priority.name()
alarmSummary[source] = {'tagPath':tagPath, 'name':name, 'state':state, 'priority':priority}
alarmSummaryGlobal = alarmSummary
I recommend placing this script in the project script as the one above. This script will get called from the UDT instance (which I describe below).
def getAlarmInstances(alarmPath):
global alarmSummaryGlobal
#Removes the tag provider is present
if alarmPath.find(']') != -1:
alarmPath = alarmPath.split(']')[1]
alarmPriorities = {'Diagnostic':0, 'Low':1, 'Medium':2, 'High':3, 'Critical':4}
statePriorities = {'ClearAcked':0, 'ClearUnacked':1, 'ActiveAcked':2, 'ActiveUnacked':3}
alarmStates = {'ActiveUnacked':'flash', 'ActiveAcked':'static', 'ClearUnacked':'flash', 'ClearAcked':'static'}
priorityCounts = {'Diagnostic': 0, 'Low': 0, 'Medium': 0, 'High': 0, 'Critical': 0}
priority = None
state = None
styleClass = None
hasUnackAlarm = 0
resultDict = {'counts': priorityCounts, 'priority': '', 'state': '', 'class': '', 'hasUnackAlarm': ''}
alarmPrioritiesList = []
for alarm in alarmSummaryGlobal:
#If alarm found within the summary then get counts and priorities
# The tagPath must match exactly starting from the left, this prevents partial matches
tagPath = alarmSummaryGlobal[alarm]['tagPath']
if tagPath.startswith(alarmPath, 0, len(alarmPath)):
#Create a list of alarm priorities, so we can later find the highest priority and state for that priority
alarmPriority = alarmSummaryGlobal[alarm]['priority']
alarmState = alarmSummaryGlobal[alarm]['state']
alarmPrioritiesList.append([alarmPriorities[alarmPriority], statePriorities[alarmState]])
if alarmState == 'ClearedUnacked' or alarmState == 'ActiveUnacked':
hasUnackAlarm = 1
if alarmPriority == 'Diagnostic':
priorityCounts['Diagnostic'] += 1
if alarmPriority == 'Low':
priorityCounts['Low'] += 1
if alarmPriority == 'Medium':
priorityCounts['Medium'] += 1
if alarmPriority == 'High':
priorityCounts['High'] += 1
if alarmPriority == 'Critical':
priorityCounts['Critical'] += 1
if alarmPrioritiesList:
alarmListMax = max(alarmPrioritiesList, key=lambda item: (item[0], item[1]))
priority = alarmPriorities.keys()[alarmPriorities.values().index(alarmListMax[0])]
state = statePriorities.keys()[statePriorities.values().index(alarmListMax[1])]
styleClass = alarmStates.get(str(state))
#Take the results and place in a dictionary
resultDict = {
'counts': priorityCounts, #A dicionary holding counts for each priority
'priority': str(priority), #The highest priority
'state': str(state), #The most important state
'class': styleClass, #The style class for indication purposes
'hasUnackAlarm': hasUnackAlarm #At lease one unacknowledged alarm exists
}
json = system.util.jsonEncode(resultDict)
return json
Attached is the alarm UDT (tagAlarms.json). You will need to set the correct path within the element summary
- replace question marks with your actual path to the script:
runScript('?????.getAlarmInstances',0,left({PathToParentFolder},lastIndexOf({PathToTag},{InstanceName})))
Now you can insert an instance of this UDT anywhere you want to get alarm summary information. You could use these instances for your table.
It should be noted that Iām not the best with Python, so any pointers/tips are welcome. I have tested with 100s of alarms and 100s UDT instances and the gateway didnāt break a sweat. There are some elements that probably wonāt be needed for your application, but I left those in. You can remove them or simply ignore them.
tagAlarms.json (2.3 KB)