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>
5.2 KiB
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::Settingsincomponents/smart_display/screen_settings.his the frozen block of eleven values that ESP Screens sends assettings. Its format is version 1 and changing it needs a preference migration and firmware-version gating in the add-on, because older firmware refuses asettingsobject that does not have exactly its own keys. Don't.- Anything new is a plain value in
settings_screen.hnext toswipe_pages,rotationandauto_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.
// 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:
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 inSETTING_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 toextrainlayout_messageand send it as its own key, next toauto_home. Never let it into thesettingsblock.screen_manager/app/static/app.js: one line insettingDefinitionsfor the editor's own control.- Needs new firmware?
min_firmware()incore.pykeeps 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.pyandtests/test_layout.pycover the add-on side.- Render it before believing it:
.esphome/readme-render/host_build.py <board> --compilebuilds the real firmware for the Mac andrender_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.