Rule catch time

Hi,

I have rule that monitor a switch, but it takes 8 seconds for the rule to catch that change

2019-05-10 23:38:49.510 [vent.ItemStateChangedEvent] - LS_Front changed from OFF to ON
2019-05-10 23:38:57.643 [INFO ] [se.smarthome.model.script.home.rules] - LS_Front Rule runs

Can I make this quicker ?
I have single rule fule with 510 lines in it

Just to be sure, does it take about 8s everytime, or just the first time after the rule is changed/loaded?
A large rule file takes some time to compile.

Everytime. Seems like other rules runs immediately.

If you monitored logs is switch slow to switch?

Nope. The moment I press I see it in the logs.
2019-05-11 01:05:26.685 [ome.event.ItemCommandEvent] - Item ‘LS_FrontOutside’ received command OFF

2019-05-11 01:05:26.702 [nt.ItemStatePredictedEvent] - LS_FrontOutside predicted to become OFF
2019-05-11 01:05:26.721 [vent.ItemStateChangedEvent] - LS_FrontOutside changed from ON to OFF
2019-05-11 01:05:26.790 [vent.ItemStateChangedEvent] - mqtt_topic_7489427a_frontlight changed from ON to OFF

I also have rules that monitor ZWAVE devices for double/triple press and the work instantly.

What’s the rule code?

rule “BI Motion FC”
when
Item BI_FC_Motion changed from OFF to ON
then
var boolean MovementLightsOn = false
logInfo(“home.rules”, “Motion rule runs”)
logInfo(“home.rules”, "MovementLightOn Before State: " + MovementLightsOn )
logInfo(“home.rules”, "Sun State: " + sun )
if (sun == false && LS_FrontOutside.state == OFF) {
MovementLightsOn = true
logInfo(“home.rules”, "MovementLightOn During State: " + MovementLightsOn )
LS_FrontOutside.sendCommand(ON)
logInfo(“home.rules”, “Lights on for Camera”)
}
createTimer(now.plusMillis(2500), [|
sendTelegramPhoto(“sec”, “http://192.168.192.104:81/”, “Front Cam movement”)
])
createTimer(now.plusMillis(3500), [|
sendTelegramPhoto(“sec”, “http://192.168.192.104:81/”, “”)
])
createTimer(now.plusMillis(4500), [|
sendTelegramPhoto(“sec”, “http://192.168.192.104:81/”, “”)
])
createTimer(now.plusMillis(6500), [|
sendTelegramPhoto(“sec”, “http://192.168.192.104:81/”, “”)
])
if (MovementLightsOn == true) {
createTimer(now.plusSeconds(300), [|
LS_FrontOutside.sendCommand(OFF)
])
MovementLightsOn = false
logInfo(“home.rules”, "MovementLightOn After State: " + MovementLightsOn )
}
end

Are you sure, this is the right rule? The snipe from log is not in the code.

Yes, I just renamed it :slight_smile:

I had some weird logs at messeges, so I decided to install on fresh SD card.
seems much better now.

This SD’s act very strange when they start malfunctioning

1 Like

Maybe consider to change the rule slightly:

var Timer tMotion = null
var Timer tMotionLight = null
var Number nMotion

rule "BI Motion FC"
when
    Item BI_FC_Motion changed from OFF to ON
then
    logInfo("home.rules", "Motion rule runs")
    if(tMotion === null) {
        tMotion=createTimer(now.plusMillis(2500), [|
            if(nMotion == 0) sendTelegramPhoto("sec", "http://192.168.192.104:81/", "Front Cam movement")
            else             sendTelegramPhoto("sec", "http://192.168.192.104:81/", "")
            nMotion+=1
            switch (nMotion) {
                case 1:  tMotion.reschedule(now.plusSeconds(1))
                case 2:  tMotion.reschedule(now.plusSeconds(1))
                case 3:  tMotion.reschedule(now.plusSeconds(2))
                default: tMotion=null
            }
        ])
        nMotion = 0
        if(tMotionLight === null && sun == false && LS_FrontOutside.state == OFF) {
            tMotionLight = createTimer(now.plusMinutes(5), [|
                LS_FrontOutside.sendCommand(OFF)
                tMotionLight = null
            ])
            LS_FrontOutside.sendCommand(ON)
            logInfo("home.rules", "Lights on for Camera")
        }
    }
end

Should be very similar, but more save in question of multiple triggers. The createTimers are out of execution order, as the if() statement should be locked immediately.

I’m not familiar with switch+case until now, but it seems like it only check nMotion once and therefore will send only 1 telegram photo. isn’t it ? I don’t see it behave like while loop

That’s what reschedule is for. The same timer code block will be run again in N seconds.

Should have said something more in question of code :slight_smile:

// global vars defined on top of rules file
var Timer tMotion = null                   //timer for delayed pictures
var Timer tMotionLight = null              //timer for light
var Number nMotion                         //counter for pictures

rule "BI Motion FC"
when
   Item BI_FC_Motion changed from OFF to ON
then
   logInfo("home.rules", "Motion rule runs")
   if(tMotion === null) {                                                                                //only if no timer is started yet
       tMotion=createTimer(now.plusMillis(2500), [|                                                      //execute code after 2.5 seconds
           if(nMotion == 0) sendTelegramPhoto("sec", "http://192.168.192.104:81/", "Front Cam movement") //on first step
           else             sendTelegramPhoto("sec", "http://192.168.192.104:81/", "")                   //every other step
           nMotion+=1                                                                                    //always add 1 to nMotion
           switch (nMotion) {
               case 1:  tMotion.reschedule(now.plusSeconds(1))                                           //first step
               case 2:  tMotion.reschedule(now.plusSeconds(1))                                           //second step
               case 3:  tMotion.reschedule(now.plusSeconds(2))                                           //third step
               default: tMotion=null                                                                     //fourth step: deinitialize timer
           }
       ])
       nMotion = 0                                                                                       //not delayed! set step to 0
       if(tMotionLight === null && sun == false && LS_FrontOutside.state == OFF) {                       //not delayed! test light
           tMotionLight = createTimer(now.plusMinutes(5), [|                                             //execute code after 5 minutes
               LS_FrontOutside.sendCommand(OFF)
               tMotionLight = null
           ])
           LS_FrontOutside.sendCommand(ON)                                                               //not delayed!
           logInfo("home.rules", "Lights on for Camera")
       }
   }
end

Timers are only created if they don’t exist yet. even if a rule is triggered twice, as the timer is created immediately, this part is “locked”.
Light is only switched on once, and also switched off once.
There will be 4 photos, after 2.5, 3.5, 4.5 and 6.5 seconds. First photo has a headline.

In my case it is only working if I use:

switch (nMotion.intValue) 

else is goes to default every time.

Jep, I think, this is something that changed between some versions of openHAB