[SOLVED] So close but no cigar

Hello everyone.

I’m new to the forum and OpenHab.

I’l start by saying I’m not a coder. All these rules look extremely complicated to me.

That being said I’ve been reading up on the site and used samples of other people’s rules (a big thank you to @_Matt).

I have a rule that is almost perfect…but not good enough.

I am trying to write a rule that will start a ten minute timer at 21:50. If there is no motion within the ten minutes, the lights turn off. If there is motion, the timer resets for another ten minutes.

The rule I have will work but only if there is someone home. If I’m working late or on holiday, the rule won’t fire.

   //Define Variables
    var Timer LivingroomLightTimer = null

    //Livingroom Movement sensor

    rule "Livingroom Light Timer"
    when Item GF_LivingRoom_Motion changed from ON to OFF
    then
    if(now.getHourOfDay() >= 21.50 && now.getHourOfDay() < 6){
            if(LivingroomLightTimer!==null) {
                    LivingroomLightTimer.cancel()
            }
           }
            LivingroomLightTimer = createTimer(now.plusMinutes(10)) [| 
                    GF_LivingDining_Light.sendCommand(OFF)
            ]
    end

It’s the When statement I need to change but I’ve tried cron and I get a weird error ‘missing EOF at ‘When’’

I know I’m so close to cracking this but I just need a little help with the trigger.

I also tried to send an ‘ON’ command to the motion sensor at 21:50 to trigger the countdown, but I couldn’t get that to work either.

Can someone save me from going mad?

Many thanks
Ben

Ok,

Install the expire binding

Create another item called:

Switch LivingRoomLightTimer { expire="10m, command=OFF" }

and your rules:

//Livingroom Movement sensor
rule "Livingroom Light Timer"
when
    Time cron "0 50 21 ? * * *" or                   // at 21:50 or
    Item GF_LivingRoom_Motion changed from OFF to ON //Motion Detected
then
    LivingRoomLightTimer.sendCommand(ON) //Start timer or reset timer
end

rule "LivingRoomlightTimer Expire"
when
    Item LivingRoomLightTimer received command OFF
then
    if(now.getHourOfDay() >= 22 && now.getHourOfDay() < 6) {
         GF_LivingDining_Light.sendCommand(OFF)
    }
end

Yeah this is invalid. GetHourOfDay returns an Int (whole number) so as @vzorglub posted, change it to 21 or 22 and use the start of the hour or add:

if ( (now.getHourOfDay() >= 21 && now.getMinuteOfDate() == 30)  && now.getHourOfDay() < 6)

Note the extra brackets on the first section, which is basically saying treat these 2 parameters together…

But I think you’d be better to just use the cron statement to set the time and not bother with the time check.

@vzorglub and @psyciknz

Thank you so much for your replies.

I’ve created the rule and added the item but unfortunately I’m getting errors with the timer rule.

no viable alternative at input ‘LivingRoomLightTimer’

I’ve probably done something wrong. But have no idea where to start to fix it.

Thanks again for your time (and patience).
Ben

Ok,
publish your items and rules as they are, please

The rule is a direct copy from your post.


//Livingroom Movement sensor
rule "Livingroom Light Timer"
when
    Time cron "0 50 21 ? * * *" or                   // at 21:50 or
    Item GF_LivingRoom_Motion changed from OFF to ON //Motion Detected
then
    LivingRoomLightTimer.sendCommand(ON) //Start timer or reset timer
end

rule "LivingRoomlightTimer Expire"
when
    LivingRoomLightTimer received command OFF
then
    if(now.getHourOfDay() >= 22 && now.getHourOfDay() < 6) {
         GF_Hallway_Light.sendCommand(OFF)
                 GF_LivingRoom_Light.sendCommand(OFF)
                 GF_LivingDining_Light.sendCommand(OFF)
                 GF_Dining_Light.sendCommand(OFF)
                 FF_Hallway_Light.sendCommand(OFF)
    }
end

Here are my items


Group     Home                      "Hughes Towers"          <house>

Group     GF                        "Ground Floor"           <groundfloor>   (Home)
Group     FF                        "First Floor"            <firstfloor>    (Home)

