Let the screen own its settings, answer its pings, and show them as cards (0.2.57)
A code check found that a setting changed on a screen could jump back. ESP Screen Manager kept its own copy and sent it with every full update: after a restart of the app or Home Assistant, every hour and after every save. A change it missed while it or Home Assistant restarted came back to the old value, a reported setting was lost when save() refused a layout with a removed entity, and every step of a held - or + on the screen resent the whole screen. Firmware 0.2.49 offers every setting as an entity over the existing preference records (no migration): Night mode, Night starts/ends, 24-hour clock, Back to page 1 and after how long, Back to page 1 on standby, Swipe between pages and, on the Guition, Rotation, next to the four numbers and Auto standby. The settings page and every entity write through settings_screen::set(), which clamps like the page and stores, applies and reports only a real change. screen_message answers a caller that asks with its status and layout revision (api.respond). The settings tile opens without Home Assistant. The app reads and changes the settings of such a screen through its entities and leaves them out of the layout message. Older firmware keeps them with the layout; a setting it reports is stored without the tile check and not sent back. Pings to screens that can answer learn at once whether a tile is missing and resend after 30 s instead of 120 s. Layout sensors come back after a Home Assistant restart, and weather tiles only ask for the forecasts the entity supports. The editor's settings form is now three cards with the rows of the screen's own page; a change applies at once, and an offline screen shows its values as unknown. Checked with 245 Python and 14 C++ tests, generate_packages --check, ESP32 builds of both profiles, host-build API tests on both boards, and a live run against Home Assistant 2026.9.1 with a temporary host device. Firmware 0.2.49. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -122,4 +122,47 @@ int main() {
|
||||
assert(stored == 1 && applied == 1 && last_key == "standby_enabled" && last_value == 0);
|
||||
row_named(screen, "After").write(600);
|
||||
assert(stored == 2 && last_key == "auto_home_seconds" && last_value == 600 && auto_home_seconds == 600);
|
||||
|
||||
// ---- set(): the one path for the rows and for Home Assistant's entities (firmware 0.2.49+) ----
|
||||
// A value the screen already has is not stored, applied or reported: an automation may set it on every change.
|
||||
SetResult result = set("standby_enabled", 0);
|
||||
assert(result == SetResult::same && stored == 2 && applied == 2);
|
||||
result = set("auto_home_seconds", 600);
|
||||
assert(result == SetResult::same && stored == 2);
|
||||
// Every key ESP Screens knows lands on the screen, clamped the way the page steps it.
|
||||
screen_settings::current = screen_settings::Settings{};
|
||||
rotation_supported = true;
|
||||
const struct { const char *key; int32_t value, expected; } cases[] = {
|
||||
{"standby_enabled", 5, 1}, {"standby_seconds", 10, 60}, {"standby_seconds", 999999, 86400},
|
||||
{"brightness", 1, 5}, {"brightness", 250, 100}, {"standby_brightness", 101, 100}, {"night_enabled", 0, 0},
|
||||
{"night_start", -5, 0}, {"night_end", 2000, 1439}, {"night_brightness", 7, 7}, {"clock_24h", 0, 0},
|
||||
{"home_on_standby", 1, 1}, {"swipe_pages", 2, 1}, {"rotation", 100, 90}, {"rotation", 400, 270},
|
||||
{"auto_home", 0, 0}, {"auto_home_seconds", 5, 30}, {"auto_home_seconds", 99999, 3600},
|
||||
};
|
||||
for (const auto &c : cases) {
|
||||
result = set(c.key, c.value);
|
||||
assert(result != SetResult::unknown);
|
||||
if (result == SetResult::changed) assert(last_key == c.key && last_value == c.expected);
|
||||
}
|
||||
assert(screen_settings::current.standby_seconds == 86400 && screen_settings::current.brightness == 100);
|
||||
assert(screen_settings::current.night_start == 0 && screen_settings::current.night_end == 1439);
|
||||
assert(swipe_pages == 1 && rotation == 270 && auto_home == 0 && auto_home_seconds == 3600);
|
||||
assert(screen_settings::current.valid());
|
||||
// A lower brightness pulls both dim levels down, and reports the brightness itself.
|
||||
set("standby_brightness", 60);
|
||||
set("night_brightness", 50);
|
||||
result = set("brightness", 30);
|
||||
assert(result == SetResult::changed && last_key == "brightness" && last_value == 30);
|
||||
assert(screen_settings::current.standby_brightness == 30 && screen_settings::current.night_brightness == 30);
|
||||
result = set("standby_brightness", 90);
|
||||
assert(result == SetResult::same && screen_settings::current.standby_brightness == 30);
|
||||
// What the screen cannot do, or does not know, is refused without a store.
|
||||
const int before = stored;
|
||||
rotation_supported = false;
|
||||
result = set("rotation", 90);
|
||||
assert(result == SetResult::unknown && rotation == 270);
|
||||
result = set("show_clock", 0);
|
||||
assert(result == SetResult::unknown);
|
||||
result = set("beep", 1);
|
||||
assert(result == SetResult::unknown && stored == before);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user