Files
homeassistant_espscreen/docs/SETTINGS.md
T
Max Gramser b83164d61a Change a screen's settings on the screen itself (0.2.52)
Holding the top bar for about a second and a half opens a settings page on the
screen, with a blue line filling along the top edge while you hold. A built-in
screen.settings tile and the esphome.<screen>_open_settings action open it too.

The page is one constexpr table of rows in settings_screen.h: Brightness,
Night, Screen (clock, back to page 1, swiping, rotation) and This screen (name,
address, firmware, Home Assistant, Restart). Toggles flip on a tap, numbers and
times step with -/+ (a held time walks whole hours), a choice cycles in a chip,
and a row that depends on a switch above it is greyed out. The LVGL objects exist
only while the page is open: +608 bytes of RAM and +10.7 KB of flash on the CYD.
A change is saved, applied and reported through the existing screen_setting
event, so ESP Screens shows the same value within a second.

New setting auto_home (default on, 2 minutes): an open card, the settings page
or a later page goes back to page 1 after that long without a touch, not only on
standby. It travels beside the frozen eleven-key settings block with its own
preference, so older firmware and older apps keep working.

docs/SETTINGS.md is the recipe for adding a setting; the Claude skill explains
the page. Firmware 0.2.44.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 10:05:53 +02:00

99 lines
5.2 KiB
Markdown

# Settings: on the screen and in ESP Screens
Every screen setting lives in two places at once: the **Screen settings** block of the add-on editor, and
the **settings page on the screen itself** (firmware 0.2.44+). This page says what that page is made of,
and exactly what adding one more setting takes.
## What the user sees
Holding the top bar of the overview for about one and a half seconds opens the page; a blue line grows
along the top edge while you hold, and letting go before it finishes cancels. A screen can also carry a
`screen.settings` tile, and Home Assistant can open it with `esphome.<screen>_open_settings`.
The page is a menu of groups, each of which opens a page of its own:
| Group | Rows |
|---|---|
| Brightness | Brightness, Auto standby, Standby after, Standby brightness |
| Night | Night mode, Starts, Ends, Night brightness |
| Screen | Clock, Back to page 1, After, Also on standby, Swipe between pages, Rotation (boards that turn) |
| This screen | Screen, Address, Firmware, Home Assistant, Restart |
Every change is saved on the screen, applied at once, and sent to the add-on as an
`esphome.screen_setting` event, so the editor shows the same value within a second. The add-on remains
the owner: its next layout message repeats every setting, and a screen that was offline catches up then.
## The rules the page follows
- **Two levels, never three.** A group page is the deepest place a setting can live.
- **No free scrolling.** A group that does not fit gets the same `< Previous / Next >` pager as the tile
pages. A 320x240 board shows five rows, a 480x480 board six.
- **A row is a control, not a form.** Toggles flip on tap, numbers and times have `-` and `+`, a choice
cycles through its options in a chip on the right.
- **A row that depends on a switch above it is greyed out, not hidden**, so the page never jumps around.
- **Only settings that belong to this piece of glass.** Tiles, the top bar and pages belong to the editor,
which has a mouse and a keyboard; the screen gets what you want to change while standing in front of it.
## Adding a setting
The example below adds "Beep on touch" (`beep`), a switch.
### 1. Where the value lives
Two homes, and the choice is fixed by history:
- `screen_settings::Settings` in `components/smart_display/screen_settings.h` is the **frozen** block of
eleven values that ESP Screens sends as `settings`. Its format is version 1 and changing it needs a
preference migration *and* firmware-version gating in the add-on, because older firmware refuses a
`settings` object that does not have exactly its own keys. Don't.
- Anything new is a plain value in `settings_screen.h` next to `swipe_pages`, `rotation` and `auto_home`,
with its own preference and its own key in the layout message. That is backward and forward
compatible in both directions: old firmware ignores the key, a new screen with an old add-on keeps its
saved value.
```cpp
// settings_screen.h, next to the others
inline int32_t swipe_pages = 0, rotation = 0, auto_home = 1, auto_home_seconds = 120, beep = 0;
```
Storing it (`components/smart_display/runtime_tiles.h`): extend `HomeTimeout`-style records or add one of
your own, load it in `load_settings()`, write it in `persist_settings()`, and accept the key in
`receive()` next to `auto_home` — validate first, then save.
### 2. The row
One line in the table of the group it belongs to, in `settings_screen.h`:
```cpp
toggle("Beep on touch", [] { return beep; },
[](int32_t value) { beep = value ? 1 : 0; changed("beep", beep); }),
```
`changed(key, value)` saves, applies and reports in one go; `key` must be the add-on's key exactly.
The row kinds are `toggle`, `number` (fixed step, optional unit), `duration` (seconds, steps grow with
the value), `moment` (minutes since midnight, quarters by tap and hours while held), `choice`, `info`
and `action`. A row can carry `shown` (leave it out on boards that lack the hardware) and `enabled`
(grey while the switch it depends on is off).
Watch the count: a group of more than five rows gets a pager on a 320x240 board. Six is the maximum
that still fits a 480x480 board in one go.
### 3. The add-on
- `screen_manager/app/core.py`: one line in `SETTING_RULES` (`'beep': (False, None, None)`), which gives
you validation, storage and the write-back from the screen for free.
- `screen_manager/app/server.py`: add the key to `extra` in `layout_message` and send it as its own key,
next to `auto_home`. Never let it into the `settings` block.
- `screen_manager/app/static/app.js`: one line in `settingDefinitions` for the editor's own control.
- Needs new firmware? `min_firmware()` in `core.py` keeps the screen from being told about something it
cannot do.
### 4. Tests and proof
- `tests/test_settings_screen.cpp` (`clang++ -std=c++17 -Wall -Wextra -Werror -I.`) walks every page and
every row: a new row is checked by the table test as soon as it exists.
- `tests/test_settings_view.py` and `tests/test_layout.py` cover the add-on side.
- Render it before believing it: `.esphome/readme-render/host_build.py <board> --compile` builds the real
firmware for the Mac and `render_settings.py <board>` drives it over the API and saves PNGs of every
page, including the hold gesture, the time picker and the settings tile.