I am trying to flash an object when an alarm is active and unacknowledged. I have the expression function isAlarmActive, and I have the scripting function system.alarm.queryStatus… is there an expression to find the unack status, or do I need to use a script?
For future me and/or others trying to do the same thing, here’s how I did it with scripting. I’d still like to know if there is a way to do this with plain expressions, as that would be a much neater, cleaner, and easier to understand solution.
In a project script library, define a package called alarmUtil and add the following code:
#This script will drive a high-performance style alarm indicator to be
# visible when the alarm is active, and blink any time the alarm is
# unacknowledged.
#The script is intended to be used by a timer object on the screen that
# contains the indicator you wish to drive. Initial value should be 0,
# bound 2, delay whatever you want your blink rate to be.
#alarmPath is the path to the alarm you wish to use, i.e.
# '*Tag Folder/Tag Name/Alarm*Name*'
#timerVal is the integer value of the timer this is intended
# to be run by, i.e. event.source.value
#indicator is the path to the indicator graphic you want to drive, i.e.
# event.source.parent.getComponent('Indicator Name Here')
def driveIndicator(alarmPath, timerVal, indicator):
#Query the alarm status
queryResult = system.alarm.queryStatus(path=[alarmPath])
#Initialize some variables for the different states
unacked = False
active = False
#Check if the alarm is in those states
for alarm in queryResult:
if "Unacknowledged" in alarm.toString():
unacked = True
#Have to include the opening ' and the , to avoid matching other
#parts of the toString status that are always present
if "'Active, " in alarm.toString():
active = True
#Set visible if appropriate
if active or unacked:
indicator.visible = True
#If also supposed to blink, set invisible when the timer is a 1
if (unacked and timerVal == 1) or (unacked == False and active == False):
indicator.visible = False
On a timer object (step by 1, bound 2, initial delay 0, delay however long you want your flash period to be) on the screen that contains the alarm indicator you wish to drive, define the following actionPerformed script:
#Set up variables required for calling the alarm driver project script
#First, drive the high level indicator
alarmPath = "*"+event.source.parent.TankTag.Meta.TagPath+"/Level*High*"
timerVal = event.source.value
indicator = event.source.parent.getComponent('Level High Indicator')
project.alarmUtil.driveIndicator(alarmPath, timerVal, indicator)
#Next, the high temperature indicator
alarmPath = "*"+event.source.parent.TankTag.Meta.TagPath+"/Temperature*High*"
indicator = event.source.parent.getComponent('Temperature High Indicator')
project.alarmUtil.driveIndicator(alarmPath, timerVal, indicator)
#Next, the low level indicator
alarmPath = "*"+event.source.parent.TankTag.Meta.TagPath+"/Level*Low*"
indicator = event.source.parent.getComponent('Level Low Indicator')
project.alarmUtil.driveIndicator(alarmPath, timerVal, indicator)
This particular example drives 3 indicators, for high and low level and high temperature.
Hi Jesse,
If I understand it correctly, you’re trying to do the following:
- If a point goes into alarm and is unacknowledged, flash the visibility of an object.
- If the point is still in alarm but is acknowledged, display the object without flashing.
- If the point is acknowledged and goes out of alarm, hide the object.
You should be able to do this using the following expression on the object’s visibility:
if({Tag_1.AlarmActiveAckCount},1,
if({Tag_1.AlarmActiveUnackCount},{Root Container.Timer.value},
if({Tag_1.AlarmClearUnackCount},{Root Container.Timer.value},0)
)
)
This code assumes you have a free running timer setup as you described. It also copes with a point going into and then out of alarm without being acknowledged.
Let me know if this helps.
You could also use the binEnc() function to create a state value:
binEnc({Tag_1.AlarmActiveAckCount}, {Tag_1.AlarmActiveUnackCount})
You can encode as many different tests as you need. In this example:
0=No Active Alarm
1= Any Active Alarm
2= Unacked Active Alarm
After that you can use styles to manipulate the colors and animations of your display. For a blink effect, you can set the alphas of one one of the animation to 0 to make it transparent.
Usually, though, I’ll use two different colors (like a red and yellow) to use as a flash.