Send one alert to every screen, teach Claude about ESP Screens, and add a Settings page (0.2.45)

- The app listens for the Home Assistant events esp_screens_show_alert and
  esp_screens_dismiss_alert and calls each screen's show_alert/dismiss_alert action,
  screens added later included. Fields are typed like Home Assistant's ESPHome action
  schema; an unusable value is left empty instead of losing the alert.
- Settings → Claude installs an ESP Screens skill for Claude Code in Home Assistant
  (/homeassistant/.claude/skills/esp-screens) or downloads it as a zip for claude.ai.
  It is generated from the alert reference, so fields, colors and icons match the firmware.
- New screen, Firmware & USB, firmware updates, Alerts and Claude move to a Settings view;
  the header keeps one button. Unselected screens in My screens get a light grey card.

App only; firmware stays 0.2.38.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Max Gramser
2026-09-15 14:52:27 +02:00
parent 3f1084a171
commit 4ff0d44312
18 changed files with 1192 additions and 165 deletions
+3 -3
View File
@@ -38,7 +38,7 @@ Use the GitHub version for updates; a local test add-on is a separate app.
1. Connect the screen with a **USB data cable** to the machine running Home
Assistant. With multiple boards: connect them one at a time for the first
installation, or check which port belongs to this screen.
2. Click **New screen**. Choose CYD or Guition and give the screen a name,
2. Open **Settings** at the top right of ESP Screens and click **New screen**. Choose CYD or Guition and give the screen a name,
for example `Kitchen`. The device name (`kitchen`) follows from that; use
**customize** to choose a different one.
3. Wi-Fi: if `wifi_ssid` and `wifi_password` are already in the ESPHome `secrets.yaml`,
@@ -67,7 +67,7 @@ No USB port in the list? A cable plugged into your laptop isn't visible to the
Raspberry Pi. In that case, choose **Later · save profile only**: the profile then
sits in the same folder ESPHome Device Builder uses, so you can open it there
and flash from your browser (**Install → Plug into this computer**), or
install it to the HA machine later via **Firmware & USB**.
install it to the HA machine later via **Settings → Firmware & USB**.
**CYD:** calibration appears on first boot. Calmly tap the visible crosshair
three times, hold each tap briefly, and follow each next crosshair in turn.
@@ -171,7 +171,7 @@ as soon as the screen comes back. The app must keep running for current tile dat
| --- | --- | --- |
| Different entities, names, or order | Save in ESP Screens | Wi-Fi, keys, calibration |
| New management page/app version | App store → ESP Screen Manager → Update | All layouts in `/data/screens.json` |
| New screen feature/card | The **Update** button on the screen, or the **Update automatically every night** checkbox (manually: Firmware & USB → Wi-Fi / OTA) | Own YAML, keys, and CYD calibration; the app resends tiles |
| New screen feature/card | The **Update** button on the screen, or **Update automatically every night** under Settings (manually: Settings → Firmware & USB → Wi-Fi / OTA) | Own YAML, keys, and CYD calibration; the app resends tiles |
The device's own YAML references the firmware packages on `main`. On a new build,
ESPHome fetches the latest published package and component code. So you don't
+20
View File
@@ -176,6 +176,26 @@ icons sit off-center in the browser); run `generate_packages.py` afterward.
The `MDI_GLYPH_*` substitutions are retired: `TILEn_ICON` in manual
profiles must come from the set. No changed preferences or keys.
### Compatibility 0.2.45 (firmware stays 0.2.38)
App only: storage version, tile protocol, preferences and keys are unchanged.
- Alerts for every screen: on connect the app also subscribes to the Home Assistant events
`esp_screens_show_alert` and `esp_screens_dismiss_alert`. The reader only queues them;
`Manager.alert_loop` handles them in arrival order, apart from the sync loop, and calls
`esphome.<node>_show_alert` / `_dismiss_alert` at once on every screen from `discover_screens`
that is online, has a device name and reports firmware 0.2.31+ (one call per node).
`core.alert_data` types the seven fields the way Home Assistant validates ESPHome actions (text,
an int clamped to 0..86400, a bool) and leaves an unusable value empty instead of failing the call.
The log line `<event>: N of M screens (not: …)` names skipped and failed screens.
- `claude_skill.py` builds SKILL.md from the alert reference and `tile_icons`, byte for byte the same
on every call. `POST /api/claude-skill` writes `$HA_CONFIG/.claude/skills/esp-screens/SKILL.md`
(default `/homeassistant`, the start folder of the Claude Code apps) only on request;
`GET /api/claude-skill.zip` returns `esp-screens/SKILL.md` for claude.ai, whose description limit
is 200 characters. The full inventory's `claude_skill` compares the file with the current text.
- Editor: the header tools and the updates block moved into `#settings-view`, shown for the hash
`#settings`; element ids and their handlers are unchanged.
### Compatibility 0.2.44 / firmware 0.2.38
Firmware only: `show_detail()` creates no `detail_status` for a large vacuum card (the hero badge
+55
View File
@@ -0,0 +1,55 @@
# Test results app 0.2.45 (firmware stays 0.2.38, 2026-09-15)
One alert for every screen (`esp_screens_show_alert` / `esp_screens_dismiss_alert`), the Claude skill
(install for Claude Code or download for claude.ai), the Settings page and grey screen cards. See
CHANGELOG 0.2.45 and RELEASING "Compatibility 0.2.45". App only; no firmware or package changes.
## Automated
- Python (`.venv-portal`): 164 tests OK, also in a clean worktree at the release parent with only
this release's changes applied.
- New: `tests/test_alert_broadcast.py` covers field typing, target selection, fan-out, failures,
queue order, and that the reader only queues.
- New: `tests/test_claude_skill.py` covers skill text, YAML examples, zip, install/update and the endpoints.
- New: `tests/test_settings_view.py` covers the header, Settings contents, view switching and the grey cards.
- `node --check app.js` clean.
- No C++ or ESPHome builds: firmware code, board profiles and packages are unchanged.
## Live Home Assistant (owner's HA 2026.9.1, dry run)
- The new `HomeAssistant` and `Manager` code ran from a development machine against the owner's
Home Assistant with a long-lived token. Screen actions were recorded, not sent.
- `POST /api/events/esp_screens_show_alert` with `timeout: "5"`, `flash: "yes"`, `button_text: true`:
- the subscription received it;
- the log said `esp_screens_show_alert: 2 of 2 screens`, with a warning that `button_text` was left empty;
- calls were recorded for `esphome.guition_wallbox_show_alert` and `esphome.cyd_2432s028_show_alert`
with `timeout: 5`, `flash: true`, `button_text: ""`.
- `esp_screens_dismiss_alert` gave both `_dismiss_alert` calls with empty data.
- Home Assistant lists both per-screen actions with the same seven fields.
## Editor (local server with a fake Home Assistant, desktop 1280 px and phone 375 px)
- The header shows one Settings button. `#settings` survives a reload; the header button, "← My screens"
and browser back/forward switch the views.
- Settings → New screen opens and closes the installer. Firmware & USB opens the firmware window
(`GET /api/firmware` 200).
- The nightly update checkbox on/off gives `PUT /api/updates` 200 with both toasts. Update all
(forced to two pending screens) posts `/api/updates/run` with the CSRF header.
- Alerts opens the cheatsheet. "Copy YAML" under All screens copies the event example.
- Claude:
- Install shows the restart toast when the skills folder is new, then "● Installed".
- After a changed skill text it shows "Installed · a newer version is ready" with "Update the skill".
- The zip download returns `application/zip` with `esp-screens/SKILL.md`.
- My screens: the unselected screen sits on the grey card (`#e9ecf1`), the selected one is white.
- No console errors; every API request 200. At 375 px the Settings cards stack, without
horizontal scrolling.
- README images `editor.png` and `editor-settings.png` come from the demo home (`.esphome/readme-render`).
## Not tested / for the owner
- The released app inside Home Assistant (ingress, Supervisor token, `/homeassistant` mount):
- the Install button writing `/homeassistant/.claude/skills/esp-screens/SKILL.md`;
- the zip download inside the HA iframe.
- A real alert on the screens through the event (the dry run did not call the screens).
- Claude Code in Home Assistant picking up the skill and writing the mailbox automation.
- The claude.ai upload of the zip.
Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 KiB

After

Width:  |  Height:  |  Size: 373 KiB