Monitoring Lights

I’m looking for a little advice here. Maybe someone has a similar issue and created a great solution. But mainly I’m looking for peoples ideas on how to resolve my issue.

I have a few lights that don’t always switch off when I expect them to, but so far I can’t find a reason why.

Let me use my downstairs WC as an example. I have a Hue light in the ceiling and a ZWave Door sensor to monitor that status of door, either open or closed. When the door is opened and the state is currently unoccupied the light will switch on and the occupied state is set. When the door is then re-opened the occupied state is then changed back. The light then switches off when the door is then closed once again. My rule for this works 90% of the time. Some times it’s down to user error, or should I say amazement that a light switches on by itself. It seem most of my friends are impressed by this small automation.

There are however occasions when the light doesn’t switch off, even though the occupied state changes as it should. Most likely this is down to a communication breakdown between OH and the Hue bridge. It’s not however a massive problem, but clearly not ideal.

One idea I have is to create a timer that then switches the light off once it’s run. But I would have to do this for all of the lights that don’t always switch off as expected. Of the rules I’ve created so far I’ve always tried to make sure they are as generic as possible, so that I’m not creating multiple rules that only have a small change.

If anyone has any suggestions then please feel free to let me know. I’m not necessarily looking for someone to write a rule for me, but examples would be greatly appreciated.

For reference here’s my rules to go along with the description above.

rule "Toilet Occupied"
when
    Item Cloakroom_ZW089_Door changed to OPEN
then
if(Cloakroom_Occupied.state != ON) {
    Cloakroom_CeilingLight_vSwitch.sendCommand(ON)
    Cloakroom_Occupied.sendCommand(ON)
    logInfo(filename, "Cloakroom: Occupied")
    logInfo(filename, "System Message: Timer myHallwayTimer has been created.")
    myHallwayTimer = createTimer(now.plusSeconds(vTimeout)) [|
        logInfo(filename, "System Message: Timer myHallwayTimer has ended.")
        if(Cloakroom_ZW089_Door.state == OPEN) {
            Cloakroom_Occupied.sendCommand(OFF)
            Cloakroom_SpotLight_Dimmer.sendCommand(75)
        }
        myHallwayTimer = null
    ]
} else {
    Cloakroom_Occupied.sendCommand(OFF)
}
end

rule "Toilet Door Closed"
when
    Item Cloakroom_ZW089_Door changed to CLOSED
then
if(Cloakroom_Occupied.state == OFF) {
    Cloakroom_CeilingLight_vSwitch.sendCommand(OFF)
    logInfo(filename, "Cloakroom: No longer Occupied")
}
end

Observation; you blindly create a new Timer each rule run, regardless of if there is already one running.
That does not cancel or destroy the old Timer, only overwrite your reference variable with the new ‘handle’. The old Timer continues on it’s way but now you can no longer control it in any way having lost the handle.

There is a fair amount of hoping things happen quickly enough before the next event comes along. Remember Item commands and updates are asynchronous in action the rules don’t stop and wait for them to take effect. Doors can be opened and closed in sub-second timescales.

If you just want to change the state of Cloakroom_Occupied, then do so with postUpdate(). Sending commands just adds overhead if there is no need.