I’m trying to have alarm priority by equipment on the window, since call system.alarm.queryStatus from the client make the client block, I’m thinking that each UDT can have a tag to show alarm priority using alarm events to do it.
It’s a good approach? Anyone can think in possible problems?
I have changed the aproach to use the expression function isAlarmActiveFiltered running on a memory tag inside the UDT. Will try to run some tests to identify possible performance issues, for each equipment I running this function eight times, 4 for each priority not allowing acknowledge (ignoring diagnostics) and 4 more for each priority allowing acknowledge alarms.
If performance became a issue I able to reverse the if’s for a situation without alarms use less server resources.
if(
isAlarmActiveFiltered({PathToParentFolder}+"*", "*", "*", 4, 4, 0, 0, 0),8,
if(
isAlarmActiveFiltered({PathToParentFolder}+"*", "*", "*", 4, 4, 0, 1, 0),4,
if(
isAlarmActiveFiltered({PathToParentFolder}+"*", "*", "*", 3, 3, 0, 0, 0),7,
if(
isAlarmActiveFiltered({PathToParentFolder}+"*", "*", "*", 3, 3, 0, 1, 0),3,
if(
isAlarmActiveFiltered({PathToParentFolder}+"*", "*", "*", 2, 2, 0, 0, 0),6,
if(
isAlarmActiveFiltered({PathToParentFolder}+"*", "*", "*", 2, 2, 0, 1, 0),2,
if(
isAlarmActiveFiltered({PathToParentFolder}+"*", "*", "*", 1, 1, 0, 0, 0),5,
if(
isAlarmActiveFiltered({PathToParentFolder}+"*", "*", "*", 1, 1, 0, 1, 0),1,0))))))))
Use it but on a Asyn Thread
Hey,
I was trying to do something similar… return the highest active alarm priority for a UDT/folder… I found that it broke everything (crashes/freezes the vision client) in 8.1.17
if(len({Object NotifyNav.Tag_Path})>0, // check if a tag path is even specified
if(
isAlarmActiveFiltered(
{Object NotifyNav.Tag_Path}+'*', // check for any alarm that starts with our tag path (e.g. children)
'*', // don't worry about alarm names
'*', // don't check the display path
4, // min priority 4
4, // max priority 4
0, // don't consider cleared alarms
1, // doesn't matter if the alarm was acknowledged...
0, //but don't consider shelved alarms
{Object NotifyNav.Alarm_UpdateRate} // the rate at which we want to refresh the alarm data (ms)
), 4, // return prioriy 4 if we get a result
if(
isAlarmActiveFiltered(
{Object NotifyNav.Tag_Path}+'*', // check for any alarm that starts with our tag path (e.g. children)
'*', // don't worry about alarm names
'*', // don't check the display path
3, // min priority 3
3, // max priority 3
0, // don't consider cleared alarms
1, // doesn't matter if the alarm was acknowledged...
0, //but don't consider shelved alarms
{Object NotifyNav.Alarm_UpdateRate} // the rate at which we want to refresh the alarm data (ms)
), 3, // return prioriy 3 if we get a result
if(
isAlarmActiveFiltered(
{Object NotifyNav.Tag_Path}+'*', // check for any alarm that starts with our tag path (e.g. children)
'*', // don't worry about alarm names
'*', // don't check the display path
2, // min priority 2
2, // max priority 2
0, // don't consider cleared alarms
1, // doesn't matter if the alarm was acknowledged...
0, //but don't consider shelved alarms
{Object NotifyNav.Alarm_UpdateRate} // the rate at which we want to refresh the alarm data (ms)
), 2, // return prioriy 2 if we get a result
if(
isAlarmActiveFiltered(
{Object NotifyNav.Tag_Path}+'*', // check for any alarm that starts with our tag path (e.g. children)
'*', // don't worry about alarm names
'*', // don't check the display path
1, // min priority 1
1, // max priority 1
0, // don't consider cleared alarms
1, // doesn't matter if the alarm was acknowledged...
0, //but don't consider shelved alarms
{Object NotifyNav.Alarm_UpdateRate} // the rate at which we want to refresh the alarm data (ms)
), 1, // return prioriy 1 if we get a result
if(
isAlarmActiveFiltered(
{Object NotifyNav.Tag_Path}+'*', // check for any alarm that starts with our tag path (e.g. children)
'*', // don't worry about alarm names
'*', // don't check the display path
0, // min priority 0
0, // max priority 0
0, // don't consider cleared alarms
1, // doesn't matter if the alarm was acknowledged...
0, //but don't consider shelved alarms
{Object NotifyNav.Alarm_UpdateRate} // the rate at which we want to refresh the alarm data (ms)
), 0, // return prioriy 0 if we get a result
-1 // if no matches, then no alarms exist!
)
)
)
)
),
-2 // return value if no TagPath is provided
)
All works good inside of my template when I directly specify the tag path, but as soon as I bind it to a parent template using “{UDT}::Meta.TagPath”, it throws this error when placed on a vision window, locks everything up, and I need to kill the designer/client task (not good!):
java.lang.Exception: Error executing expression binding on
Object NotifyNav.Object NotifyNav.Alarm_Priority
at com.inductiveautomation.factorypmi.application.binding.ExpressionPropertyAdapter.runExpression(ExpressionPropertyAdapter.java:92)
at com.inductiveautomation.factorypmi.application.binding.ExpressionPropertyAdapter$1.run(ExpressionPropertyAdapter.java:59)
at com.inductiveautomation.ignition.client.util.EDTUtil$ProcessQueue.run(EDTUtil.java:128)
at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Caused by: com.inductiveautomation.ignition.common.expressions.ExpressionException: Error retrieving alarm state from gateway.
at com.inductiveautomation.ignition.client.expressions.ClientFunctionFactory$IsAlarmActiveFilteredFunctionClient.execute(ClientFunctionFactory.java:217)
at com.inductiveautomation.ignition.client.expressions.ClientDynamicDispatchFunction.execute(ClientDynamicDispatchFunction.java:43)
at com.inductiveautomation.ignition.common.expressions.FunctionExpression.execute(FunctionExpression.java:69)
at com.inductiveautomation.ignition.common.expressions.DefaultFunctionFactory$IfFunction.execute(DefaultFunctionFactory.java:2061)
at com.inductiveautomation.ignition.common.expressions.FunctionExpression.execute(FunctionExpression.java:69)
at com.inductiveautomation.ignition.common.expressions.DefaultFunctionFactory$IfFunction.execute(DefaultFunctionFactory.java:2078)
at com.inductiveautomation.ignition.common.expressions.FunctionExpression.execute(FunctionExpression.java:69)
at com.inductiveautomation.factorypmi.application.binding.ExpressionPropertyAdapter.runExpression(ExpressionPropertyAdapter.java:83)
... 15 more
Caused by: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: Read timed out
at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.newGatewayException(GatewayInterface.java:351)
at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.getResponse(GatewayInterface.java:543)
at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:283)
at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:278)
at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.invoke(GatewayInterface.java:945)
at com.inductiveautomation.ignition.client.expressions.ClientFunctionFactory$IsAlarmActiveFilteredFunctionClient.execute(ClientFunctionFactory.java:213)
... 22 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
at java.base/java.net.SocketInputStream.socketRead(Unknown Source)
at java.base/java.net.SocketInputStream.read(Unknown Source)
at java.base/java.net.SocketInputStream.read(Unknown Source)
at java.base/java.io.BufferedInputStream.fill(Unknown Source)
at java.base/java.io.BufferedInputStream.read1(Unknown Source)
at java.base/java.io.BufferedInputStream.read(Unknown Source)
at java.base/sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
at java.base/sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.base/java.net.HttpURLConnection.getResponseCode(Unknown Source)
at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.getResponse(GatewayInterface.java:437)
... 26 more
Ignition v8.1.16 (b2022040511)
Java: Azul Systems, Inc. 11.0.14.1
In the error output, line that stuck out to me is:
Caused by: com.inductiveautomation.ignition.common.expressions.ExpressionException: Error retrieving alarm state from gateway.
So weird… is there something wrong with the “isAlarmActiveFiltered()” expression function itself, or with how the nested template receives the TagPath binding?
I’ll do some more basic testing… but really thought this would have worked.