My Smart Home

Presence Lights That Don't Fight You

The seven-automation system that stops mmWave presence lights arguing with the wall switch: on when you walk in, off when you say off, and no flip-backs.

On this page
  1. The actual problem
  2. The state it keeps
  3. The seven automations
  4. Why the ownership flag matters more than the sensor
  5. Details that took a while to get right
  6. The rest of the house
  7. Occupancy-aware lighting for the plain rooms

Presence lighting is the first thing everybody builds with a mmWave sensor and the first thing everybody regrets. The sensor sees you, the light comes on. Fine. Then you turn it off because you’re watching a movie, and thirty seconds later the sensor sees you again and turns it right back on. So you add a condition, then another, and a month later you’ve got a light that sometimes comes on and sometimes doesn’t and nobody in the house trusts the switch anymore.

I went through all of that in my dining room. The fix was deciding, explicitly, who owns the light at any given moment - the automation or the human - and writing that down as state Home Assistant can check.

This assumes the sensor side already works. If you are still at the choose-and-tune stage, how to add presence detection to every room covers combining and tuning the sensors, and the mmWave presence sensor roundup covers what to buy.

The actual problem

A presence sensor only answers one question: is somebody in the room. It says nothing about what that person wants. Turning the light off while you’re still in the room is a perfectly normal thing to do, and a naive automation treats it as a glitch to be corrected.

So the automation needs a memory. Specifically, it needs to know:

  • Did I turn this light on, or did a person?
  • Did a person turn it off while the room was still occupied?
  • How long ago did any of that happen?

Once those three things are tracked, every rule gets simple.

The state it keeps

Five small helpers do all the remembering. Nothing fancy, just the built-in helper types:

HelperWhat it means
input_boolean.dining_room_lights_auto_activeThe automation currently owns the light. It turned it on and expects to turn it off.
input_boolean.dining_room_lights_manual_off_blockSomeone turned the light off while the room was occupied. Do not turn it back on.
input_datetime.dining_room_lights_last_auto_onWhen the automation last switched it on.
input_datetime.dining_room_lights_last_manual_onWhen a person last switched it on.
input_datetime.dining_room_lights_last_auto_off and input_number.dining_room_lights_last_brightnessWhen the automation last turned it off, and how bright it was, so it can put things back the way they were.

The auto_active flag is the important one. Everything else hangs off the question “does the automation own this light right now.”

The seven automations

Each one is small and does exactly one job. Together they’re a little state machine.

1. Presence on. When the sensor flips to occupied, and the manual-off block isn’t set, and the light is either off or already automation-owned: turn it on, claim ownership, and stamp last_auto_on. Brightness is 85% during the day and 30% between 10 PM and 6 AM. One nice touch: if the automation itself turned the light off within the last five minutes - you stepped out to grab something - it restores whatever brightness you had rather than resetting to the default.

2. Presence off. When the room has been empty for 60 seconds, turn the light off with a three-second fade - but only if the automation owns it, or if a person turned it on more than four hours ago. That four-hour rule is the escape hatch for “I turned this on by hand and forgot about it.” Before it turns the light off it saves the current brightness so rule 1 can restore it.

3. Manual off block. If the light goes from on to off while the automation owns it and the room is still occupied, a person did that on purpose. Set the block flag and release ownership. Now rule 1 won’t fire again no matter how much the sensor sees you.

4. Clear the block. When the room has been empty for 60 seconds, clear the manual-off block. The next time someone walks in, presence lighting works normally again. The block is tied to the occupancy session, not to a timer, which is the part I got wrong for a long time.

5. Manual interaction override. If the dimmer changes state while the automation owns it, and it’s been more than 10 seconds since the automation touched it, treat that as a human taking over: stamp last_manual_on and release ownership. The 10-second window is there so the automation’s own turn_on doesn’t trigger this and immediately fire itself.

6. Record manual on. If the light goes from off to on while the automation does not own it, a person turned it on. Stamp last_manual_on so rule 2 knows to leave it alone for four hours.

7. Claim manual on. A leftover from an earlier version that I’ve since folded into rules 5 and 6. It’s sitting there empty and unavailable because I never got around to deleting it. Every real automation setup has one of these.

Why the ownership flag matters more than the sensor

Most people try to fix presence lights by tuning the sensor: more sensitivity, less sensitivity, a longer off delay. Tuning is worth doing, and the plain version of presence lighting - occupancy-aware lighting for the plain rooms, at the end of this piece - is enough for most rooms. But in a room where people deliberately switch the light off, tuning treats the symptom. The sensor was never the problem; it was doing its job. The problem was that the automation had no way to tell “the room is occupied and the light is off because I haven’t turned it on yet” apart from “the room is occupied and the light is off because someone just turned it off.” Those look identical to a sensor. They’re completely different to a person.

The auto_active flag is what separates them. When the automation owns the light, an off event is a human override. When it doesn’t, an off event is just the state of the world. That one distinction removes almost every case where the lights used to fight back.

