[SOLVED] Identify wich items fired the rule

Hi,
I have this rule:

rule "Xiaomi Battery Notification"
when
    Item BAGNO_MG_LOWBATT changed from OFF to ON or
    Item SALA_MG_LOWBATT changed from OFF to ON or
    Item SALOTTO_DX_MG_LOWBATT changed from OFF to ON or
    Item SALOTTO_SX_MG_LOWBATT changed from OFF to ON
then
    //Checke wich Item fired this rule

    //Do something Else

end

This rule is fired every time a sensor send Low Battery. Is there a way in the rule to check wich Item fired the rule and have its name into a string? So I can send a specific notification for each sensor without write one rule for each sensor.

Many Thanks

You can try assigning these items to a group, then use this as a guideline!
For the item name, in the rule, after you get the item that triggered the group update, you can use

myItem.name.toString

Be aware that you might have to use persistence for this!

Best regards,
Geroge

Thanks,
I’ll read the Article and I will try.

Marco

look and try also

Determining the triggering item in the body of a rule

Thanks a lot.
In this 2 article there are the answers I need.

Marco

Hey, great! It would be amazing if you could post your findings for others. The next one looking for an answer on how to “Identify which item fired a rule” will be thankful to you.

Actually, @rlkoshak already explains that in the article, maybe a tag with

would be better, in order not to duplicate the solutions! WDYT?

The best way without duplicates would be to mark


as the solution and maybe explain which part of the linked post solved the problem, if it was not the complete post.

I might suggest that there could be a different approach that would require a slightly more complex rule but would not require the persistence hack to get the triggering Item. Rather than sending a separate alert for each battery why not consolidate the alerts. If anyone of them goes off send an alert with all the batteries that are off.

Put your Items into a Group. Then:

val lastAlert = ""

rule "Xiaomi Battery Notification"
when
    Item XiaomiBatteries received update
then
    // If all the Switches are OFF we have nothing to do
    if(XiaomiBatteries.state == OFF) return false;

    val StringBuilder alert = new StringBuilder

    // Build an alert message listing all the Items that are ON
    alert.append("The following devices have a low battery: ")
    XiaomiBatteries.members.filter[bat | bat.state == ON].forEach[ bat |
        // use a MAP transform to convert the Item name into a nice name for messages
        alert.append(transform("MAP", "xiaomi.map", bat.name) + ", ")
     ]
    alert.setLength(sb.length() - 2) // strip off the trailing ", "
    alert.append(".")

    // Only send this alert if it is different from the last alert sent
    if(alert.toString != lastAlert){
        lastAlert = alert.toString
        // send the alert
    }
end

Where ever possible, I try to avoid using the persistence hack to identify which Item triggered a rule because while it works fairly well, it is brittle and dependent on timing differences.

3 Likes

Hi @rlkoshak
as usual thanks for your precious help.
I started from your example, but I prefer to use “changed from OFF to ON”, this because my item receive an update every couple of minutes, using “changed from OFF to ON” rule is fired only when a sensor send alarm.

I have an issue with this line of your code:
alert.setLength(sb.length() - 2) // strip off the trailing ", "

rule execution stop at this line, tell me that sb is not valid

Thanks

Marco

Hi,
I fixed the issue with sb.lengt, but I have issue with trigger.
Using

when
Item gpXiaomiLowBatt received update

rule is not fired. gpXiaomiLowBatt is a item group with all items.

Marco

Everyone gets caught by stupid copy and paste errors every now and again. It looks like you figured it out but for everyone else, it should be alert.setLength(alert.length() - 1).

Did you define it as a Group:Switch? If you do not provide a type to the Group it will never be updated and therefore never trigger the rule.

Hi @rlkoshak,
i defined a normal group Group gpXiaomiLowBatt
I suppose I have to define something like this: Group gpXiaomiLowBatt

Group:Switch:OR(ON, OFF) gpXiaomiLowBatt

Marco

Yes, that is exactly right.

There is now the automatic variable “triggeringItem”, which contains exactly that information.

1 Like