system.tag.getAlarmStates alternative?

I had a function working which would pass a tagpath from a tag tree and display all the alarms under that path in a table. Since 8.0 the tag.getAlarmStates has been romved is there another option for this?

tags = system.tag.browseTagsSimple(dsSelected.getValueAt(0, 0), "ASC")
headers = ["Tag Name", "Alarm Name","Label","Active Pipeline","SetPointA","DisplayPath","Priority","enabled"]
data = []
for tag in tags:
	try:
		tagDefs = system.tag.getAlarmStates(tag.fullPath)
		for tagDef in tagDefs:		
			priority = 0
			for prop in tagDef.getAlarmProperties():
				if str(prop.property) == 'activePipeline':
					try:
						active = str(prop.value)
					except:
						pass
				elif str(prop.property) == 'setpointA':
					try:
						setPoint = str(prop.value)
					except:
						pass
				elif str(prop.property) == 'displayPath':
					try:
						displayPath = str(prop.value)
					except:
						pass
				elif str(prop.property) == 'priority':
					try:
						priority = str(prop.value)
					except:
						pass
				elif str(prop.property) == 'enabled':
					try:
						enabled = str(prop.value)
					except:
						pass
				elif str(prop.property) == 'label':
					try:
						label = str(prop.value)
					except:
						pass
			data.append([tag.fullPath,tagDef.alarm,label,active,setPoint,displayPath,priority,enabled])
	except:
		pass
dataset = system.dataset.toDataSet(headers, data)
event.source.parent.parent.getComponent('Container').getComponent('Power Table').data = dataset

Hi Oisin.gribben,

The functionality has been depricated. However, you can use the system.tag.configuration to do the same thing. https://docs.inductiveautomation.com/display/DOC80/system.tag.getConfiguration

Thanks
Anthony

What way are we able to get the alarm setpoint, enabled etc. from this?
When using the function on the docs it returns the tag properties instead of the alarms.

Hi Oisin.gribben,

Wouldn’t be far easier to get the same properties from an Alarm Status table? It seems like the same properties status such as Active time, Display path, Current State, Priority , label can all be found there.

Thanks
Anthony

Hi,
I’m trying to get the alarm configurations from all tags whether or not they are or have been in alarm.

Hi,

It seems that the system.tag.configuration only gets tags in folders.
I am pointing the Tagpath to a udt instance with a hundred tags and 6 folders with tags inside.
There should be 4 tags with alarms configured in total in the folders and 10 outside the folders.
When I run this script i only get the ones in the folders.

    tags = system.tag.browseTags(parentPath=Tagpath, recursive=True)
	headers = ["Tag Name", "Alarm Name","Label","Active Pipeline","SetPointA","DisplayPath","Priority","enabled"]
	data = []
	for tag in tags:
		try:
			nodes = system.tag.getConfiguration(tag.fullPath, True)
		
			# Iterate over the results
			for item in nodes:
			
				# Through the results, search each dictionary
				for key, value in item.iteritems():
					#print tag.fullPath
					# ...looking for a 'tags' key
					if key == 'tags':
						# iterate over the tag configurations we found
						for tagConfig in value:
							# ...looking for a 'alarms' key
							#print tag.fullPath , tagConfig.keys()	
							if 'alarms' in tagConfig.keys():	
								#print 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
								#print tag.fullPath , tagConfig.keys()	
								for alarm in tagConfig['alarms']:
									
									try:
										if type(alarm["activePipeline"]) is dict:
											active =  alarm["activePipeline"].get("value")
										else:
											active = alarm["activePipeline"]
									except:
										active = ""
										
									try:
										if type(alarm["name"]) is dict:
											name =  alarm["name"].get("value")
										else:
											name = alarm["name"]
									except:
										name = ""
										
									try:
										if type(alarm["setpointA"]) is dict:
											setPoint =  alarm["setpointA"].get("value")
										else:
											setPoint = alarm["setpointA"]
									except:
										setPoint = ""
										
									try:
										if type(alarm["displayPath"]) is dict:
											displayPath =  alarm["displayPath"].get("value")
										else:
											displayPath = alarm["displayPath"].value
									except:
										displayPath = ""
										
									try:
										if type(alarm["priority"]) is dict:
											priority =  alarm["priority"].get("value")
										else:
											priority = alarm["priority"]
									except:
										priority = ""
										
									try:
										if type(alarm["enabled"]) is dict:
											enabled =  alarm["enabled"].get("value")
										else:
											enabled = alarm["enabled"]
									except:
										enabled = True
									
									try:
										if type(alarm["label"]) is dict:
											label =  alarm["label"].get("value")
										else:
											label = alarm["label"]
									except:
										label = ""
									row = [tag.fullPath,str(name),str(label),str(active),str(setPoint),str(displayPath),str(priority),str(enabled)]
									data.append(row)
										
		except:
			x= 1
	dataset = system.dataset.toDataSet(headers, data)

Hi Oisin.gribben,

Could you send me a gateway backup with a project that is displaying the issue?

