Motion-Activated Lighting: Hallway, Bathroom, Kitchen, and Common Mistakes
Motion-Activated Lighting: Hallway, Bathroom, Kitchen, and Common Mistakes
Automation can turn on a light, but it doesn't own it. If a person deliberately changes its state, their decision takes priority: automation only turns off what it turned on itself. This lesson builds the first sensible layer of motion control: the hallway as a test point, then the bathroom and kitchen.
We're not promoting "motion everywhere." A PIR doesn't mean presence. Lux limits turning on, not holding a light on. A timer counts time since motion last stopped. The modes from Lesson 10 (Night, Movie, Guests) affect the behavior. You only turn on the global lighting_automation_enabled helper after reviewing every automation that uses it. Further on I'll shorten Home Assistant to HA.
Plan on about 115 to 125 minutes. Automations use the action: syntax.
This lesson's rule
Motion can turn a light on. Absence starts a countdown. Lux decides whether to turn it on automatically. A household member's manual decision comes first.
A real-life problem: the light goes out in the bathtub
A PIR above the door, a 2-minute delay, then turn off. After two minutes in the bath, the light goes out: the sensor can't see a person behind the shower screen. Or: a household member manually turns off the light, is still standing in the hallway, and the sensor turns it back on. Or: lux rises once the lamp is on, the next motion event doesn't cancel the timer, and the light goes out despite someone being present.
These problems come from flawed logic: a delay instead of measuring time since motion actually stopped, checking lux before every click, and no distinction between a light turned on by automation and one turned on by hand.
What takes priority
- A household member's manual control.
- A local lockout or a manual override.
- A special mode: Movie, Guests, Cleaning.
- Night mode, setting the brightness.
- Motion or presence.
- Lux limiting automatic turn-on.
- A timer responsible for turning it off.
PIR and mmWave: no magic involved
A PIR detects body movement. Cheap, efficient. It doesn't detect a motionless person, someone lying in a bathtub, or someone behind a wall. False triggers can come from a radiator, warm air currents, sunlight, a pet, or a poorly tuned sensitivity setting: a fluttering curtain isn't an obvious trigger for every PIR.
An mmWave radar can detect subtle movement, but its effectiveness depends on mounting, zones, and the surrounding environment. It can react to movement behind a wall, a curtain, a washing machine, a fan, or a pet. First you observe the data and calibrate the zone: only afterward do you let the sensor turn off the light.
Humidity can support ventilation or extend a light's runtime during a bath, but it doesn't replace presence detection: it rises with a lag, lingers after someone leaves, and doesn't change for a quick trip to the toilet. A door contact sensor isn't a people counter: a closed door doesn't equal someone being there.
| Room | Starting point | Notes |
|---|---|---|
| Hallway / entryway | A PIR is usually enough | The first test point |
| Bathroom | PIR plus a long timer = a workaround | mmWave only after calibration; humidity as a helper signal |
| Kitchen | Zones, not one sensor | The entrance isn't the counter while cooking |
| Living room | Don't turn it off on a brief PIR | Motion can be a helper signal, not a quick shutoff trigger |
A cat walking through at night is a correct motion detection, not necessarily a "sensor bug." You can limit brightness or the angle if you don't want a full-brightness light in that case.
Lux only for turning on
Lux measures the light level at the mounting location. Once the lamp is lit, the reading rises: if the lux condition sits ahead of canceling the timer, the next motion event won't keep the light on. That's why: check lux only when the light is off and you're deciding whether to turn it on automatically. When the light is on, motion cancels the timer regardless of lux.
Don't carry a threshold from one model over to another. Record the reading at the moment you yourself judge the light is needed. A starting point: hallway ~30-50, a kitchen with a window higher: calibrate it. Lux unknown/unavailable: for an important passage, consider a low emergency brightness rather than no light at all; for decorative lighting, you can choose not to turn it on. In a windowless bathroom, lux often adds nothing useful: you can skip it.
The simplest rule: automation only turns off a point it turned on itself. The hallway_light_on_by_motion helper marks the owner. Manual turn-on: don't switch it off with the motion timer. Manual turn-off: don't turn it back on for a set period (a manual-override timer).
The timer: on cancels, off starts it
The pattern "motion on → turn on plus start the timer" doesn't measure time since motion actually stopped. A PIR can stay on for a minute: a timer started at "on" finishes too early relative to the real absence of a person.
A better pattern: motion on → cancel the shutoff (and possibly turn on); motion off → start the timer; timer finished → confirm there's still no motion and check the owner → turn it off.
For a simple point, one automation with mode: restart and a wait for no-motion may be enough. A timer is better when you want to see the remaining time, cancel the countdown, or share it with manual control. Calling timer.start on an active timer restarts the countdown from scratch. Use timer.cancel to cancel it: timer.finish can trigger the shutoff event.
restore: true can restore an active timer after an HA restart, but if the timer expired while HA was down, the timer.finished event won't fire once it starts back up. After a restart, run a test: an active timer and an expired one, the light's state, and the helpers' states. The owner helper (hallway_light_on_by_motion) may not reflect reality: clear it whenever the light is off. For a critical hallway with lux unavailable: turn on a limited brightness and report the sensor problem.
Hallway helpers
input_boolean:
hallway_motion_lockout:
name: Motion lockout - hallway
icon: mdi:motion-sensor-off
hallway_light_on_by_motion:
name: Hallway - light turned on by motion
icon: mdi:motion-sensor
timer:
hallway_light:
name: Hallway light shutoff timer
duration: "00:03:00"
restore: true
hallway_light_manual_override:
name: Hallway light manual override
duration: "00:30:00"
restore: true
hallway_motion_lockout disables both automatic turn-on and turn-off: the light's current state stays put, and the household member controls it manually; cancel any active timer. In a real home, local lockouts (hallway_motion_lockout) are usually more convenient than one global one. The global lighting_automation_enabled blocks new turn-on cycles; you can leave an already-started shutoff to finish (define this deliberately). Don't turn on the global helper "just for the hallway": it's global; test with the local helper instead, or disable the other automations. If your helpers are created via the UI, don't duplicate them in YAML.
- id: hallway_lockout_cancels_timer
alias: Hallway - motion lockout cancels the timer
mode: single
triggers:
- trigger: state
entity_id: input_boolean.hallway_motion_lockout
to: "on"
actions:
- action: timer.cancel
target:
entity_id: timer.hallway_light
The hallway's architecture: three automations
Take the nighttime brightness from light_mode = night (Lesson 10), not from duplicated 10pm-6am windows. Brightness should be no lower than the minimum stable start level from Lesson 5. On stairs, safety takes priority over "an efficient 5%." When the light is already on: don't change a manually set brightness; only cancel the timer. Don't trigger the Evening scene from hallway motion.
- id: hallway_motion_holds_and_turns_on
alias: Hallway - motion holds and turns on the light
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.hallway_motion
to: "on"
actions:
# Cancel the timer before the master check: motion should hold an already-lit
# light even when the master is off (master = don't start new cycles; don't
# immediately interrupt one already running). If the master is meant to
# "change nothing," move timer.cancel after the master/lockout conditions.
- action: timer.cancel
target:
entity_id: timer.hallway_light
- condition: state
entity_id: input_boolean.lighting_automation_enabled
state: "on"
- condition: state
entity_id: input_boolean.hallway_motion_lockout
state: "off"
- condition: state
entity_id: timer.hallway_light_manual_override
state: "idle"
- if:
- condition: state
entity_id: light.hallway_ceiling
state: "off"
then:
- condition: numeric_state
entity_id: sensor.hallway_motion_illuminance
below: 40
- choose:
- conditions:
- condition: state
entity_id: input_select.light_mode
state: "night"
sequence:
- action: light.turn_on
target:
entity_id: light.hallway_ceiling
data:
brightness_pct: 10
transition: 1
default:
- action: light.turn_on
target:
entity_id: light.hallway_ceiling
data:
brightness_pct: 60
transition: 1
- action: input_boolean.turn_on
target:
entity_id: input_boolean.hallway_light_on_by_motion
- id: hallway_no_motion_starts_timer
alias: Hallway - no motion starts the timer
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.hallway_motion
to: "off"
conditions:
- condition: state
entity_id: input_boolean.hallway_motion_lockout
state: "off"
- condition: state
entity_id: light.hallway_ceiling
state: "on"
- condition: state
entity_id: input_boolean.hallway_light_on_by_motion
state: "on"
actions:
- action: timer.start
target:
entity_id: timer.hallway_light
data:
duration: "00:03:00"
- id: hallway_timer_turns_off_light
alias: Hallway - the timer turns off the light
mode: single
triggers:
- trigger: event
event_type: timer.finished
event_data:
entity_id: timer.hallway_light
conditions:
- condition: state
entity_id: input_boolean.hallway_motion_lockout
state: "off"
- condition: state
entity_id: binary_sensor.hallway_motion
state: "off"
- condition: state
entity_id: light.hallway_ceiling
state: "on"
- condition: state
entity_id: input_boolean.hallway_light_on_by_motion
state: "on"
actions:
- action: light.turn_off
target:
entity_id: light.hallway_ceiling
data:
transition: 1
- action: input_boolean.turn_off
target:
entity_id: input_boolean.hallway_light_on_by_motion
Movie / Guests / Cleaning modes: don't turn on a bright light visible from the living room during Movie mode; Guests: a longer timer; Cleaning: often a local lockout. Adapt the automation's choose block to light_mode. A motion sensor that's unavailable isn't the same as no motion: don't turn the light off for that reason. After a manual turn-off, start timer.hallway_light_manual_override (a condition already checked in the first automation). Recognizing manual control depends on your hardware: check the Logbook; there's no single universal YAML for it. In your exercise, don't require detecting the source of a command if the device doesn't expose it: a separate manual-lockout button, or a button that runs through an HA script, is an acceptable alternative. light_mode is the last deliberately chosen logical mode: it isn't confirmation that every lamp actually adopted the scene.
Bathroom and kitchen: later, more carefully
Bathroom: presence on → cancel the timer, turn on if allowed; presence off → a 30-90 second timer; finished → confirm it's still off and check sensor availability; only turn off the light this automation owns. On unavailable: don't turn off automatically, fall back to a manual Plan B. On stuck-on: a diagnostic alert, not an aggressive shutoff. Test with the bathtub/shower screen, the fan, and steam: don't test electrical wiring near water.
Kitchen: a PIR at the entrance (ceiling-mounted, oriented) isn't the same as the counter zone. When cooking: an mmWave sensor at the counter, or a manual counter turn-on, a Cooking scene, and a long override. Don't turn off the counter light just because someone's standing still at the cutting board.
With Hue Motion, check the bridge-to-HA delay and the local path: don't assume "cloud polling" is a typical cause. Don't compare Zigbee to Wi-Fi with fixed millisecond figures: latency depends on the installation.
Testing motion-activated lighting
☐ Motion with the light on doesn't change a manually set brightness.
☐ A rise in lux after turning on doesn't block the light from being held on.
☐ No motion only starts the timer once the sensor actually goes to off.
☐ New motion cancels an active timer.
☐ The timer only turns off a light the automation itself turned on.
☐ A manual turn-off blocks a re-trigger for a set period.
☐ A manual turn-on doesn't get switched off by the motion timer.
☐ Night mode sets a safe brightness (≥ the minimum from Lesson 5).
☐ Movie, Guests, and Cleaning modes have defined behavior.
☐ Lux-unavailable and motion-sensor-unavailable have a defined fallback strategy.
☐ A local lockout cancels the timer and leaves manual control available.
☐ A test after an HA restart: both an active and an expired timer.
☐ Plan B: HA stopped, the coordinator, the router, the internet: tested separately.
☐ A household member can turn off automation for a specific room.
☐ Automation traces: id, name, which conditions passed.
Technical dashboard: PIR battery, last motion, availability, the timer, the lockout, the last trigger time. Maximum lit time with a hung mmWave sensor: lean toward an alert rather than an aggressive shutoff in a bathroom.
Common mistakes
A delay instead of a timer started from motion off.
Checking lux before canceling the timer: the light goes out despite motion.
A timer that turns off a light that was switched on manually.
timer.finish instead of timer.cancel.
mmWave, humidity, or a door sensor treated as "certain presence."
Movie mode overridden by hallway motion; 100% brightness at night.
Hands-on exercise
☐ Add the local lockout and the shutoff timer.
☐ Separate the reaction to motion on, motion off, and the timer finishing.
☐ Use lux only to decide on automatic turn-on.
☐ Add a flag for whether the light was turned on by motion.
☐ Test a manual turn-on and a manual turn-off.
☐ Test Night mode at a brightness no lower than the Lesson 5 minimum.
☐ Test with lux unavailable and with the motion sensor unavailable.
☐ Restart HA while the timer is active.
☐ Observe the point for at least a few days before rolling out the bathroom.
☐ Only roll out the bathroom after a real test of presence behind the shower screen or in the tub.
☐ Only turn on the global helper after reviewing every automation that uses it.
Key takeaways
- A PIR detects motion, not certain human presence.
- mmWave needs calibration and can also generate false presence.
- Lux decides whether to turn a light on automatically, but shouldn't block holding an already-lit light on.
- Motion on cancels the shutoff, and motion off starts the countdown.
- A timer only turns a light off after confirming, again, that there's no motion.
- Automation should only turn off a light it turned on itself.
- A manual turn-on or turn-off takes priority over the sensor.
- Night mode is a better source of brightness than duplicated hours spread across many automations.
- Movie, Guests, and Cleaning modes have to affect how motion automation behaves.
unknownandunavailableneed a deliberately chosen fallback behavior.restore: truedoesn't guarantee an action that was supposed to happen while HA was off actually runs.timer.cancelcancels the shutoff;timer.finishcan trigger the completion event.- You test one hallway first, and only then the bathroom and kitchen.
In Lesson 12 you'll add lighting based on the sun and schedules. Before moving on, the hallway should work reliably by hand, not just on paper in YAML.