# Alarm Status Table - Dynamic filtering

**URL:** <https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [February 27, 2023, 9:12pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391 "2023-02-27T21:12:48Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brodie\_Pascal](https://avatars.discourse-cdn.com/v4/letter/b/a698b9/32.png) [@Brodie\_Pascal](https://forum.inductiveautomation.com/u/Brodie_Pascal)\
**Post date:** [February 27, 2023, 9:12pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/1 "2023-02-27T21:12:48Z")

</div>

Fairly new to using Ignition Vision, but is there a way to dynamically link an alarm status table to reference only the alarms for a specific tag?

For example on an HMI I have a pressure sensor, and when I click the sensor it will open a popup that has data related to that sensor only (PV, alarm values, etc), and on that popup I want to have an alarm status table for only that sensors alarms.

---

<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:** [February 27, 2023, 9:17pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/2 "2023-02-27T21:17:03Z")

</div>

This post should help you figure it out:

> [@\[Solved\] Alarm Status Table/Alarm Journal: Source Filtering](https://forum.inductiveautomation.com/t/solved-alarm-status-table-alarm-journal-source-filtering/69924):
>
> At least twice now I've seen this topic come up where a source filter is being used, and it does not return the expected result. In all cases, an expression of some kind is being used that produces a name that will look like \*Flowmeter 1\*, but instead of filtering out all but Flowmeter 1, it also shows Flowmeter 10, Flowmeter 11, etc.. My recommendation has always been to modify the expression to include a colon after the flowmeter name, so the outcome is \*Flowmeter 1:\*, but it occurs to me tha…

---

<div class="post-metadata">

**Author:** ![Brodie\_Pascal](https://avatars.discourse-cdn.com/v4/letter/b/a698b9/32.png) [@Brodie\_Pascal](https://forum.inductiveautomation.com/u/Brodie_Pascal)\
**Post date:** [February 27, 2023, 9:27pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/3 "2023-02-27T21:27:49Z")

</div>

I appreciate the link, however I am looking to somehow, for lack of a better term "universally" link the table without having to type anything into the filters. I am looking to bind them to a tag of some sort.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [February 28, 2023, 8:07am UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/4 "2023-02-28T08:07:20Z")

</div>

You'll just need to bind the source filter (note don't use the display path since this is configurable and may not be the tag path) to an expression that manipulates the tag path by adding the prefix and suffix parts, and removes the tag provider if you supply that. Best to add the tag provider into the filter too.

e.g.  
if you're passing into the popup the tagpath to the device:  
`deviceTagPath = '[default]Area A/Sub B/Pump 1'`

Then you could generate the alarm source filter using a combination of the following custom properties added to the root container:  
`RootContainer.tagProvider` [expression binding]: `split(split({RootContainer.deviceTagPath}, ']')[0,0], '[')[1,0]`  
`RootContainer.tagPath` [expression binding]: `split({RootContainer.deviceTagPath}, ']')[1,0]`

Then the source filter would be:  
source filter = `'prov:/' + {RootContainer.tagProvider} + ':/tag:' + {RootContainer.tagPath} + ':*'`

\*\* Completely untested, so it might need some tweaks \*\*

---

<div class="post-metadata">

**Author:** ![bschroeder](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bschroeder/32/13260_2.png) [@bschroeder](https://forum.inductiveautomation.com/u/bschroeder)\
**Post date:** [February 28, 2023, 12:33pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/5 "2023-02-28T12:33:56Z")

</div>

We do something very similar with our popups... We have an alarm table (in a template) on the popup, and using the tagPath passed to the popup we create a source filter for that alarm table template.

---

<div class="post-metadata">

**Author:** ![Brodie\_Pascal](https://avatars.discourse-cdn.com/v4/letter/b/a698b9/32.png) [@Brodie\_Pascal](https://forum.inductiveautomation.com/u/Brodie_Pascal)\
**Post date:** [February 28, 2023, 4:21pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/6 "2023-02-28T16:21:57Z")

</div>

Do you have an example of what that looks like?

---

<div class="post-metadata">

**Author:** ![bschroeder](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bschroeder/32/13260_2.png) [@bschroeder](https://forum.inductiveautomation.com/u/bschroeder)\
**Post date:** [February 28, 2023, 4:32pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/7 "2023-02-28T16:32:55Z")

</div>

Sure.

Basically we have been working on making out popups as responsive to the client as possible so we do this from a timer on the popup rather than an expression. Any how...

On the popup there is a custom property named "AlarmSourceFilter" that the Alarm table SourceFilter property is bound.

The code that generates a comma separated list of sourceFilters is:

```auto
def __setupAlarmFilter(event,rootContainer,**kwargs):
	'''
	Setups the alarm filter for a device
	
	Args:
		event: The event that triggered this check. Usually from a timer
		rootContainer: The root container for the window
	
	Return:
		Nothing
	'''
	logger = kwargs.get('logger',system.util.getLogger(__baseLogger))
	try:
		tagList = [rootContainer.Tag]
		
		alarmSource = ESP.Standards.Common.Alarming.Util.createSourceFilter(tagList)
		
		def updateGUI():
			rootContainer.AlarmSourceFilter = alarmSource
			
		system.util.invokeLater(updateGUI)
		
	except Throwable, t:
		ESP.exceptions.handleException(ex=t,logger=logger)
	except Exception, e:
		ESP.exceptions.handleException(ex=e,logger=logger)

```

Where the Root Container has a property called "Tag" which is the base tag for the popup.

The function called to generate the sourceFilter depends on a list of tag Paths and it looks like this:

```auto
@funcLogging(__baseLogger)		
def createSourceFilter(tagList,**kwargs):
	"""Creates a comma seperated string of alarm source filter tags for the list of tags provided"""
	logger = kwargs.get('logger',system.util.getLogger(__baseLogger))
	alarmList = [__alarmTag(x) for x in tagList]
	if len(alarmList) == 1:
		return '{}/*'.format(alarmList[0])
	else:
		return '/*,'.join(alarmList)

def __alarmTag(tagPath,**kwargs):
	'''
	returns the alarm tag in the prov:PROVIDER:/tag:TAG format
	If no tag is provided only the provider then the TAG is empty
	
	Example:
	__alarmTag([Development]Motors/C100/MTR)
		returns prov:Development:/tag:Motors/C100/MTR
	__alarmTag([Development])
		returns prov:Development:/tag:
	'''	
	logger = kwargs.get('logger',system.util.getLogger(__baseLogger))
	retData = 'prov:{}:/tag:{}'
	provSearch = re.search(r"(?<=\[).+?(?=\])",str(tagPath))
	prov = 'default' if provSearch is None else provSearch.group() #If no provider was provided, make the default the provider
	tag = re.sub(r"\[[^()]*\]", "", str(tagPath))
	
	return retData.format(prov,tag)		

```

This works well... I'm sure there are places we can optimize but it fits our needs at the moment and is pretty responsive for our vision clients.

---

<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:** [February 28, 2023, 4:48pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/8 "2023-02-28T16:48:46Z")

</div>

Here's an alternative approach that scripts the conversation without a regular expression:

```auto
#tagPath = ... #custom prop value here
def getSourcePath(tagPath):
	sourcePath = tagPath.replace('[', 'prov:').replace(']', ':/tag:').replace('/Alarms/', ':/alm:', 1) + '*'
	return sourcePath
sourcePath = getSourcePath(tagPath)

```

---

<div class="post-metadata">

**Author:** ![Brodie\_Pascal](https://avatars.discourse-cdn.com/v4/letter/b/a698b9/32.png) [@Brodie\_Pascal](https://forum.inductiveautomation.com/u/Brodie_Pascal)\
**Post date:** [February 28, 2023, 6:38pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/9 "2023-02-28T18:38:24Z")

</div>

Where exactly are you putting this expression/script?

---

<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:** [February 28, 2023, 9:59pm UTC](https://forum.inductiveautomation.com/t/alarm-status-table-dynamic-filtering/70391/10 "2023-02-28T21:59:36Z")

</div>

> [@Brodie\_Pascal](#):
>
> Where exactly are you putting this

My apologies; I copied that conversion script from a post I made [here](https://forum.inductiveautomation.com/t/individial-alarm-acknowledge-button/70317/6) without putting it into context. Using a [parameterized popup window](https://docs.inductiveautomation.com/display/DOC81/Parameterized+Popup+Windows), I imagine that this would need to be adapted for the alarm status table's filterAlarm extension function. The script would look like this:

```auto
#def filterAlarm(self, alarmEvent):
	tagPath = self.parent.yourCustomProp #custom prop value here
	def getSourcePath(tagPath):
		sourcePath = tagPath.replace('[', 'prov:').replace(']', ':/tag:').replace('/Alarms/', ':/alm:', 1)
		return sourcePath
	if getSourcePath(tagPath) in str(alarmEvent.source):
		return True
	else:
		return False

```

...or perhaps even simpler:

```auto
#def filterAlarm(self, alarmEvent):
	tagPath = self.parent.yourCustomProperty #custom prop value here
	sourcePath = tagPath.replace('[', 'prov:').replace(']', ':/tag:').replace('/Alarms/', ':/alm:', 1)
	if sourcePath in str(alarmEvent.source):
		return True
	else:
		return False

```
