# How to dynamically get valid descriptions and display names for all alarm event properties?

**URL:** <https://forum.inductiveautomation.com/t/how-to-dynamically-get-valid-descriptions-and-display-names-for-all-alarm-event-properties/91994>\
**Category:** Ignition\
**Tags:** ignition81, scripting\
**Created:** [June 18, 2024, 6:15am UTC](https://forum.inductiveautomation.com/t/how-to-dynamically-get-valid-descriptions-and-display-names-for-all-alarm-event-properties/91994 "2024-06-18T06:15:40Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![tyler.bennett](https://avatars.discourse-cdn.com/v4/letter/t/f04885/32.png) [@tyler.bennett](https://forum.inductiveautomation.com/u/tyler.bennett)\
**Post date:** [June 18, 2024, 6:15am UTC](https://forum.inductiveautomation.com/t/how-to-dynamically-get-valid-descriptions-and-display-names-for-all-alarm-event-properties/91994/1 "2024-06-18T06:15:40Z")

</div>

When interrogating the properties ([CommonAlarmProperties](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.41/com/inductiveautomation/ignition/common/alarming/config/CommonAlarmProperties.html)) of an alarm event ([PyAlarmEvent](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.41/com/inductiveautomation/ignition/common/alarming/PyAlarmEvent.html)) object, as returned from [system.alarm.queryStatus()](https://www.docs.inductiveautomation.com/docs/8.1/appendix/scripting-functions/system-alarm/system-alarm-queryStatus) I have noticed that the getDescription() method returns a [LocalizedString](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.41/com/inductiveautomation/ignition/common/i18n/LocalizedString.html) object that has a readable description for some (most) properties while others return `¿enums.CommonAlarmProperties.ackTime.Desc?`

Similar anomalies for getDisplayName().

Does this represent a a lack of completion by Ignition developers or a lack of understanding on my part. Is there a way to dynamically get valid descriptions  
and display names for all alarm event properties?

I'm aiming to dynamically discover all available alarm event properties, with their display names and descriptions. I was aiming to do this dynamically rather than hardcode it to make it somewhat future proof (say IA adds more properties or revises descriptions in the future).

Example code:

```python
alarms = system.alarm.queryStatus()
if len(alarms):
	event = alarms[0]
	for prop in event.getProperties():
		print "{:19s} ({:26s}): {}".format(prop.getName(), prop.getDisplayName(),prop.getDescription())
	print "Alarm Event Object:", type(event)
	print "Alarm Event Property object:", type(prop)
	print "Alarm Event Property Description object:", type(prop.getDescription())
else:
	print "Query returned no alarms"

```

Example Results:

```plaintext
>>> 
notes (Notes ): Documentation about the alarm.
itemPath (Item Path ): The path of the item holding the alarm, not including the alarm name.
activeDuration (Active Duration ): The elapsed time between the alarm becoming active and being cleared, as a formatted string. Calculated against the current time if the alarm is still active.
timeOnDelaySeconds (Active delay (seconds) ): The time, in seconds, before the alarm will be considered truly active after the active condition becomes true. Also known as a "rising edge time deadband".
shelvingAllowed (Shelving Allowed ): Whether or not this alarm can be shelved.
isActive (Active? ): �enums.CommonAlarmProperties.isActive.Desc?
eventTime (Event Time ): �enums.CommonAlarmProperties.eventTime.Desc?
source (Source Path ): �enums.CommonAlarmProperties.source.Desc?
ackUserName (Ack'ed By (Name) ): �enums.CommonAlarmProperties.ackUserName.Desc?
enabled (Enabled ): Specifies whether or not this alarm is evaluated by the system.
isAcked (Acked? ): �enums.CommonAlarmProperties.isAcked.Desc?
mode (Mode ): None
ackTime (Ack Time ): �enums.CommonAlarmProperties.ackTime.Desc?
ackUser (Ack'ed By ): �enums.CommonAlarmProperties.ackUser.Desc?
clearTime (Clear Time ): �enums.CommonAlarmProperties.clearTime.Desc?
deadband (Deadband ): A numeric deadband for the alarm condition. The interpretation of this value depends on the deadband mode. Note that this deadband is separate from, and evaluated after, the tag's deadband.
timeOffDelaySeconds (Clear delay (seconds) ): The time, in seconds, before the alarm will be considered truly clear after the clear condition becomes true. Also known as a "falling edge time deadband".
state (Current State ): �enums.CommonAlarmProperties.state.Desc?
displayPath (Display Path ): An optional path (separated by "/") that will be used for display and browsing purposes.
displayPathOrSource (Display Path or Source ): �enums.CommonAlarmProperties.displayPathOrSource.Desc?
liveBranchCount (�enums.CommonAlarmProperties.liveBranchCount?): �enums.CommonAlarmProperties.liveBranchCount.Desc?
fullItemPath (Full Item Path ): The full path of the item holding the alarm, not including the alarm name. An easier to read version of Source Path.
itemName (Item Name ): The name of the item holding the alarm.
label (Label ): An optional name that will be used for display purposes. Provides a dynamic alternative to the static "name" identifier. If left blank, the name will be used.
priority (Priority ): The priority (or "severity") of this alarm.
ackNotesReqd (Ack Notes Required ): Select this option to require operators to provide some explanation when the alarm is acknowledged.
timestampSource (Timestamp Source ): Dictates whether the timestamp used on the alarm comes from the system or the value.
ackMode (Ack Mode ): How acknowledgement works for the alarm: Auto - Alarm is acknowledged when cleared. Manual - Alarm acknowledged by user. Off - Alarm is always marked as 'acknowledged'.
eventValue (Event Value ): �enums.CommonAlarmProperties.eventValue.Desc?
isShelved (Is Shelved? ): �enums.CommonAlarmProperties.isShelved.Desc?
ackDuration (Unacknowledged Duration ): The elapsed time between the alarm becoming active and being acknowledged, as a formatted string.
activeTime (Active Time ): �enums.CommonAlarmProperties.activeTime.Desc?
isClear (Clear? ): �enums.CommonAlarmProperties.isClear.Desc?
eventState (Event State ): �enums.CommonAlarmProperties.eventState.Desc?
name (Name ): The identifier of the alarm. Combined with the location of the alarm, this will be the unique id of the alarm definition. For dynamic values, use Label and/or Display Path.
deadbandMode (Deadband Mode ): Defines how the deadband value is used. If percent, the value (0-100) will be compared against the Eng. limits defined for the value.
Alarm Event Object: <type 'com.inductiveautomation.ignition.common.alarming.PyAlarmEvent'>
Alarm Event Property object: <type 'com.inductiveautomation.ignition.common.alarming.config.CommonAlarmProperties'>
Alarm Event Property Description object: <type 'com.inductiveautomation.ignition.common.i18n.LocalizedString'>

```

Ignition v8.1.41

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [June 18, 2024, 9:17am UTC](https://forum.inductiveautomation.com/t/how-to-dynamically-get-valid-descriptions-and-display-names-for-all-alarm-event-properties/91994/2 "2024-06-18T09:17:22Z")

</div>

> [@tyler.bennett](#):
>
> enums.CommonAlarmProperties.[...].Desc

It does look like this is the generic enum description property that simply hasn't been filled in.

```python
topAlarm = system.alarm.queryStatus()[0]
for prop in topAlarm.properties:
	if not prop.description or 'enums' in prop.description.toString():
		print '#', prop.displayName

```

Here are the properties with missing descriptions:

```python
# Active?
# Event Time
# Source Path
# Ack'ed By (Name)
# Acked?
# Mode
# Ack Time
# Ack'ed By
# Clear Time
# Current State
# Display Path or Source
# Event Value
# Is Shelved?
# Active Time
# Clear?
# Event State

```

---

<div class="post-metadata">

**Author:** ![tyler.bennett](https://avatars.discourse-cdn.com/v4/letter/t/f04885/32.png) [@tyler.bennett](https://forum.inductiveautomation.com/u/tyler.bennett)\
**Post date:** [June 18, 2024, 3:01pm UTC](https://forum.inductiveautomation.com/t/how-to-dynamically-get-valid-descriptions-and-display-names-for-all-alarm-event-properties/91994/3 "2024-06-18T15:01:40Z")

</div>

@Kevin.Herron, would this count as a bug (to be fixed)?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 18, 2024, 4:45pm UTC](https://forum.inductiveautomation.com/t/how-to-dynamically-get-valid-descriptions-and-display-names-for-all-alarm-event-properties/91994/4 "2024-06-18T16:45:41Z")

</div>

> [@tyler.bennett](#):
>
> I was aiming to do this dynamically rather than hardcode it to make it somewhat future proof

A laudable goal, but note that each module installed that interacts with alarming can add arbitrary properties, so the set of properties available to you is going to depend on if you have, for instance, alarm notification +/- each different alarm notification _type_ (Twilio, SMS, various third parties, etc).

That said, it's not like this shouldn't work.

In this particular case, it looks like an oversight on our part. We _do_ have bundle keys for the properties you're running into, but they're not formatted with the additional `.Desc` qualifier the `LocalizedString` is expecting:

```properties
enums.CommonAlarmProperties.isAcked=Acked?
enums.CommonAlarmProperties.isClear=Clear?
enums.CommonAlarmProperties.isActive=Active?
enums.CommonAlarmProperties.activeTime=Active Time
enums.CommonAlarmProperties.clearTime=Clear Time
enums.CommonAlarmProperties.ackTime=Ack Time
enums.CommonAlarmProperties.eventTime=Event Time
enums.CommonAlarmProperties.eventValue=Event Value
enums.CommonAlarmProperties.isShelved=Is Shelved?
enums.CommonAlarmProperties.shelveExpiration=Shelf Expiration

```

At least, for _most_ of the ones on your list. Some others simply aren't documented because of either a genuine accident on our part, or because they were never intended to be end-user facing, e.g. `liveBranchCount` is an internal counter for alarm pipelines, not something you should ever need or want to interact with as an end user. It's hard to separate those two, because most of this stuff has been in place for literally years.

Possibly you could work around the issue with most of the keys with something like this, that directly calls out to the localization mechanism based on the key provided in the `LocalizedString`, and tries to get the shorter variant if the first lookup fails:

```python
from com.inductiveautomation.ignition.common import BundleUtil

# returns None if key isn't present
i18n = lambda key: BundleUtil.get().getString(key)

def getDescription(fullKey):
    qualifier = ".Desc"
    return i18n(fullKey) or i18n(fullKey[:-len(qualifier)]) if fullKey.endsWith(qualifier) else fullKey

alarms = system.alarm.queryStatus()
if len(alarms):
    event = alarms[0]

    for prop in event.getProperties():
        print "{:19s} ({:26s}): {}".format(prop.getName(), prop.getDisplayName(), getDescription(prop.getDescription().getKey()))
    print "Alarm Event Object:", type(event)
    print "Alarm Event Property object:", type(prop)
    print "Alarm Event Property Description object:", type(prop.getDescription())
else:
    print "Query returned no alarms"

```

(Disclaimer: Untested, there may be one or more syntax errors, but hopefully it gets the point across.)
