Lighting sensor versus dimmer switch brain ache

Hi all,

Hope you are all fairing well during this time.

I’m after some brain power please.

I have hue lights in various rooms and all have the same problem, I’ll use the hallway as the example.

The lights are controlled by a sensor, when it detects movement it sets a virtual switch to on, with a timer to turn said switch off after 60 seconds. My rule at its very basic level runs to turn the light on when the switch is on and turns the light off when the switch changes to off.

This works just fine.

Each room also had a physical dimmer switch and sometimes we like to just use this to turn the light on to keep it on etc

However, the motion sensor always overrides it, ie if we press the physical switch and the light turns on as soon as the motion sensor senses movement it starts the timer and then 60 seconds later the light turns off.

So, I’m just after some advice on how to tackle this really. I want the switch to be the ‘master’ and then the sensor to be the slave, however I would like to have it that the master switch automatically turns off after some time assuming we have forgotten to switch it off.

What have others done, what logic have you all used…I’m after some inspiration please…

so … ?

If you get a motion alert but the state of the light is already on - do nothing.

If the light changes from off to on, set a timer to turn it off in several hours.
If the light changes from on to off, cancel any outstanding timer, so that the cycle will get a clean restart at next off/on.

As you have asked for some inspiration here is a rule I use to control some lights that are grouped. The rule doesn’t check if the lights have been manually activated but you could add a check for the state of the lights where it checks the ‘lux’ value since my rule only turns on the lights if the room is dark. This rule works in both OH 2.x and OH 3 although in OH 3 you need to put it in a file (it uses a couple of global variables and I’m not sure where these should be defined in OH 3)

val String logName = "cloakroom.rules"

var Timer tLight = null
var Boolean bMotionActivated = false

rule "Turn on lights when motion triggered"
when 
    Item Sensor_FF_CR_Motion received update
then

    logInfo(logName, "Cloakroom Motion - State: " + Sensor_FF_CR_Motion.state)

    if (Sensor_FF_CR_Motion.state == 1) {
        // Record the last motion time
        //Var_FF_CR_MotionLastDetected.postUpdate( new DateTimeType() )

        var lux = Sensor_FF_CR_Lux.state
        logInfo(logName, "Cloakroom Motion - lux: " + lux)

        logInfo(logName, "Cloakroom Motion - tod: " + Astro_OU_CurrentTimeOfDay.state.toString)
        var brightness = 100
        // set the brightness according to time of day
        if (Astro_OU_IsDaylight.state === ON) {
            brightness = 80
        } else {
            // check Sleep Mode
            if ((Astro_OU_CurrentTimeOfDay.state.toString != "Night") && (Astro_OU_CurrentTimeOfDay.state.toString != "Early Morning")) {
                 brightness = 50
            } else {
                brightness = 10
            }
        }

        logInfo(logName, "Cloakroom Motion - Lights " + brightness + "%")

        // if the lights haven't been activated check the lux
        if (lux > 1000 && !bMotionActivated) {
            // turn on the lights
            bMotionActivated = true
        } 

        if (bMotionActivated) {
            // lights should be turned on
            if(Grp_Lights_FF_CR_Ceiling_Switch.state != ON) {
                Grp_Lights_FF_CR_Ceiling_Brightness.sendCommand(brightness)
                Grp_Lights_FF_CR_Ceiling_Switch.sendCommand(ON) 

            }

            // create / reset the timer 
            if (tLight !== null) tLight.cancel                                                              
            //logInfo("CloakroomPir","Creating Timer")
            tLight = createTimer(now.plusMinutes(1), [ |                                                    
                //logInfo("CloakroomPir","Timer Expired")
                Grp_Lights_FF_CR_Ceiling_Switch.sendCommand(OFF)                                               
                tLight = null                                                                               
                bMotionActivated = false
            ]) 
        }
    }

end

only when the light is on manually (timer =null)

if (GF_Mpalkoni_Light_1.state == ON && occupancyTimer === null) return;

my rule, with when the sun is low

var Timer occupancyTimer = null
val int timeoutMinutes = 1 // choose an appropriate value

rule "MotionDetector1 received ON"
when
    Item MotionDetection changed from OFF to ON
then

if (GF_Mpalkoni_Light_1.state == ON && occupancyTimer === null) return;
    

if(Sun_Elevation.state < -5|°  ) { 
//logInfo("MotionDetection","light on") 

            GF_Mpalkoni_Light_1.sendCommand(ON)

    if(occupancyTimer === null) {
        occupancyTimer = createTimer(now.plusMinutes(timeoutMinutes ), [|
            GF_Mpalkoni_Light_1.sendCommand(OFF)
           // logInfo("MotionDetection","light off")
            occupancyTimer = null
        ])
    }
    else {
        occupancyTimer.reschedule(now.plusMinutes(timeoutMinutes ))
    }
}
1 Like

Thanks guys…one question. For the motion sensor I have it turning on a virtual switch which has a expire binding of 60 seconds.

The rule then runs to turn the light on if that switch is on and off when the switch expires.

  1. With the expire binding does the 60 second timer reset for each ON command it receives or does it set to 60 and then just ignore any new commands during the 60 seconds.

  2. how do you reset the timer on an expire binding, just automatically set it to off directly via a command or as with (1) does it ignore any new commands during the 60 seconds timer?

#1, same as in OH2.

If by reset you mean “cancel” - the only way to do that is by pre-empting what it is going to do i.e.if you have expire 5m, command=OFF then you must send an OFF command.

It is not possible to “abort” a running expire timer without taking the action it is going to do. Expire is simple, but not a complete substitute for rules based timers.

1 Like

Hi all,

Spent the weekend getting my brain back into OH mode. Thanks for all your input, it’s made me realise that my rules were wrong which is what was causing all the infighting between sensor and switch.

I had a rule that started a switch with expire binding of 60 seconds, that same rule also turned the light on and did a few other bits. The rule with ‘where timing switch is ON or OFF simply turned the light off.

I now realise that the light on or off part both need to be within the timing rule, otherwise the light works outside of the timer and stomps over the ‘if the light is already on’ statement controlling the physical dimmer switch.

Not sure how I got into this pickle and didn’t notice it but there you go…

All sorted now, the wife is happy again now the lights work as expected :slightly_smiling_face:

1 Like