Follow-me stair light for the Apollo MTR-1 and WLED

ESPHome package for the Apollo MTR-1: tracks people on the stairs with the
LD2450 radar and streams a lit window to a WLED controller over DDP. The
sensor serves a setup wizard that measures the stairs with one walk and
stores the setup on the device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jackson AndresandClaude Opus 5.5 committed 2026-10-14 19:31:00 -04:00
commit 6831bbf9a8
24 files changed
+10874

No files matched your search

+94
View File
@@ -0,0 +1,94 @@
<!--
type: reference
audience: technical
reader: Someone changing the firmware or the setup wizard. Has this repository, Node 22 or newer, Google Chrome and ESPHome.
owner: follow-me-stairs maintainer
last_verified: 2026-10-14. Commands run from the repository root. File contents checked against the source.
sources: firmware/, wizard/, example/
-->
# Developing follow-me-stairs
This document covers how the repository is organized, the tools for the setup wizard, and facts the firmware and wizard depend on. For installation and settings, see the [README](../README.md).
## Repository layout
| Path | Contents |
|---|---|
| `example/apollo-mtr-1.yaml` | Complete device configuration: Apollo's MTR-1 configuration, pinned to a release in Apollo's repository, plus the follow-me package |
| `firmware/follow-me.yaml` | The ESPHome package: tracking, the window, effects, night light, WLED pause, and the setup button on the sensor's web page. Its header comment documents the behaviour in detail. |
| `firmware/follow-me.h` | WLED connection: a background task for address lookup, LED count, strip type and WLED on/off, and the DDP sender |
| `firmware/follow-me-calibration.h` | The stored setup, the stair geometry built from it, and the sensor's `/followme` web addresses |
| `firmware/follow-me-wizard.h` | Generated by `wizard/tools/embed.mjs`. The wizard page with its fonts, gzipped. Do not edit it by hand. |
| `firmware/follow-me-button.js` | Adds the "Set up Follow-Me" button to the sensor's web page, through `web_server` `js_include` |
| `firmware/follow-me-effects.h` | The per-LED effect patterns. It compiles on a desktop for previews. |
| `wled/README.md` | The WLED settings that follow-me needs |
| `wizard/wizard.html` | The setup wizard, as one page |
| `wizard/fonts/` | IBM Plex Sans and Mono, Latin subset, SIL OFL 1.1 |
| `wizard/tools/embed.mjs` | Builds `firmware/follow-me-wizard.h` from the wizard and its fonts |
| `wizard/tools/serve.mjs` | Serves the wizard from a computer on the local network |
| `wizard/tools/drive.mjs` | Runs the wizard in headless Chrome from a list of steps, and saves screenshots |
| `wizard/tools/walk-*.json` | Step lists for `drive.mjs`: one complete setup with the simulated walker per stair shape |
## Changing the wizard
After a change to `wizard/wizard.html` or `wizard/fonts/`, rebuild the embedded page, then build and install the firmware again:
```sh
node wizard/tools/embed.mjs
```
To serve the wizard from a computer, run this from the repository root:
```sh
node wizard/tools/serve.mjs 8080
```
Then open `http://<computer address>:8080/` on a phone, and enter the sensor's address in the bar at the top. To use the simulated walker instead of the radar, add `?sim=1` to the address.
To run a complete setup without a phone, run this while `serve.mjs` is running:
```sh
node wizard/tools/drive.mjs "http://127.0.0.1:8080/?sim=1" 1280 820 wizard/tools/walk-l.json
```
`drive.mjs` saves the screenshots named in the step list to the current folder, and prints "no page errors" when the page raised no errors. It uses Google Chrome at its macOS path. To use another Chrome, set `CHROME` to its path.
## Walk grading
The Walk screen grades each stretch of the walk: each flight, and the landing. A stretch fails when one of these is true:
| Check | Fails when |
|---|---|
| Coverage | The radar has no reading for 3 steps or more |
| Drift | More than 25% of the stretch's readings are outside the stairs, farther than half the stair width from the walking line |
| Step spacing | A flight's average step is less than half or more than twice 260 mm, or more than twice the other flight's |
The limits are constants at the top of the walk report section in `wizard/wizard.html`. A setup loaded from the sensor has no radar readings, so only step spacing is checked. "Show raw numbers" shows the walk in the radar's own frame, in mm.
## Firmware facts
- Frames go to WLED over DDP, UDP port 4048. Each LED takes 4 bytes on strips with a white LED and 3 bytes on other strips, as WLED reports. A frame is split over as many packets as the strip needs, for strips up to 1500 LEDs.
- LED numbers are raw indexes on the WLED controller, the same numbers DDP uses. WLED's segments do not change them.
- Where the strip has a gap, for example a jumper across a landing, the firmware finds it from the LED spacing. A window that crosses the gap lights both sides.
- The setup is stored in the sensor's flash. A change to the size of the stored setup erases it, and the setup wizard must be run again.
## Web addresses on the sensor
| Address | Method | Use |
|---|---|---|
| `/followme` | GET | The setup wizard |
| `/followme/calibration` | GET, POST | The stored setup |
| `/followme/targets` | GET | The radar's raw targets, for the wizard's live view |
| `/followme/preview` | POST | Lights one LED, for the Match screen |
These addresses have no authentication. Any device on the network can use them.
## LD2450 facts
- The LD2450 reports target x mirrored. The stored setup keeps the radar's own frame. Code that draws radar readings or decides left and right must negate x.
- The LD2450 sees about 60° to each side and about 6 m out. The wizard warns when part of the stairs is outside that area.
## Not built
- Installing a prebuilt firmware from a web browser.
+79
View File
@@ -0,0 +1,79 @@
<!--
type: reference
audience: functional
reader: Owner of an Apollo MTR-1 and a WLED strip, with or without Home Assistant. Can flash ESPHome and change WLED settings. Has this repository, their own sensor and their own WLED controller. Does not read the firmware source.
owner: follow-me-stairs maintainer
last_verified: 2026-10-14. Names, ranges, defaults and behaviour checked against firmware/follow-me.yaml and firmware/follow-me.h. Not checked: how each control renders on the sensor's web page.
sources: firmware/follow-me.yaml, firmware/follow-me.h, firmware/follow-me-calibration.h
-->
# Follow-Me settings
This document lists every control that follow-me adds to the sensor. For installation and setup, see the [README](../README.md).
## Where the settings are
| Place | Contents |
|---|---|
| The sensor's web page, `http://<sensor address>/` | Every control in this document |
| Home Assistant, on the sensor's device page | Every control in this document, when the sensor is added to Home Assistant |
| The Test screen of the setup wizard | Window, Buffer, Smoothness, Hold, Offset and Approach |
A change applies immediately. The sensor keeps every setting after a restart.
## Steps
Distances are in steps. One step is the average tread depth that the setup wizard measured on your stairs. A Window of 3 steps lights about three treads on any staircase.
## Lights
| Control | What it does | Default |
|---|---|---|
| Follow-Me Glow | The light that follows people. Off turns follow-me off. It sets the brightness, color, white level and effect of the window. | On, white only, 40% |
| Follow-Me Night Light | Lights a patch at each end of the stairs. It works when Follow-Me Glow is on or off. | Off. When turned on: white only, 5% |
Follow-Me Glow effects: Rainbow, New Year's, Valentine's, St. Patrick's, Easter, Fourth of July, Autumn, Halloween, Haunted, Hanukkah, Christmas, Candy Cane, Snowfall, Fireplace, Aurora, Ocean. An effect replaces the color with a moving pattern, inside the window. The pattern stays fixed to the stairs, and the person walks through it. When Follow-Me Glow turns off, the effect goes back to None.
Where the window and the night light overlap, each LED shows the brighter of the two.
## Tuning
| Control | What it does | Range | Default |
|---|---|---|---|
| Follow-Me Window | The length of the lit window. | 1 to 15 steps | 3 steps |
| Follow-Me Buffer | How close the person gets to either end of the window before the window moves. The window stays still while the person is inside it. When the person comes within this distance of either end of the window, the window slides to keep this distance. | 0 to 5 steps | 1 step |
| Follow-Me Offset | Moves the window ahead of the person, in the direction they walk. A negative value moves it behind. The shift grows with walking speed, so a person who stands still gets no shift. | -3 to 3 steps | 0 steps |
| Follow-Me Approach | A person off the stairs within this distance of either end lights that end of the stairs. The sensor ignores people farther away. | 0 to 6 steps | 2 steps |
| Follow-Me Smoothness | How closely the window follows the radar. 0% follows each radar reading. 100% moves slowly and smoothly. | 0 to 100% | 50% |
| Follow-Me Hold | How long the window stays lit after the radar loses a person on the stairs. Then the window fades out. | 0 to 60 s | 4 s |
| Follow-Me Fade In | The fade-in time of a window that starts away from the ends of the stairs. A window that starts at either end slides in from that end in 0.25 s. | 0.1 to 10 s | 1.5 s |
| Follow-Me Fade Out | The fade-out time after Follow-Me Hold ends. When a person walks off either end of the stairs, the window shrinks toward that end and fades out in 1 s. | 0.1 to 10 s | 3 s |
| Follow-Me Night Light Size | The length of each night light patch. | 0.5 to 8 steps | 2 steps |
## Switches and choices
| Control | What it does | Default |
|---|---|---|
| Follow-Me Multi-Person | Off: one window follows one person. On: up to three windows follow up to three people. With it on, a new window starts only near either end of the stairs. | Off |
| Follow-Me Pause While WLED On | Lets WLED take over the strip while WLED itself is on. On: while WLED itself is on, follow-me sends nothing and the strip shows WLED's own state. WLED can be turned on from its app, its button or Home Assistant. Follow-me starts again when WLED turns off. Off: follow-me lights the strip when WLED is on or off. | On |
| Follow-Me RGB White | For strips with no white LED only. Sets how the sensor mixes white from red, green and blue: Warm, Neutral or Cool. It applies to Follow-Me Glow and Follow-Me Night Light. | Warm |
## Status
These controls are read-only.
| Control | What it shows |
|---|---|
| Follow-Me Setup | What follow-me needs before it can work. See the table below. |
| Follow-Me Paused | On while WLED itself is on. When the sensor cannot reach WLED, it shows off. |
| Follow-Me Position | Where the followed person is, in steps down from the top edge of the top step. Empty when nobody is followed. It updates every second. |
| Follow-Me Setup value | Meaning | What to do |
|---|---|---|
| Ready | Follow-me is working. | Nothing. |
| Not set up | The setup wizard has not saved a setup to this sensor. | Open the setup wizard and complete it. |
| Radar not found | The sensor cannot find the radar's position readings by name. | Set `radar_x_name` and `radar_y_name` in the device configuration to the names of the radar's target X and Y sensors. See the [README](../README.md#using-a-different-device). |
| WLED not found | The sensor cannot reach WLED at the address saved by the setup wizard. | Make sure WLED is on the network at that address. To change the address, open the setup wizard and go to the Match screen. |
| No web server | The device configuration has no web server, so the setup wizard cannot run. | Add `web_server:` to the device configuration and install it again. |
Until Follow-Me Setup shows Ready, the strip stays dark.