[BUG/FEATURE] Disallow commas and slashes in alarm names

v8.1.5

Not sure if this is fixed already, but someone added some alarms into my project and put commas and slashes into the alarm names which is obviously bad and caused issues.

Can the alarm name field please do some input parsing to stop illegal characters from making it into this field?

Specifically, the issue is that you can’t use script to read these alarms.
E.g.:

system.tag.readBlocking('Alarms/Stuff Broke Check Something/Alarms/Stuff Broke, Check Something.Priority')

>>ValueError: Invalid path element 'Alarms/Stuff Broke Check Something/Alarms/Stuff Broke, Check Something.Priority': Illegal character ',' (Line 1 , Char xxx)
1 Like

Any known work-around for reading alarm properties for an alarm with "illegal characters" in it's name.

For example trying to read this path
[default]Diagnostics/Redfish-00/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng/alarms/Percent Life < 25%.anyChange

Results in this error:

Traceback (most recent call last):
  File "<input>", line 2, in <module>
ValueError: Invalid path element '[default]Diagnostics/Redfish-00/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng/alarms/Percent Life < 25%.anyChange': Illegal character '<' (Line 1 , Char 107)

Pretty sure you will need to fix the name. Sorry.

As a general rule, make names in Ignition valid programming identifiers. (No spaces or special characters, and not starting with a digit.) Use documentation props and/or display names to carry more human-friendly names.

1 Like

Well, one potential work-around would be to query values using system.alarm.queryStatus() which does not seem bothered by the "illegal characters" .

Examples:

system.alarm.queryStatus(path=["*Percent Life < 25%*"])


path = 'prov:default:/tag:Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%'
results = system.alarm.queryStatus(path=[path])


for result in results:
	for propertyName in result.getProperties():
		print propertyName, "|",  result[propertyName], "|", result.get(propertyName)
