isAlarmActive and isAlarmActiveFiltered not automatically updating color binding in Perspective

I am trying to implement a indicator that changes colors based on a tag’s alarm state; Green for no alarm, red for alarm+unack, and yellow for alarm+ackd. I used a label with a BackgroundColor Binding but it will not automatically update. My binding uses the expression:

if(isAlarmActive({view.params.Tag}),if(isAlarmActiveFiltered({view.params.Tag},'*','*',0,4,false,false,false),1,2),0)

where {view.params.Tag} is the tag path to be indicated. I then applied a color map transform for 0=Green, 1=red, and 2=yellow. However it is not working as I expected. In my test case, I have a single alarm when the tag itself is false, If I make the tag false, the indicator color does not change to red until I open the binding dialog and click OK (I do not have to do anything else, simply opening it and clicking OK makes the color update in the designer) and In order to get the actual perspective session to display the correct color, I then have to save the project and when the page auto refreshes, it will be correct. The same goes for once the alarm is acknowledged (it doesn’t change to yellow until the binding dialog is opened and OK’d etc)
I tried adding a polling rate to both isAlarmActive and isAlarmActiveFiltered but I get errors that the functions don’t work with 3 & 9 arguments respectively.
How do I get this binding expression to evaluate and update automatically?
Version is 8.1.0

Thanks

I think expressions only execute when a value within them changes. Since {view.params.tag} is not actually changing value, the expression will not update.

I would indirectly bind against the tag value, then I would use your expression in a transform with NO changes, and then I would include the Map transform again with no changes. In this way, the value will update whenever the tag value changes, and then evaluate whether or not the alarm is active.

When I tested this setup locally my label's background updated whenever the tag value updated.

Update:
I'm a bit more confident in my response after reading the docs

This part is the important part:

Typically, expressions are driven by events. If the expression was adding multiple values together, then when one of those values changed the expression would update, regardless of whether those values came from other properties or Tags.

In your original expression, the string value which represents your tag path is never changing, so the expression will not update, however, the expression will evaluate any time the expression is used/edited/viewed and so the binding dialog kicks of a new evaluation.

Expression bindings will always update immediately when the window they are in is opened.

This would include binding dialogs because the expression has to determine what value to display in the binding dialog.

1 Like

That seems to do the trick for the alarm transition but not on the Ack, but I think I can come up with something.

I’m still not entirely sure why I wasn’t able to use the optional poll rate parameter, I was thinking the expression should be running in the client scope, is that not the case?

Perspective expressions are running on the gateway. The pollRate parameter only applies to Vision clients.

1 Like

Ah, yes, you're right. I suspect this is now going to require some changes to your expression unless someone has a better way.

This is my solution, but it requires that you also supply the name of the alarm in use for the tag. This solution also make the original solution even easier because you are now binding against the alarm itself instead of the tag value and then an evaluation of the alarm states. You might need to safeguard against the potential of this view being passed a tag path which does not have an alarm configured.

  1. I would make a custom property on the View: isAcked.
  2. I would then bind this property directly to the isAcked property of the specified alarm via an indirect tag binding where you also supply the name of the alarm.
  3. I would make a custom property on the View: isActive.
  4. I would then bind the isActive custom property to the same property of the specified alarm.
  5. You should now bind the backgroundColor property of the Label to an Expression Structure; this will allow you to re-evaluate whenever any of multiple properties change. You'll want two entries in your expression structure - one for each of the custom properties on the view.
  6. Prior to 8.1.8, expression can become difficult to use after expression structures, so I recommend a script transform, followed by your Map transform.

Custom property which is bound to the actual properties of the alarm in use:

Label binding for backgroundColor:

I just made the topmost a direct binding, pointed it to the GatewayDateTime, and left the rest of the binding configuration the same. This causes the binding to be evaluated every second, and seems to be working.

Hi,
I’m trying to change the color of my pump and I try to use your syntax. I don’t understand it really well so maybe you can help. When my tag TP1_On_DIN is off, I want grey, if the same tag is on, I want white, but if the alarm on an other tag (TEST in this case) is true, I want the color red. So, this is what I tried:

You need to fix your expression transform. The if expression requires three arguments: condition, truth value, false value. You have only supplied one argument for the second if expression. Since the transform is failing to resolve, the map is receiving a value other than 0, 1, or 2, snd so it is outputting the fallback value - which happens to be black.

1 Like