Group     GF_Hallway                "Hallway"                <corridor>      (Home, GF)
Group     GF_LivingRoom             "Living Room"            <sofa>          (Home, GF)
Group     GF_Dining                 "Dining"                                 (Home, GF)
Group     GF_Toilet                 "Toilet"                 <toilet>        (Home, GF)
Group     GF_Kitchen                "Kitchen"                <kitchen>       (Home, GF)
Group     GF_LivingDining           "Living & Dining Room"   <sofa>          (Home, GF)
Group     FF_Bathroom               "Bathroom"               <bath>          (Home, FF)
Group     FF_Bedroom                "Bedroom"                <bedroom>       (Home, FF)
Group     FF_MasterBedroom          "Master Bedroom"         <bedroom_red>   (Home, FF)
Group     FF_Office                 "Office"                 <office>        (Home, FF)
Group     FF_Hallway                "Hallway"                <corridor>      (Home, FF)
Group     FF_Boiler                 "Boiler Room"            <gas>           (Home, FF)

Switch    GF_Hallway_Light          "Light"                  <light>         (GF_Hallway, gLight)    $
Switch    GF_Hallway_Motion         "Motion Sensor"          <motion>        (GF_Hallway, gMotion)   $
Switch    GF_LivingRoom_Light       "Light"                  <light>         (GF_LivingRoom, gLight) $
Switch    GF_LivingRoom_Motion      "Motion Sensor"          <motion>        (GF_LivingRoom, gMotion)$
Contact   GF_LivingRoom_Window      "Window"                 <window>        (GF_LivingRoom, gWindow)$
Contact   GF_LivingRoom_Door        "Door"                   <door>          (GF_LivingRoom, gDoor)  $
Switch    GF_LivingDining_Light     "Light"                  <light>         (GF_LivingDining, gLight$
Switch    GF_Dining_Light           "Light"                  <light>         (GF_Dining, gLight)     $
Contact   GF_Toilet_Window          "Window"                 <window>        (GF_Toilet, gWindow)    $
Contact   GF_Kitchen_Window         "Window"                 <window>        (GF_Kitchen, gWindow)   $
Contact   FF_Bathroom_Window        "Window"                 <window>        (FF_Bathroom, gWindow)  $
Number    FF_Bathroom_Battery       "Battery"                <heating>       (FF_Bathroom, gHeating) $
Contact   FF_Bedroom_Window         "Window"                 <window>        (FF_Bedroom, gWindow)   $
Contact   FF_MasterBedroom_Window   "Window"                 <window>        (FF_MasterBedroom, gWind$
Contact   FF_MasterBedroom_Door     "Door"                   <door>          (FF_MasterBedroom, gDoor$
Switch    FF_MasterBedroom_Power    "Power Outlet"           <poweroutlet>   (FF_MasterBedroom, gPowe$
Contact   FF_Office_Window          "Window"                 <window>        (FF_Office, gWindow)    $
Switch    FF_Hallway_Light          "Light"                  <light>         (FF_Hallway, gLight)    $
Switch    FF_Boiler_Power           "Power Outlet"           <poweroutlet>   (FF_Boiler, gPower)     $
Switch LivingRoomLightTimer { expire="10m, command=OFF" }

Group:Switch:OR(ON, OFF)         gLight     "Light"           <light>         (Home)
Group:Switch:OR(ON, OFF)         gPower     "Power Outlet"    <poweroutlet>   (Home)
Group:Switch:OR(ON, OFF)         gMotion    "Motion Sensor"   <motion>        (Home)
Group:Contact:OR(OPEN, CLOSED)   gWindow    "Window"          <window>        (Home)
Group:Contact:OR(OPEN, CLOSED)   gDoor      "Door"            <door>          (Home)
Group:Number:AVG                 gHeating   "Heating"         <heating>       (Home)

Thank you so much for your time. Sorry to be so stupid.

Ben

my fault

Second rule:

when
    Item LivingRoomLightTimer received command OFF
then

If you want to have rule which is triggered @ 21:50, use the Trime cron trigger:

rule "time trigger"
when
    //         s  m  h D M W [Y]
    Time cron "0 50 21 * * ?"
then
    logInfo("time","It's 10 Minutes to 10 O'clock p.m.")
end

As you can see, Time cron uses a similar format as GNU/Linux cron, but it supports Seconds.
You have to use exactly one question mark in the cron expression, either for day of month or for weekday.
So there is no chance to build a working cron expression, which will only trigger if the 1st day of a month is a Monday :wink: Year is optional and so it’s most often omitted.

Now, you are able to start a timer at 21:50, which will last 10 minutes.

But I guess that is not your goal :wink:

I’m pretty sure you want a rule to automatically switch off the lights only between 9:50 p.m. and 6:00 a.m.:

var Timer tLivingLightsOff = null

rule "auto lights off"
when
    Item GF_LivingRoom_Motion changed
then
    if(tLivingLightsOff !== null) {  // cancel Timer if existing
        tLivingLightsOff.cancel      // as motion was detected
        tLivingLightsOff = null
    }
    if(GF_LivingRoom_Motion.state == OFF) { // motion ended
        if(now.getMinuteOfDay > 21 * 60 + 50 || now.getMinuteOfDay < 6 * 60) {      // now.getMinuteOfDay is of Type Integer
            tLivingLightsOff = createTimer(now.plusMinutes(10), [
                // switch of lights
            ])
        }
    } 
end

So why it’s so differen’t?
Well, I’m pretty sure the light shouldn’t went out when motion was detected within the 10 Minutes, so the timer has to be cancelled if motion is detected.
If no motion was detected, it does not hurt to reinitialize the timer, if already set, as the rule uses the changed trigger.
Using .getMinuteOfDay makes it easy to use a fraction of the hour, as you can see.
As you want the period between 9:50 p.m. and 6:00 a.m., there is midnight between those borders. At midnight, getMinuteOfDay (as well as getHourOfDay) becomes 0.

The time either has to be higher than high level or lower than low level (not and, a number can’t be lower than 6 and higher than 21 at the same time :wink: at least as long as the number is rational)

Thank you for all the replies.

I think @vzorglub solved it.

Unfortunately I forgot to add the other switches to the rule and the test switch I was using wasn’t switched on!

I’ve just checked the log file and at 22:00 I saw this: Item ‘LivingRoomLightTimer’ received command OFF

So I think that was a success.

You’ve saved me from days/weeks of madness, I would never have figured that out on my own.

Ben

Please mark the thread as solved. Thanks

Hi everyone

I’ve been working away all week so not had a chance to try this code. Initially there was a problem with Wemo were it detected motion every minute. I’ve think that was a hardware issue as I’ve unplugged the sensor and moved it to my office. From then on it’s been fine.

One issue I’ve just found is once the lights have gone out, if I trip the sensor, the lights don’t come on again. This would be useful if I wake up at night for a drink.

I thought the fix would be easy so I added this to the code:

when
    Item LivingRoomLightTimer changed command ON
then
    if(now.getHourOfDay() >= 22 && now.getHourOfDay() < 6) {
                 GF_LivingDining_Light.sendCommand(ON)
                 GF_Dining_Light.sendCommand(ON)
    }
end

But I noticed I got this error in the log file:

Configuration model ‘LivingRoomlightTimer.rules’ has errors, therefore ignoring it: [25,39]: missing ‘then’ at ‘command’

The whole rule looks like this:

rule "Livingroom Light Timer"
when
    Time cron "0 50 21 ? * * *" or                   // at 21:50 or
    Item GF_LivingRoom_Motion changed from OFF to ON //Motion Detected
then
    Item LivingRoomLightTimer.sendCommand(ON) //Start timer or reset timer
end

rule "LivingRoomlightTimer Expire"
when
    Item LivingRoomLightTimer received command OFF
then
    if(now.getHourOfDay() >= 22 && now.getHourOfDay() < 6) {
         GF_Hallway_Light.sendCommand(OFF)
                 GF_LivingRoom_Light.sendCommand(OFF)
                 GF_LivingDining_Light.sendCommand(OFF)
                 GF_Dining_Light.sendCommand(OFF)
                 FF_Hallway_Light.sendCommand(OFF)
    }
end

rule "LivingRoomlightTimer Renew"
when
    Item LivingRoomLightTimer changed command ON
then
    if(now.getHourOfDay() >= 22 && now.getHourOfDay() < 6) {
                 GF_LivingDining_Light.sendCommand(ON)
                 GF_Dining_Light.sendCommand(ON)
    }
end

Thanks again for all your help

when
    Item LivingRoomLightTimer changed to ON
then

@vzorglub

Excellent, you’ve come to my rescue once again.

Many thanks
Ben