[SOLVED] The last rule I need but can't at a time to run

Another point… You don’t need two rules, and the rule would be much easier if using a group item for the lights:

Group:Switch gLights
Switch GF_Hallway_Light      (gLights)
Switch GF_LivingRoom_Light   (gLights)
Switch GF_LivingDining_Light (gLights)
Switch GF_Dining_Light       (gLights)
Switch FF_Hallway_Light      (gLights)
rule "LightSwitchOFF"
when
    Item LivingRoomLightTimer changed
then
    if(now.getHourOfDay > 21 || now.getHourOfDay < 7) 
        gLights.sendCommand(LivingRoomLightTimer.state)
    else
        logInfo("lightswitch","LivingRoomLightTimer triggered out of time range.")
end

I feel like that all the time, don’t let it discourage you. OH rules are like skinning a cat, several ways to go about it.:grinning: Just keep reading and studying other post on the forum, as you learn more, you can apply it to make your rules more efficient. Example above is as short and simple as it gits.:+1:

1 Like

:smile:

@Udo_Hartmann

That looks like a very elegant piece of code but I can’t see where it tells the lights to either turn on or off.

Is it taking the LivingRoomLightTimer state and applying it to the lights? So if the LivingRoomLightTimer state is OFF the lights will turn off (within the given time frame)?

If that’s the case, my mind has just been blown.

Yep, that’s how it works. Just have to use the items in a group like mentioned above.

I copied the code and added some commits to help understand what’s happening. Hope it helps.

rule "LightSwitchOFF"
when
    Item LivingRoomLightTimer changed
then
    if(now.getHourOfDay > 21 || now.getHourOfDay < 7) // rule will run during this time only
        gLights.sendCommand(LivingRoomLightTimer.state) // all items in the group will receive the state of LivingRoomLightTimer e.g if OFF then off or if ON then on
    else
        logInfo("lightswitch","LivingRoomLightTimer triggered out of time range.") // Just some info to let you know whats happening. You can omit this if and the rule will continue to work.
end

EDIT: The rule may not work (haven’t checked just observing,:thinking:) as posted. Can you spot why? Hint it’s missing something small (four of them), after that it;s an open/closed case.:wink: If it does work as posted then I just learned something myself. Please give it a try and let us know.:grinning:

I think I’ve spotted the missing items…

Is this correct?

rule "LightSwitchOFF"
when
    Item LivingRoomLightTimer changed
then
    if(now.getHourOfDay > 21 || now.getHourOfDay < 7){ // rule will run during this time only
        gLights.sendCommand(LivingRoomLightTimer.state) // all items in the group will receive the state of LivingRoomLightTimer e.g if OFF then off or if ON then on
    }
	else
        {logInfo("lightswitch","LivingRoomLightTimer triggered out of time range.") // Just some info to let you know whats happening. You can omit this if and the rule will continue to work.
    }
		end

:worried:

Saying that, the rule must be working as I’m getting the message back say it’s out of time range.

Yep, I was referring to the { }, nice catch.:+1: Question is, will it work without them?

Also good to keep the { } organized like below. When using VSCode you will see a line (vertical dashes) to help keep the correct { } place. This really helps when your rules start to get long and complex.

rule "LightSwitchOFF"
when
    Item LivingRoomLightTimer changed
then
    if(now.getHourOfDay > 21 || now.getHourOfDay < 7){ 
        gLights.sendCommand(LivingRoomLightTimer.state)
   }
    else {
        logInfo("lightswitch","LivingRoomLightTimer triggered out of time range.")
   }
end

If you are thinking about {} curly brackets, these are not essential, as long as only one command is executed.

rule testrule // quotes are optional, as long as the rule name is only one word
when
    Item myItem changed  // every time, the state of myItem changed
then
    logInfo("test","test line 1")
    if(myItem.state == OFF)
        logInfo("test","test line 2")
    logInfo("test","test line 3")
    if(myItem.state == ON) {
        logInfo("test","test line 4")
        logInfo("test","test line 5")
    }
end

When the rule is triggered,

  • the first log line is executed.
  • the second log line is only executed if the status of myItem is OFF.
  • the third log line will be executed, because the if statement will only apply to the first following line.
  • the fourth and fifth log line will only be executed if myItem is of state ON

So {} is used to build a block of commands.

1 Like

Everyday, learning something new.:grin:

Thanks @Udo_Hartmann

Question, for beginners do you recommend using { } regardless of command amount, or is there ever a time that adding to a single command could prevent the rule from running, or cause some other issue?

As far as I know there is no situation where curly brackets are absolutely needed, other than switch case:

rule testrule
when
    Item myItem changed
then
    switch(myItem.state) {  // { not optional, always more than one option
        case ON:  logInfo("rule","myItem ON")
        case OFF: logInfo("rule","myItem OFF")
        default:  logInfo("rule","myItem neither ON nor OFF")
    }
end