Nice graphic alarm (Pir sensors) visualization in HABPanel

Thanks for posting this great tutorial. I’m on my phone right now so it’s hard to do a full review of the rule but I do notice some things with a quick scan:

  • done cancel a Timer from inside the Timer body. If the body is running then it is already cancelled. The line end up doing nothing.

  • similarly, it makes no sense I have an if statement inside the body of the timer to test if the timer is cancelled or null immediately after cancelling and setting the timer to null. You don’t need the if because you already know it’s cancelled and null.

  • have a look at the cascading timers design pattern for a more flexible way to do this, though in this case I think I would implement it with Expire Based Timers.

If you combined the Expire Based Timers DP and Associated Items DP and take advantage of the new triggeringItem implicit variable you can not only reduce this down to one Rule for all PIRS but reduce the lines of coffee and complexity of that rule by more than half.

Note I’m just typing this in from memory on my phone. It will be riddled with errors. It is meant as a guide, not workable code.

Group gPirTimers
String Pir01 "PIR1 [%s]" <dmotion> (gPirs, gPirsOutside)
Switch Pir01_Timer (gPirTimers)
 {expire="5s,command=OFF"}
String Pir02 "PIR2 [%s]" <dmotion> (gPirs, gPirsOutside)
Switch Pir02_Timer  (gPirTimers) {expire="5s,command=OFF"}
rule "Pir on"
when
    Item Pir01_raw received update 1 or
    Item Pir02_raw received update 1
then
    val pir = gPirs.members.findFirst[p| p.name == triggering item.name.split("_").get(1)]
    val timer = gPirTimers.members.findFirst[t| t.name = pir.name+"_Timer"]
    pir.postUpdate("red")
    timer.sendCommand(ON)
end

rule "PIR Timer"
when
    Item Pir01_Timer received command OFF or
    Item Pir02_Timer received command OFF
then
    val pir = gPirs.members.findFirst[p| p.name == triggering item.name.split("_").get(0)]

    var color = "off"
    switch(pir.state.toString){
        case "red": color = "orange"
        case "orange": color = "orangelight"
        case "orangelight": color = "yellow"
        case "yellow" : color = "off"
    }

    pir.postUpdate(color)
    if(color != "off") triggeringItem.sendCommand(ON)
end

For now you have to add each new PIR as a trigger to the first rule and each timer as a trigger to the second. Soon we will be able to trigger of if a group I hope.

1 Like