Thanks,
Anthony

Hi @anjoroge,
I’m facing the same issue. Did we find why we can get alarms inside folders?

Thanks for your answer!

Hi,
What version of ignition are you on? The reason I ask is because we had a few version changes since then and the issue may be fixed in the latest version. you could try setting up a separate environment with the latest build and restoring the gwbk and see if the issue is still there.
https://inductiveautomation.com/downloads/ignition/8.0.16

Old post, but still relevant issue… the issue here is that getConfiguration returns only non-default property values of tags, nothing more. For example, if you leave the alarm Priority at the default of Low, then this configuration will not show if you run getConfiguration. Therefore you need to use getConfiguration to get the name of the alarm, then you can use readBlocking to read the properties of the alarms you need.

The only way that I can see being able to use getConfiguration to help with this, is if you:

  1. use system.tag.browse to find all of the tags
  2. call system.tag.getConfiguration in a loop to get the configuration of each tag individually. check if it has an alarm and if so, store the alarm name in a list
  3. create a list or lists of the tag paths to the alarm properties that you want to read by appending to the alarm tags list created in (2) e.g. alarmPriorityTagPaths = [tagPath + '/Alarms/' + alarmName + '.Priority' for tagPath, alarmName in zip(tags, alarmNames)]
  4. use system.tag.readBlocking to read the values of the alarm properties list(s)

For 350k tags, I estimated this to take a solid 9hrs… extremely inefficient, but I don’t know any other way to do this…
For 450 tags it took 42s to do parts 1-2 above

import time
times = []
times.append(time.time())

tags = shared.tag.browseTags(path='Winery/Cask Hall', recursive=True)
tags = [str(tag['fullPath']) for tag in tags if str(tag['tagType']) == 'AtomicTag']
times.append(time.time())

alarmTagPaths=[]
alarmNames=[]
for tag in tags:
	config = system.tag.getConfiguration(basePath=tag)
	if 'alarms' in config:
		alarmTagPaths.append(tag)
		alarmNames.append(config['alarms'][0].get('name', 'Alarm')) # not sure if this would ever not exist



times.append(time.time())
print times[-1]-times[0], 's for ', len(tags), ' tags'

print 'Times'
for i in range(1,len(times)):
	print '\t', i, times[i]-times[i-1], 's'
4 Likes

I've been down this path as well, definitely frustrating not being able to get the default properties. That said, I think getAlarmStates has the same behavior, at least per a note in the docs.

It would be great to get all properties, even defaults, particularly for functional testing. For instance, I've wanted to make a report that can quickly grab all alarm details, history details, etc and print them in one big PDF - that info is particularly desirable for pharma customers. Might end up doing it the way you mentioned, but as you noted it's...a bit unwieldy.

The only other way that I can think to do this that would hopefully be faster, but a lot more effort… (although I’ve actually started this already as I need it for other things)
is to:

  1. First create a script that collates a complete tag list with all configuration, including for UDT instances (note that exporting standard tags to json doesn’t include any information for tags inside of UDT instances except for name and tagType - we want to fix this).
    This requires:
    a) taking a json export of all UDT tag definitions and a json export of all standard tags
    b) creating a dictionary with {udtDefTagPath1: {<UDT DEF JSON>}, udtDefTagPath2: ....}
    c) recursively merge all nested UDT instances within each UDT definition json with the UDT instance’s definition’s json (need to do this recursively as otherwise any nested UDT instances within UDT definitions would not have all the configuration for their nested tags, and think, there could be many layers of UDT nesting…)
    d) finally, loop through the standard tags looking for udt instances, then merge the udt definition json from (c) to give you the full configuration.

  2. Once you have the complete tag configuration, you can then loop through the tags and compile a list of all tags with configured alarms. Note: you will still have missing configuration for default values.

  3. For each tags with alarms, collate a list of alarm names and corresponding tag paths. We need the alarm names to read the alarm properties as tags.

  4. Create a list of tagpaths to the alarm properties that you want to read, using (3) for the tagPath prefixes.
    E.g. to read the priority of an alarm, you would read:
    <tagPath>/Alarms/<AlarmName>.Priority

  5. Finally, use system.tag.readBlocking to read the list of alarm properties…

It really shouldn’t be this hard though, especially not to get a complete list of tag configuration

Update:
You can get the alarm default values using:

from com.inductiveautomation.ignition.common.alarming.config import CommonAlarmProperties, AlarmModeProperties
properties = {}
properties.update(dict((s.getName(), s.getDefaultValue()) for s in CommonAlarmProperties.values()))
properties.update(dict((s.getName(), s.getDefaultValue()) for s in AlarmModeProperties.values()))
3 Likes

where do you put the tag path?

You don't need to put in a tag path, all default properties will be in the properties dictionary.
So if you are interested in returning the default priority for a tag, you would use the code provided above, and access it with:

priority = properties['priority']

according to the scripting name in the manual here:
https://docs.inductiveautomation.com/display/DOC81/Tag+Alarm+Properties

1 Like