It's common to want Expression Rules to detect and do something when an alarm has been unacknowledged for some time, like an hour. One way to accomplish this is to have a timer that looks for unacknowledged alarms for every asset. This would be a bad solution because it's a huge number of queries to find a small number of offenders.
To solve this problem, we have the Reevaluate action in Expression Rules. It queues the event that it's currently processing and evaluates it later. But when it reevaluates, the status of any objects is updated. Let's see how to use it.
Rule 1:
Trigger: Alarm
IF: Alarm.age < 10 && Alarm.severity > 100
THEN: Reevaluate("1h")
Rule 2:
Trigger: Alarm
IF: Alarm.age > 60*60 && Alarm.state == "STARTED"
THEN: SetAlarmState("ESCALATED")
Reevaluate processes an event again later -- not a particular rule. So, if there are 7 alarm rules, then all 7 rules will process the alarm event later.
You need at least two rules: one when the alarm is received, and another when the alarm is reevaluated, just like the example above. By using Alarm.age, you can distinguish between new and old alarms. If you try to combine them into a single rule it may look like this:
RULE THAT WON'T WORK:
Trigger: Alarm
IF: Alarm.state == "STARTED" && Alarm.age > 60*60
THEN: SetAlarmState("ESCALATED")
ELSE: Reevaluate("1h")
The IF-THEN part works OK; an hour-old alarm still in the started state gets escalated. The problem is the ELSE part. An alarm in ACKNOWLEDGED or CLOSED state will go to the ELSE expression and be reevaluated.
The Reevaluate action uses a syntax where a string includes units, so 5m is 5 minutes, and 3h is 3 hours.
Reevaluate stores the message for a particular object. It will not reevaluate and process a different alarm, for example. Even if the alarm has the same name, a new alarm has a unique ID in the system.

