Help, rules not working as expected

I’ve created this rule below, however it’s not working as I’d expect.

What happens is the bed side light switches on every time the motion sensor is activated, where as I was only expecting the bed side light to switch on if the living room floor light is switched off and the landing ceiling light was switched on.

What have I done wrong with the logic?

rule "Going To Bed"
when
Item Landing_First_Floor_Motion changed from CLOSED to OPEN
then
if(Ceiling_Light.state != ON && Floor_Light_Living_Room.state != OFF){
Bed_Side_Light.sendCommand(20)
}
end

That means Not-equals ; your rule seems to be the opposite of your description?

Made this change, but still not getting the expected result.

if(Floor_Light_Living_Room.state == OFF && Ceiling_Light.state == ON) {
    Bed_Side_Light.sendCommand(20)
}

Don’t make it complicated. Just make your conditional be what you would say in words.

If (if) the living room floor light is switched off (Floor_Light_Living_Room.state == OFF) and (&&) the landing ceiling light is switched ON (Ceiling_Light.state == ON) then turn on the bed side light (Bed_Side_Light.sendCommand(20)).

Thanks for your help, but sadly that doesn’t work either. The bed side light doesn’t switch on no matter what combination the other lights are. If I remove the IF statement then the bed side light switches on, but that’s only halfway to what I’m looking for.

You do realize that the two lights must be in the OFF and ON state before the motion sensor triggers the right, right?

It won’t work to have the motion sensor trigger and then turn off the living room lamp.

this may be a long shot - but if you use

Floor_Light_Living_Room.state == OFF && Ceiling_Light.state == ON

and as you say, nothing happens no matter if the other lights are actually on, off or in the right combination - would it be possible that the states are reported differently? Like

Floor_Light_Living_Room.state == 0 && Ceiling_Light.state == 1

what ends up in your events.log if you switch Floor_Light_Living_Room and Ceiling_Light ?

The idea is that if the Living room floor light is switched OFF and the Landing Ceiling light is switched ON then if motion is detected the Bed side light should switch on at 20% brightness.

Just checked the events.log and the states for each of the lights is either ON or OFF.

Ok, it was a long shot :slight_smile:

maybe you could add some logging befor the if statement, like:

rule "Going To Bed"
when
	Item Landing_First_Floor_Motion changed from CLOSED to OPEN
then
     logInfo("my.rules", "lamp states "+Ceiling_Light.state.toString+Floor_Light_Living_Room.state.toString)

this way you can check if the states are really what they ought to be at time of rule execution

Rules are triggered by events. An if statement checks state. What you are looking for is to detect three events, not detect one event and check the state of two Items.

So, as I said, rules are triggered by events so all three of these events AND you care about the order and timing of these events. This is not going to be easy.

If you don’t care about the order of the events or the timing of the events, you can just trigger the rule on all three events and leave the body the same:

rule "Going To Bed"
when
    Item Landing_First_Floor_Motion changed from CLOSED to OPEN or
    Item Ceiling_Light changed from OFF to ON or
    Item Floor_Light_Living_Room changed from ON to OFF
then
    if(Ceiling_Light.state != ON && Floor_Light_Living_Room.state != OFF){
        Bed_Side_Light.sendCommand(20)
    }
end

You might add a time check in there so this rule only executes at night or during a time that you are likely to be going to bed.

Clearly the order of the events does not matter as far as this rule is concerned. Whenever any one of those three events occur, if the lights are in the indicated states the bedroom lamp will turn on. This may be adequate, it may not. It depends on your use case.

If you really want them to occur in order there are several approaches you can take but all of them involve keeping up with when the events occurred and checking to see if they occurred in order.

Perhaps the easiest is if you set up persistence on the light switches. Then you can test the lastUpdate time.

rule "Going To Bed"
when
    Item Landing_First_Floor_Motion changed from CLOSED to OPEN
then
    if(Floor_Light_Living_Room.state == OFF && Ceiling_Light.state == ON){
        val livingTime = Floor_Light_Living_Room.lastUpdate
        val ceilingTime = Ceiling_Light.lastUpdate
        if(livingTime.isBefore(ceilingTime) && livingTime.isAfter(now.minusMinutes(5).millis) ) {
            Bed_Side_Light.sendCommand(20)
        }
    }
end

In the above, when the motion sensor goes off, if living room lamp is OFF, and the ceiling light is ON, and the lamp was turned off no more than five minutes ago and the ceiling light was turned ON even closer to now (i.e. ceiling light was turned ON after the living room light was turned ON) then turn on the Bed_Side_Light.

Without Persistence you can keep track of the times these events occur manually:

var livingTime = null
var ceiling = null

rule "Living room lamp turned off"
when 
    Item Floor_Light_Living_Room changed from ON to OFF
then
    livingTime = now
end

rule "Celing light turned on"
when
    Item Ceiling_Light changed from OFF to ON
then
    ceiling = now
end

rule "Going To Bed"
when
    Item Landing_First_Floor_Motion changed from CLOSED to OPEN
then
    if(living.isBefore(ceiling) && living.isBefore(now.minusMinutes(5)) {
        Bed_Side_Light.sendCommand(20)
    }
end

The problem isn’t that the states are wrong, it is that @Maximo is misunderstanding how the if statement works.

But assuming (ok, the right order of actions is a must) light in living room is switched OFF, ceiling light is switched ON and after that motion sensor is triggered, why should the simple rule not work? Or am I missing a basic point?

That is a good point. Upon looking at it the simple rule should have triggered the bedroom lamp when the motion sensor went off because the other lights should have been in the correct state.

Just tried that new rule setup and it’s still not working. :frowning:

So there is something not right still. Really appreciate the help though guys.

You had the light switching when you were looking for not-equals in first post.
I would still guess that the state(s) are not taking the values you expect. Maybe something is undefined (as yet). Use that logInfo suggestion to be sure.

Result, finally got it sorted. Here’s the rule below. Thanks to those of you that have helped me with this.

rule "Going To Bed"
when
Item Landing_First_Floor_Motion changed from CLOSED to OPEN
then
logInfo(“Going To Bed”, "Motion Detected, the Floor Light is “+Floor_Light_Living_Room.state+” the Ceiling Light is "+Ceiling_Light.state.toString)
if(Floor_Light_Living_Room.state == 0 && Ceiling_Light.state == 100) {
Bed_Side_Light.sendCommand(20)
}
end

Aha, the “switches” are really dimmers. That explains it. Glad you got it working.