# Perspective - Creating dynamic icon based on alarm priority

**URL:** <https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980>\
**Category:** Ignition\
**Tags:** ignition81, perspective\
**Created:** [March 7, 2024, 4:28pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980 "2024-03-07T16:28:43Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![John\_Winship](https://avatars.discourse-cdn.com/v4/letter/j/87869e/32.png) [@John\_Winship](https://forum.inductiveautomation.com/u/John_Winship)\
**Post date:** [March 7, 2024, 4:28pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/1 "2024-03-07T16:28:43Z")

</div>

Hello!

I'm new to Ignition, and I'm working on my first project with it. I'm attempting to use Perspective to design an HMI for a simple project. As part of this HMI, I want each device/sensor on the HMI to display a special indicator in the event of an alarm. I'd like this indicator to dynamically change based on the priority of the associated alarm, as seen in _The High Performance HMI Handbook_:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/5/0/509f5bf407bf769a0793953c7b0ce6aa39f0b8e6.png)

I've created and uploaded the desired icons to my gateway, and I can use them in the designer without issue:

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/a/ba3b2af1d5dd7f6a7798ea9e3e388c86dc60177e.png)

I have this view which serves as a motor faceplate, with a parameter for motor name. I tried using an expression binding to dynamically change the path of the icon based on the highest priority alarm on the given motor. The following expression does not work:

**EDIT**  
This is the case statement format provided kindly by @ michael.flagler. Unfortunately, it still does not work, and returns a 'Bad\_NotFound' error.

```auto
case(true,
    isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*","*","*",4,4,0,1,0), "alarmIcons/Alarm-Priority-1",
    isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*","*","*",3,3,0,1,0), "alarmIcons/Alarm-Priority-2",
    isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*","*","*",2,2,0,1,0), "alarmIcons/Alarm-Priority-3",
    isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*","*","*",1,1,0,1,0), "alarmIcons/Alarm-Priority-4",
    0)

```

This expression structure seems to work in other expressions I've tried elsewhere, and I've confirmed that I can dynamically change the icon path with an expression binding through other methods. For example, this expression works properly if I manually assign the parameter.

```auto
if({view.params.highestAlarm}=4,'alarmIcons/Alarm-Priority-4','alarmIcons/Alarm-Priority-3')

```

I'm not quite sure why this isn't working, or if there is a better way to go about achieving the desired functionality. I've considered stacking all the icons in an embedded view and just setting visibility based on alarm priority, but to the best of my knowledge, my issue lies with how I'm trying to get the alarm priorities.

I'd appreciate it if anyone could give me some guidance on how to achieve this.

Thanks for your time!

---

<div class="post-metadata">