>>> 
[{Source: 'prov:default:/tag:Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: 'f3d04a27-fdf6-48a2-8b5d-68c78341030c', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00B: Disk3_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: '340ead6f-6ae7-40ad-8fe4-3ea6f76443cd', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00A: Disk3_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk4_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: 'e670f1a5-d7f9-4619-8672-12cec8b9f7c7', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00B: Disk4_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk1_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: '14fa596e-3eb8-4f9b-ae5c-7053d6ed79cc', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00B: Disk1_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00/Systems/Storage/Drives/Disk2_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: '0165b344-d417-4717-9fdc-3485fddea050', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00A: Disk2_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00/Systems/Storage/Drives/Disk1_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: '88bcf99f-8d1b-4cb7-b0ff-9a89bfffe99c', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00A: Disk1_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=92.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk0_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: '7eaf5ce2-eac2-4d0b-979f-33ecc17979ab', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00B: Disk0_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00/Systems/Storage/Drives/Disk5_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: '9e7a166d-ed95-4a8a-8948-c9481c252ee0', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00A: Disk5_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00/Systems/Storage/Drives/Disk4_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: 'a75452ac-ecf0-4418-9a5b-26da7b84144e', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00A: Disk4_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk2_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: '417ddb52-8eaf-4eb7-9a4f-8f7dca808494', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00B: Disk2_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk5_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: 'd13e4906-d691-4bd8-b5ba-76cc499f0572', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00B: Disk5_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}, {Source: 'prov:default:/tag:Diagnostics/Redfish-00/Systems/Storage/Drives/Disk0_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%', Display Path: '', UUID: '56b55f79-d285-498e-8893-83973bb7399a', Current State: 'Cleared, Acknowledged', Priority: 'Medium', Active Data: {setpointA=25.0, activeCondition=true, activePipeline=ABL200MW/Diagnostics, shelvingAllowed=false, timeOnDelaySeconds=5.0, eventTime=Mon Nov 25 19:16:03 CST 2024, label=ABL01-SB-00A: Disk0_LifeLeftPercent Percent Life < 25%, priority=Medium, mode=Below Setpoint, eventValue=100.0, systemAck=true, clearPipeline=ABL200MW/Diagnostics, name=Percent Life < 25%, timeOffDelaySeconds=5.0, deadbandMode=Off}, Clear Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Ack Data: {eventTime=Mon Nov 25 19:16:03 CST 2024}, Runtime Data: {isInitialEvent=true, isShelved=false, isJournaled=true}}]
isInitialEvent | True | True
notes |  | 
itemPath | Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng | Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng
activeDuration | 0 ms | 0 ms
timeOnDelaySeconds | 5.0 | 5.0
shelvingAllowed | False | False
isActive | False | False
eventTime | Mon Nov 25 19:16:03 CST 2024 | Mon Nov 25 19:16:03 CST 2024
source | prov:default:/tag:Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng:/alm:Percent Life < 25% | prov:default:/tag:Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng:/alm:Percent Life < 25%
ackUserName |  | 
enabled | True | None
isAcked | True | True
mode | Below Setpoint | Below Setpoint
ackTime | Mon Nov 25 19:16:03 CST 2024 | Mon Nov 25 19:16:03 CST 2024
ackUser | None | None
clearTime | Mon Nov 25 19:16:03 CST 2024 | Mon Nov 25 19:16:03 CST 2024
deadband | 0.0 | None
timeOffDelaySeconds | 5.0 | 5.0
state | Cleared, Acknowledged | Cleared, Acknowledged
displayPath |  | 
displayPathOrSource | Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng/Percent Life < 25% | Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng/Percent Life < 25%
fullItemPath | default/Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng | default/Diagnostics/Redfish-00B/Systems/Storage/Drives/Disk3_LifeLeftPercent/ValueEng
itemName | ValueEng | ValueEng
label | ABL01-SB-00B: Disk3_LifeLeftPercent Percent Life < 25% | ABL01-SB-00B: Disk3_LifeLeftPercent Percent Life < 25%
priority | Medium | Medium
isJournaled | True | True
ackNotesReqd | False | None
timestampSource | System | None
ackMode | Manual | None
eventValue | 100.0 | 100.0
isShelved | False | False
ackDuration | 0 ms | 0 ms
activeTime | Mon Nov 25 19:16:03 CST 2024 | Mon Nov 25 19:16:03 CST 2024
isClear | True | True
eventState | Clear | Clear
name | Percent Life < 25% | Percent Life < 25%
deadbandMode | Off | Off
>>> 

I confess I don't have my head wrapped around potential downsides. But as I understand it alarm properties with dynamic bindings are included in the alarm event. More testing required to confirm.

Initial tests look good, seems I can get any alarm property, even ones not included in result.getProperties(), and even alarm associated data.

Here is a generalized solution, just substitute in your own alarmPath and list of propertyNames. I suspect there is some fatal flaw in this solution but haven't come upon it yet. Let me know if you find it useful.

def getQualifiedAlarmPath(path):
	from com.inductiveautomation.ignition.common import QualifiedPathUtils
	from com.inductiveautomation.ignition.common.tags.paths.parser import TagPathParser
	
	splitPath = path.rsplit("/Alarms/", 1)
	basicTagPath = TagPathParser.parse(splitPath[0])
	qPath = QualifiedPathUtils.fromTagPathNew(basicTagPath)
	if len(splitPath)>1:
		qPath = qPath.extend("alm", splitPath[1])
	
	return qPath

def getAlarmProperties(alarmPath, propertyNames):
	qualifiedAlarmPath = getQualifiedAlarmPath(alarmPath)
	result = system.alarm.queryStatus(path=[str(qualifiedAlarmPath)])[0]
	return {propertyName: result[propertyName] for propertyName in propertyNames}
	

import pprint
print "=== start"
alarmPath = "[default]_Test/Tyler/Test var-sim-analog with internal alarm context/ValueEng/Alarms/High Alarm > 25%"
propertyNames = ["source", "name", "enabled", "mode", "setPointA", "inclusiveA"]
alarmProperties = getAlarmProperties(alarmPath, propertyNames)
pprint.pprint(alarmProperties)
print "=== End"

Example results:

=== start
{'enabled': True,
 'inclusiveA': True,
 'mode': Above Setpoint,
 'name': u'High Alarm > 25%',
 'setPointA': 60.0,
 'source': prov:default:/tag:_Test/Tyler/Test var-sim-analog with internal alarm context/ValueEng:/alm:High Alarm > 25%}
=== End
1 Like