Following on from my previous post about improving motion sensor behaviour, this is another little automation that I enjoyed making work.

The background

We have a downstairs toilet near our front door. I wanted to add a contact sensor to the door but there are 2 different scenarios to consider.

Scenario 1 - Just popping in

The first is the "normal" contact sensor behaviour where the light turns on when the door is opened and off again when it is closed. I wanted this to work because we often just "pop in" to this bathroom to wash our hands or use one of the cleaning utensils that live in there.

Scenario 2 - Taking care of business

The second is for actually using the loo. Clearly in this case we don't want to have to leave the door open in order to keep the light on. I also didn't want to use a timer since sometimes suffice to say we'd be in there longer than others. Timers and / or motion sensors would have had the potential to lead to unwanted black outs or arm waving at inconvenient moments.

The solution

As before, the key is differentianting between the concept of occupancy and that of the contact sensor being open or closed.

When the door opens, we turn the light on but don't yet mark the room as occupied.

After a suitable delay (I settled on 3 seconds), we check again to see if the door is still open. If so we assume it is scenario 1. We then mark the room as occupied.

Then when the door closes again we invert the occupied state. This means that if we have decided it is scenario 1, the room will have already been marked as occupied and so we will set the room state to unoccupied which will turn the light off. Otherwise we will set the room state to occupied. Whilst this will send a message to turn the light on, it will already be on and so nothing will change.

Then in the case of scenario 2, when we open the door to leave we will send another message to turn the light on. Since the light will still be on, this will have no effect. Finally when we close the door again, the room's state will be inverted setting it to false and turning off the light.

The implementation

Home Assistant

I set up an additional binary sensor in Home Assistant to represent the downstairs toilet occupancy which is bound to an MQTT topic, in this case home/s/downstairs-toilet/occupied. Here is the configuration for that sensor.

# configuration.yaml

binary_sensor:
  - platform: mqtt
    device_class: occupancy
    name: Downstairs toilet occupied
    state_topic: home/s/downstairs-toilet/occupied
    payload_on: 'true'
    payload_off: 'false'

Node-RED

Here is the flow implementation in Node-RED

Node-RED flow

There is an additional simple connection from the MQTT occupancy topic to the topic to turn the light on. Since these are both boolean topics all that is required is to pass the message from the home/s/downstairs-toilet/occupied topic to the home/s/downstairs-toilet/lights/on topic.

The result

This works great! Not only that, it makes me smile every time and no-one else in the house even seems to notice it which in my eyes is the sign of a great automation!