Details that took a while to get right

The 10-second guard on rule 5 was the first. Without it, the automation turning the light on fires the “someone touched the dimmer” rule, which releases ownership, which breaks rule 2. Any automation that watches an entity it also controls needs a guard like this. It also only works with a switch that reports its own state changes locally, which is the first thing to check when picking one from the local switch and dimmer options. Saving brightness on the way out was the second. Coming back into a room and having the light snap to 85% when you’d dimmed it to 40% for dinner is exactly the kind of small annoyance that makes people rip automations out, and saving and restoring it costs one helper. Tying the block to the occupancy session rather than a timer was the third. My first version cleared the manual-off block after 15 minutes, so if you sat through a two-hour movie with the lights off, they’d come on at the 15-minute mark. Clearing it only after the room empties out matches what people expect. And the four-hour manual rule: if a person turns the light on and leaves, something eventually has to turn it off, and four hours is long enough that it never interrupts a real use and short enough that it doesn’t burn all night.

The rest of the house

Every other room here runs a much simpler version: one automation per room that turns the lights on with presence and off after a delay. The kitchen, living room, gym, basement stairs, and man cave all work that way, with no ownership flag at all, and they’re fine, because nobody sits in the gym with the lights deliberately off. The dining room got the full treatment because it’s the one room where someone is likely to turn the light off on purpose and then stay put.

Occupancy-aware lighting for the plain rooms

The simple version - lights on when someone is present, off when the room empties - is the upgrade I’d put in every room first. The work is in choosing sensors that detect presence well, and wiring them to lighting control that runs locally.

Plain PIR motion sensors are cheap and reliable for detecting movement, but they can switch lights off while you’re sitting still. For rooms where you’re sedentary (offices, living rooms), mmWave presence sensors detect tiny movements like breathing and keep lights on while you’re there. The Everything Presence One is the mmWave option to look at for Home Assistant: an ESP32/ESPHome device that combines mmWave presence, PIR motion, light level, and temperature/humidity. For battery PIR, the Aqara Motion and Light Sensor P2 is a Matter-over-Thread sensor that reports both motion and illuminance, and on Zigbee the frient Motion Sensor Pro reports light and temperature as well. Avoid the cheapest no-name sensors, which often have slow re-trigger times and short battery life. The local presence sensor roundup has the longer list.

For the lights themselves, smart bulbs like Philips Hue work, but a relay wired behind the existing fixture - the Shelly 1 Gen4 or the Shelly 1 Mini Gen3 - is often better for occupancy lighting because it keeps working when someone uses the physical switch. When tuning, set a sensible off-delay (often 1-5 minutes for living spaces, shorter for closets), and use a sensor’s illuminance reading (the Aqara P2, frient Pro, and Everything Presence One all report light level) so lights only come on when it’s dark. mmWave solves the “still person” problem but can be triggered by fans, pets, or motion in an adjacent room, so placement and sensitivity matter; PIR can miss a still person or trigger from movement seen through a doorway. Battery sensors need occasional battery changes; USB-powered options like the Everything Presence One avoid that at the cost of needing power nearby.

On HomeKit, pair a Matter or HomeKit motion sensor with HomeKit-compatible lights and let a Home hub (a HomePod or an Apple TV; iPads are no longer supported as hubs) run the automation locally. On Hubitat, use the Motion Lighting app or Rule Machine; Hubitat natively supports Zigbee and Z-Wave sensors and lights. One catch for those households: the Everything Presence One is an ESPHome/Wi-Fi device that neither HomeKit nor Hubitat supports natively, and the Matter-over-Thread P2 joins Apple Home directly but needs a separate Thread border router on the network before a standard Hubitat hub can reach it. On those hubs, choose Zigbee or Z-Wave sensors instead.

If you build one of these, start with rules 1, 2, and 3. Ownership, presence-off, and the manual-off block cover the case that makes people hate presence lighting. Add the rest when the room asks for them. And if seven automations sounds like more YAML than you want to own, a motion-lights blueprint gets you the simple version in a few clicks - Home Assistant blueprints worth installing first covers the ones to import.

Keep going

All articles →
Article

Best local presence sensors for Home Assistant and local-first homes

Everything Presence Lite first for a Home Assistant house: local mmWave, no cloud account. Plus Apollo MSR-2, Aqara FP1E and FP2, and wired picks room by room.

Read article →
Article

Best mmWave presence sensors for Home Assistant

The mmWave presence sensors worth buying for Home Assistant: why they beat PIR, my picks with prices, placement gotchas, and HomeKit/Hubitat notes.

Read article →
Article

How to add presence detection to every room

How I add reliable presence detection to every room of a local-first Home Assistant house: mmWave and PIR sensors by room type, network tracking for who's home, and why I skip Bluetooth trackers.

Read article →
New guides and product notes, no inbox required. Follow via RSS →