Give each screen its own YAML override that survives updates (0.2.61)

Override YAML on a screen edits <name>.local.yaml, a package loaded after
the shared board package. New profiles get an empty one; an existing
profile is attached on the first save without reformatting the file. The
editor validates YAML, refuses the managed sections and substitutions,
and Save & check runs ESPHome's full validation of the complete profile.

The example uses !extend: ESPHome appends package lists instead of
merging them by id, so a bare id added a second display without a
platform and failed the build. An override is 12 KB at most and a
too-large body answers as JSON instead of a bare 413. The sidecar is
written before the profile includes it, and a symlinked sidecar is
refused. Firmware stays 0.2.52.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Max Gramser
2026-09-17 08:23:13 +02:00
parent 87b2082f81
commit 8a587303d7
12 changed files with 694 additions and 4 deletions
+48
View File
@@ -0,0 +1,48 @@
# Test results app 0.2.61 / firmware 0.2.52 (2026-09-17)
Max built the Override YAML feature with ChatGPT and asked for a review before release. The feature is app-only:
`installation_yaml` gives every new profile a `local_overrides: !include <name>.local.yaml` package after the shared
board package, `Firmware.save_override` attaches an existing profile on the first save (spliced into `packages:`
without reformatting the rest), and the page edits the sidecar in a dialog with Save and Save & check (ESPHome
`config` of the complete profile). The review changed four things before release:
- **The example was wrong.** ESPHome 2026.6.2 `merge_config` appends package lists (`old + new`); it does not merge
items by `id`. `display: - id: my_display, model: ST7789V` therefore adds a second display without a platform and
`esphome config` fails with "'display' requires a 'platform' key". The example, placeholder and docs now use
`id: !extend my_display`, which edits the display the shared package defines. Checked with the CLI (below).
- **A too-big body was a bare 413.** The app accepts 16 KB request bodies; the override allowed 128 KB, so anything
in between made aiohttp answer a 413 HTML page and the dialog said "That didn't work". The override is now 12 KB at
most, and the guard middleware answers `HTTPRequestEntityTooLarge` as JSON like every other refusal.
- **Order of writes.** The sidecar is written before the profile gets its include, so a profile never points at a
file that isn't there. A profile whose `packages:` is the last section without a trailing newline no longer gets
the include glued to its last line.
- **Symlinks.** A symlinked `<name>.local.yaml` is refused for reading and writing; `profile()` already did that for
profiles. The Save & check poller stops when the dialog closes instead of polling `/api/firmware` for two hours.
## Automated
- Python (`.venv-portal`): `tests/test_overrides.py` 11/11 OK: hidden empty sidecar on create, attach without
reformatting and survive a reload, attach an existing profile, refuse managed sections / managed substitutions /
bad YAML without writing, accept `!extend`, normalise empty text and a missing newline, refuse 12 KB+, refuse a
symlinked sidecar without touching its target, append the include after a `packages:` section without newline,
leave a profile with a foreign `local_overrides` alone; plus the HTTP round trip (CSRF 403, GET, PUT 200, managed
section 400, oversized 413 as JSON, the sidecar stays out of the profile list).
- Full Python suite: 291 tests, 1 failure in `test_tile_icons` (`light: F0335`). That test passes on a clean copy of
HEAD; the failure comes from the binary-sensor-words session's uncommitted firmware headers in the shared working
tree, not from this change.
- `node --check app.js` clean.
## ESPHome CLI (2026.6.2)
- A profile generated by `installation_yaml` for a CYD, with the remote `packages/cyd.yaml` from GitHub and an
override of `display: - id: !extend my_display, model: ST7789V`: **Configuration is valid**, the merged display
shows `model: ST7789V`.
- Minimal local configs: an empty `{}` sidecar is valid; a bare `id:` in the override fails ("requires a 'platform'
key"); `id: !extend` merges into the package's component and a later package wins for scalars (`logger.level`).
## Not tested / for the owner
- Nothing was flashed and the Home Assistant add-on was not rebuilt locally. In the add-on: open a screen, Override
YAML, Use example, Save & check; the status should end in "The complete profile is valid".
- Existing profiles from before 0.2.61 have no include until the first save; the dialog says so ("Ready to attach").
- The example changes the display controller. It is right only for a board that really has an ST7789V.