Scope of filterAlarm and its prerequisites
The Alarm Status table and the Alarm Journal table both expose a filterAlarm extension function. The component calls it once for every alarm event it is about to display. It passes that event as alarmEvent and expects a boolean back. Return True to keep the row and False to hide it. The function only hides rows. It does not change which alarms the gateway evaluates, which pipelines run, or which records the journal stores.
The built-in code snippet shows only a handful of alarmEvent.get('propertyName') calls. Most of the keys it accepts are defined in the Java class CommonAlarmProperties. The alarm objects are not very script-friendly, so get the key list from that class rather than guessing names.
Before anything else, confirm three things:
- You have Designer access with the Script Console available.
- The table component already shows alarms with no filter. Leave
filterAlarmempty or returningTrue. - At least one test alarm can be forced active, acknowledged, and cleared on demand.
Do not move on until the unfiltered table shows the test alarm in each state.
Property list dump from the Script Console
Run this in the Designer Script Console:
from com.inductiveautomation.ignition.common.alarming.config import CommonAlarmProperties
for p in CommonAlarmProperties.values():
print p, p.getType()
Printing CommonAlarmProperties.values() on its own returns the whole array on one line. The loop prints one property per line, followed by its Java type. You need the type later when you write comparisons.
Check: the output lists every name in the table in the next section. If the import fails, recheck the package path character by character. com.inductiveautomation.ignition.common.alarming.config is case-sensitive.
alarmEvent property reference
The dump returns the following names, grouped here by what they answer in a filter.
| Group | Property names | Typical filter use |
|---|---|---|
| Identity and path |
name, displayPath, displayPathOrSource, source, itemPath, fullItemPath, itemName, branchDepth, eventId
|
Area or line filtering, excluding test tags |
| Live state |
state, eventState, eventValue, isActive, isClear, isAcked, isShelved, shelveExpiration
|
Hide cleared or shelved rows, show only unacked alarms |
| Event flags |
isSystemEvent, isInitialEvent, systemAck, eventNotificationCanceled, legacySendClear
|
Suppress system-generated or startup events |
| Acknowledgement |
ackUser, ackUserName, ackNotes, ackTime, ackMode, ackNotesReqd
|
Operator-specific views, audit screens |
| Timing |
eventTime, activeTime, clearTime, activeDuration, activeDurationMS, ackDuration, ackDurationMS, timestampSource
|
Hide chattering or short-lived alarms, show stale unacked alarms |
| Configuration |
enabled, priority, notes, deadband, deadbandMode, timeOnDelaySeconds, timeOffDelaySeconds, shelvingAllowed, filter
|
Priority thresholds, configuration review screens |
| Pipelines |
activePipeline, clearPipeline, ackPipeline, pipelineTransitionCount
|
Diagnostics on notification routing |
For numeric duration comparisons, prefer the MS variants (activeDurationMS, ackDurationMS). They avoid parsing a duration object.
Value types inside filterAlarm
Many values are Java objects, not Python strings. priority is an enum. source is a path object. The time fields are dates. A comparison such as alarmEvent.get('priority') == 'High' compares an enum to a string, so it silently returns False. Log the real values before you write any logic:
def filterAlarm(self, alarmEvent):
log = system.util.getLogger('AlarmFilterDebug')
for key in ['priority', 'state', 'eventState', 'isAcked',
'isShelved', 'source', 'displayPath', 'activeDurationMS']:
v = alarmEvent.get(key)
log.info('%s = %r type=%s' % (key, v, type(v)))
return True
- Save the function, then trigger the test alarm.
- Read the log output. For Perspective components, look in the gateway logs. For Vision components, look in the client or Designer output console.
- Record the type and exact text of each value you plan to filter on.
If a string key raises a type error in your component scope, pass the Property object instead. Build a lookup once from the class:
from com.inductiveautomation.ignition.common.alarming.config import CommonAlarmProperties
PROPS = dict((str(p), p) for p in CommonAlarmProperties.values())
# usage: alarmEvent.get(PROPS['displayPath'])
Check: every key you intend to use logs a non-None value for the live test alarm. Remove the debug loop once you have the values. filterAlarm runs per row on every refresh, and logging there floods the log.
Filter logic and recurring pitfalls
Convert values to strings or primitives before comparing them, and guard against None:
def filterAlarm(self, alarmEvent):
path = alarmEvent.get('displayPathOrSource')
path = str(path) if path is not None else ''
if 'Test' in path:
return False
if alarmEvent.get('isShelved'):
return False
prio = str(alarmEvent.get('priority'))
if prio in ('Diagnostic', 'Low'):
return False
dur = alarmEvent.get('activeDurationMS')
if dur is not None and dur < 5000:
return False
return True
Use the exact priority text strings you recorded in the logging step.
| Symptom | Cause | Correction |
|---|---|---|
| Filter hides everything | Enum or path object compared to a Python string | Wrap the value in str(), or compare against the logged enum text |
| Rows vanish only on the journal table | Live-only properties return None for historical records |
Treat None as "keep" unless you intend to drop the row |
| Script error on some rows only |
ackUser, clearTime, or ackTime is empty on unacked or active alarms |
Test for None before calling methods on the value |
| Table becomes sluggish | Logging, database queries, or tag reads inside filterAlarm
|
Keep the function to pure property comparisons |
| Area filter misses some alarms |
displayPath is blank on alarms without a configured display path |
Filter on displayPathOrSource or source instead |
End-to-end verification
- Force the test alarm active. Confirm it appears or disappears according to each rule, one rule at a time.
- Acknowledge it. Confirm that rules based on
isAcked,state, orackUserchange visibility as expected. - Shelve it, where
shelvingAllowedis true. Confirm the shelved-row rule hides it, and that it returns when the shelve expires. - Clear it. Confirm rules based on
isClearandclearTimebehave as expected. - Open the Alarm Journal table over the same time window. Confirm the historical records obey the same rules and that no row throws a script error.
- Check the gateway or client log. Confirm the filter wrote no exceptions during steps 1 to 5, then deploy the component.
FAQ
How do I list all alarmEvent properties in Ignition?
Run from com.inductiveautomation.ignition.common.alarming.config import CommonAlarmProperties and then print CommonAlarmProperties.values() in the Script Console. The output includes name, priority, displayPath, state, isAcked, activeDurationMS, fullItemPath, and the rest of the keys that alarmEvent.get() accepts.
How do I filter alarms by priority in filterAlarm?
Read alarmEvent.get('priority') and convert it with str() before comparing. The raw value is an enum, not a string. Return False for the priorities you want to hide.
How do I hide shelved or cleared alarms in the alarm table script?
Return False when alarmEvent.get('isShelved') or alarmEvent.get('isClear') is true. Guard both checks against None on the journal table.
Why does my filterAlarm return nothing even though alarms are active?
The usual cause is comparing a Java object, such as a priority enum or a source path, directly to a Python string, so every comparison fails. Log each value with system.util.getLogger to see its real type, then compare against str(value).