Room-following light that tracks you along the corridor
Three Thread presence sensors hand a single 20 % light level from zone to zone so the corridor is lit 2 m ahead of you and 4 m behind, without ever lighting the whole run at once. Measured handoff latency 600 ms.
# HearthNodes recipe 02 - corridor room-following light handoff
alias: "Presence - corridor follows you"
id: hn_presence_room_follow_lights
description: "Three-zone corridor light handoff at 20 percent, direction aware"
mode: restart
max_exceeded: silent
trigger:
- platform: state
entity_id:
- binary_sensor.corridor_zone_a_presence
- binary_sensor.corridor_zone_b_presence
- binary_sensor.corridor_zone_c_presence
to: ["on", "off"]
variables:
zones: ['a','b','c']
here: "{{ trigger.to_state.entity_id.split('_')[2] }}"
prev: "{{ states('input_text.corridor_last_zone') }}"
going_up: "{{ zones.index(here) > zones.index(prev) if prev in zones else true }}"
next_zone: >-
{{ zones[zones.index(here) + (1 if going_up else -1)]
if (going_up and zones.index(here) < 2) or ((not going_up) and zones.index(here) > 0)
else here }}
condition:
- condition: state
entity_id: input_boolean.night_path_armed
state: "on"
- condition: template
value_template: "{{ trigger.to_state.state != trigger.from_state.state }}"
- condition: numeric_state
entity_id: sensor.corridor_illuminance
below: 80
action:
- service: input_text.set_value
target:
entity_id: input_text.corridor_last_zone
data:
value: "{{ here }}"
- service: light.turn_on
target:
entity_id:
- "light.corridor_segment_{{ here }}"
- "light.corridor_segment_{{ next_zone }}"
data:
brightness_pct: 20
color_temp_kelvin: 2200
transition: 0.8
- service: light.turn_off
target:
entity_id: "light.corridor_segment_{{ prev }}"
data:
transition: 6
# Direction unknown (two neighbours in the same second) -> light both, fall back
# to a 90 second all-corridor timer. Thread border router loss -> plain motion
# trigger at 20 percent with the same 90 second off delay.
Trigger · state
binary_sensor.corridor_zone_{a|b|c}_presence
Any of the three corridor zone presence sensors changes state (on or off).
Step-by-step
- light.corridor_segment_a|b|cLight the occupied segment plus the next segment in the direction of travel; both at 20 %, 2200 K.
turn_on · brightness_pct 20 · color_temp_kelvin 2200 · transition 0.8s - light.corridor_segment_prevFade the segment behind you out over 6 s so the light visibly follows rather than snapping.
turn_off · transition 6s - input_text.corridor_last_zoneRemember the last occupied zone so a second transition 1 s later can compute the direction of travel.
set_value {{ trigger.to_state.entity_id }}
Split the corridor into three overlapping zones
Zones should overlap by roughly 0.6 m. If they abut exactly, you get a dead band where the previous light has already faded and the next has not yet triggered. Measure the overlap with a tape and write the numbers on the sensor labels; guessing here is why most room-following setups flicker.
Make the off transition longer than the on transition
0.8 s on and 6 s off is the ratio that reads as movement. If both are short you get a strobe; if both are long the corridor feels sluggish and people outrun the light. Tune the off value first, because it is the one people notice.
Keep one border router per floor
Thread partitions merge on their own but take seconds. If your corridor spans two partitions, handoffs stall exactly when someone walks fast. Either keep one border router per floor or plug a Thread router-capable mains device at the corridor midpoint so both ends stay in one partition.
Hardware
| Model | Protocol | Link | Role in this chain |
|---|---|---|---|
| Eve Motion (Thread) | thread |
wireless | Zone A and C sensors; battery powered, Thread router-capable so they also strengthen the mesh. |
| Aqara FP2 | wifi |
wireless | Zone B (mid-corridor) mmWave sensor, used because a still person in the doorway must not drop the light. |
| Thread border router (HomePod mini or SkyConnect) | thread |
wired | Single border router for the corridor mesh; a second one is kept as a cold spare because Thread partition merges are the usual cause of 2–3 s handoff stalls. |
When it fails
If the direction cannot be computed (both neighbours transition in the same second), the automation lights both neighbours at 20 % and falls back to a 90 s all-corridor timer. If the Thread border router drops, the scene degrades to a plain motion-triggered full-corridor 20 % with the same 90 s off delay, which is dimmer but never leaves you in the dark.