**Author:** ![leonardo.godoi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/leonardo.godoi/32/27178_2.png) [@leonardo.godoi](https://forum.inductiveautomation.com/u/leonardo.godoi)\
**Post date:** [March 7, 2024, 4:50pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/2 "2024-03-07T16:50:55Z")

</div>

Please edit your post and add your code using the 'Preformatted text' formating (CTRL+E).  
Have you tried instead of writting your tag path like this:

```auto
'[default]TestBench_Controller_Tags/Motors/{view.params.motorName}/*'

```

Writing it like this?

```auto
'[default]TestBench_Controller_Tags/Motors/'+ {view.params.motorName} + '/*'

```

---

<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:** [March 7, 2024, 7:34pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/3 "2024-03-07T19:34:21Z")

</div>

~~You are probably going to need an individual property using indirect binding for each tag, and then use those properties rather than a direct tag read.~~  
Yeah... don't do this. I was mistaken on this.

---

<div class="post-metadata">

**Author:** ![michael.flagler](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/michael.flagler/32/26272_2.png) [@michael.flagler](https://forum.inductiveautomation.com/u/michael.flagler)\
**Post date:** [March 7, 2024, 11:47pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/4 "2024-03-07T23:47:55Z")

</div>

As @leonardo.godoi mentioned, you won't be able to use the parameter directly inside quotes and it will need to be concatenated with the other strings, also, it will probably be cleaner using a case statement like this:

```auto
case(true,
    isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*","*","*",4,4,0,1,0), "alarmIcons/Alarm-Priority-1",
    isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*","*","*",3,3,0,1,0), "alarmIcons/Alarm-Priority-2",
    isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*","*","*",2,2,0,1,0), "alarmIcons/Alarm-Priority-3",
    isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*","*","*",1,1,0,1,0), "alarmIcons/Alarm-Priority-4",
    0)

```

---

<div class="post-metadata">

**Author:** ![John\_Winship](https://avatars.discourse-cdn.com/v4/letter/j/87869e/32.png) [@John\_Winship](https://forum.inductiveautomation.com/u/John_Winship)\
**Post date:** [March 8, 2024, 2:35pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/5 "2024-03-08T14:35:26Z")

</div>

Thanks for your response. I've edited my post as you described. Unfortunately, changing the string structure like this gives me the same error.

---

<div class="post-metadata">

**Author:** ![John\_Winship](https://avatars.discourse-cdn.com/v4/letter/j/87869e/32.png) [@John\_Winship](https://forum.inductiveautomation.com/u/John_Winship)\
**Post date:** [March 8, 2024, 2:49pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/6 "2024-03-08T14:49:25Z")

</div>

I'm not quite sure what you mean by this. Are you saying that on each tag for which I have an associated alarm, I need to configure a custom property which contains the highest alarm priority on that tag, then bind my expression to that property? I'd appreciate any clarification you can give on how to go about this. Thanks!

---

<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:** [March 8, 2024, 2:50pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/7 "2024-03-08T14:50:02Z")

</div>

I mis-read things. I'll edit my post out.

---

<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:** [March 8, 2024, 3:07pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/8 "2024-03-08T15:07:23Z")

</div>

> [@John\_Winship](#):
>
> `isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*","*","*",1,1,0,1,0)`

What happens if you just check for a true using isAlarmActiveFiltered? Do you get something back?

---

<div class="post-metadata">

**Author:** ![John\_Winship](https://avatars.discourse-cdn.com/v4/letter/j/87869e/32.png) [@John\_Winship](https://forum.inductiveautomation.com/u/John_Winship)\
**Post date:** [March 8, 2024, 4:03pm UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/9 "2024-03-08T16:03:32Z")

</div>

Testing this, it seems like the issue lies somewhere with the minimum and maximum priorities in this function call. Right now, I have a priority 1 alarm configured on the desired motor, which should be active. When setting the priority range from 0-4 in this function, the expression evaluates successfully.

```auto
if(isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*", "*", "*", 0,4,0,1,0), 'alarmIcons/Alarm-Priority-4', 'alarmIcons/blue-circle')

```

When I attempt to close the range, for example from 2-4, the expression returns the same 'Bad\_NotFound'

```auto
if(isAlarmActiveFiltered("[default]Testbench_Controller_Tags/Motors/" + {view.params.motorName} + "/*", "*", "*", 2,4,0,1,0), 'alarmIcons/Alarm-Priority-4', 'alarmIcons/blue-circle')

```

The expression also throws an error if the configured alarm is shelved. This behavior seems really strange, since it seems that an error is thrown any time there is no active tag that fits the criteria. I would expect it to simply return false, rather than throwing an error like this.

Have I made a configuration error somewhere, or is there more at play here?

---

<div class="post-metadata">

**Author:** ![Roman\_Rozenshteyn](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@Roman\_Rozenshteyn](https://forum.inductiveautomation.com/u/Roman_Rozenshteyn)\
**Post date:** [March 31, 2024, 2:55am UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/10 "2024-03-31T02:55:48Z")

</div>

I was looking for something similar, in order to implement an alarm indicator/border for my faceplates. Here's what I came up with:

```auto
def transform(self, value, quality, timestamp):
	tag = "*" + self.view.params.tagPath + "*"
	tag = tag.replace("[edge]","")
	alarms = system.alarm.queryStatus(source=[tag], state=[2,3])
	for i in alarms:
		priority = str(i["Priority"])
		if priority == "Critical":
			value = 4
			break
		elif priority == "High":
			value = 3
			break
		elif priority == "Medium":
			value = 2
			break
		elif priority == "Low":
			value = 1
			break
return value

```

I haven't tried to set this up with multiple faceplates on a single view but, I expect performance to take a hit. Although, I did add a 1 second clock to the expression binding for this script.

Does anyone have a take on doing it this way?

I also read that there is a method that would get the priority out of the AlarmEvent object, which would look something like the following but, it wasn't working out for some reason. Not sure what I'm doing wrong, the manual is a bit light on getting properties out of the parent object.

```auto
alarms = system.alarm.queryStatus(source=[tag], state=[2,3])
priorities = alarms.getPriority()

```

---

<div class="post-metadata">

**Author:** ![Hugh](https://avatars.discourse-cdn.com/v4/letter/h/c5a1d2/32.png) [@Hugh](https://forum.inductiveautomation.com/u/Hugh)\
**Post date:** [May 23, 2024, 8:00am UTC](https://forum.inductiveautomation.com/t/perspective-creating-dynamic-icon-based-on-alarm-priority/86980/11 "2024-05-23T08:00:21Z")

</div>

What is the update rate of isAlarmActiveFiltered in an expression (Perspective)?  
Trying to use this to show alarm borders on devices but getting inconsistent results.

A little bit disappointed in the alarm attributes. It would be really good if tag attributes like "ActiveUnackCount" could be used at a UDT / device level.  
Ie sum all the Active Unack for all the tags within that UDT.
