Our target is to catch the IN Alarm followed by its corresponding OUT alarm for the same source
Result seen:
Alarm-IN1/Alarm-OUT1 matching correctly
Alarm-IN2/Alarm-OUT2 matching correctly
Alarm-IN1/Alarm-OUT2 also matching and this is not the behavior that we want, and that is why status = active is added as a condition because Alarm-OUT1 clears Alarm-IN1 so Alarm-IN1 is not active anymore but for some reason it is matching, maybe because it “was” active when the matching process started
on all Alarm(type=ALARM_IN_TYPE, status="ACTIVE") as a1 {
// check for Alarm of type OUT for the same 'source' that received the IN
on Alarm(source=a1.source, type=ALARM_OUT_TYPE, status="ACTIVE) as a2 {
// Application logic
}
}
In your current implementation, the inner listener remains active after processing Alarm-OUT1, causing unintended event matches like Alarm-IN1/Alarm-OUT2. This occurs because the inner listener remains open and continues to process alarms beyond the intended scope.
To refine the approach, ensure the inner listener automatically terminates once the OUT alarm is received:
on all Alarm(type="A1", status= "ACTIVE") as a1
{
on Alarm(type= "A2", status= "ACTIVE", source= a1.source) as a2
{
//your code
}
}
Alternatively, using a followed by listener pattern can help enforce sequential event processing while eliminating unintended matches:
on all Alarm(type="A1", status= "ACTIVE") as a1 -> Alarm(type= "A2", status= "ACTIVE") as a2
{
if a1.source = a2.source
{ // your code }
}
thanks I will test the first suggestion, concerning the 2nd suggestion (listener pattern (->)) I tested it and it seems to match only consecutive events received back-to-back which never happens for IN/OUT of the same source due to multiple concurrent sources
After testing it now I can confirm that the problem was solved! counting is 100% correct now thanks, I would like to understand what was causing the inner listener to remain open and why it was solved by moving the “source = a1.source” inside the inner on all instead of just after it in a dedicated if, I appreciate providing more details to learn from it
The main change is using “on” instead of “on all” in the inner listener statement. The matching condition “source = a1.source” is also beneficial as it eliminates the need for an extra conditional statement.
When the “on all” operator appears before an event template, when that event template finds a match, it continues to watch for subsequent events that also match the template.
In contrast, when “on” is used, the event template identifies a match, triggers the listener, and then terminates it.
Doc for more info with example:
I have tested having ‘on all’ as parent alarm and ‘on’ as child alarm first I though that it solved by problem and then I discovered that it is based on how the 2 alarms are received. In one case the IN#2 Alarm is received at the same time of OUT#1 alarm so practically it is processed before OUT#1 which seems to be creating an issue maybe cause IN#2 replaced IN#1 in the listener (not sure about it, just an assumption)
another issue is in our case, we need to search inside the 2 ON for an IF condition. So our logic is done only if the “If condition is met” so we need to keep searching for this condition and definitely we need the on all also in the nested child as well but whenever we catch this condition, we need to execute the logic and exit the on all listeners