Make daily traffic scale to dozens of screens: incremental sync, ping keepalive, one action per message (0.2.39)
App 0.2.39 / firmware 0.2.33, items 1, 2, 4, 5 and 6 of the 30-screen scaling check. - Only the tiles (and top bar) of changed entities are rebuilt; the screen list is cached until the registry or a screen diagnostic changes; the SSE stream follows. - Sensor history comes from one recorder/statistics_during_period call per window in a background task, with the REST history as fallback per sensor without statistics. - Firmware 0.2.33 answers a keepalive ping with its layout revision; a mismatch or a restart asks for the layout again, everything is repeated hourly as a safety net. - The screen_message API action takes one whole message; the text inbox chunks stay as fallback for older firmware. A repeated unchanged layout keeps the inbox state. - Quiet diagnostics: Opgestart (uptime as timestamp) replaces Uptime, heap every 5 min, setting numbers publish only on change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -371,3 +371,54 @@ domeinen in de hele indeling; de manager stuurt zo'n indeling daarom pas na
|
||||
firmware 0.2.14 (`min_firmware`) en bewaart haar ondertussen. Voorspellingen
|
||||
komen via `weather.get_forecasts` met `return_response`; zonder antwoord blijft
|
||||
de weerkaart de gewone kaart. Geen gewijzigde preferences of sleutels.
|
||||
|
||||
### Compatibiliteit 0.2.39 / firmware 0.2.33
|
||||
|
||||
Opslagversie en tegelprotocol blijven 1; geen nieuwe velden in `screens.json`, geen
|
||||
gewijzigde preferences of sleutels. Alles is additief en per scherm gekoppeld aan de
|
||||
gemelde `Schermfirmware`:
|
||||
|
||||
- **Transport.** Firmware 0.2.33 heeft de API-actie `screen_message` (één string
|
||||
`message`, het complete JSON-bericht, maximaal 4096 bytes). De manager roept
|
||||
`esphome.<apparaatnaam>_screen_message` aan zodra het scherm 0.2.33+ meldt
|
||||
(`TRANSPORT_MIN_FIRMWARE` in `core.py`, `Manager.transport`); daaronder blijven de
|
||||
base64-blokjes in de tekstentiteit `Tegelinstellingen`. De actie publiceert het
|
||||
resultaat op dezelfde inbox-entiteit, dus de status op de beheerpagina blijft gelijk.
|
||||
Het API-frame van ESPHome op de ESP32 is 32 KiB; `receive()` weigert boven 4096.
|
||||
- **Keepalive.** Het layoutbericht krijgt `rev` (twaalf hex-tekens, `core.revision`
|
||||
van het layoutbericht zonder `rev`); oudere firmware negeert het veld. Firmware
|
||||
0.2.33 bewaart de revisie en beantwoordt `{v:1, op:"ping", rev, keepalive}` met
|
||||
`Gesynchroniseerd`/`Tegels laden` (revisie gelijk) of `Indeling opnieuw nodig`
|
||||
(anders, of na een herstart). Een ping ververst het feed-venster (`last_received`)
|
||||
net als een layout. De manager pingt elke `KEEPALIVE_SECONDS` (120 s) en herhaalt
|
||||
alles pas na `FULL_REPEAT_SECONDS` (3600 s), of direct wanneer de inbox een status
|
||||
uit `RESEND_STATES` meldt (`Klaar voor tegelconfiguratie`, `Indeling opnieuw
|
||||
nodig`, `Tegels laden`), met een guard van 120 s na de laatste volledige verzending.
|
||||
Firmware onder 0.2.33 krijgt elke 120 s de volledige herhaling zoals voorheen.
|
||||
Een herhaald, ongewijzigd layoutbericht antwoordt nu `Gesynchroniseerd` in plaats
|
||||
van `Indeling ontvangen`; `diagnostics/send_layout.py` accepteert beide.
|
||||
- **Incrementeel.** `HomeAssistant.dirty` verzamelt de gewijzigde entity-id's;
|
||||
`Manager.sync_one(..., dirty=...)` bouwt alleen die tegels en, als een van hen in
|
||||
de bovenbalk staat, de balk. `dirty=None` (eerste ronde, nieuw register, offline
|
||||
geweest) bouwt alles en stuurt de verschillen; `force=True` stuurt alles. `sent`
|
||||
bewaart per scherm `{'layout','header','states','rev'}`. `Manager.screens()`
|
||||
vervangt `inventory()[0]` in de lus en de updater: alleen de ESPHome-schermentiteiten
|
||||
worden gelezen, gecachet op register-identiteit plus de status van die entiteiten.
|
||||
`inventory()` (volledig) blijft voor de editor en `save()`.
|
||||
- **Historie.** `Manager.history_loop` (eigen taak in `main()`) haalt per venster
|
||||
(1/6/24 uur) één `recorder/statistics_during_period` op (`hour` voor 24 uur,
|
||||
`5minute` daaronder, `types: [mean, state]`; `mean`, anders `state`), valt per
|
||||
sensor zonder rijen terug op `GET /history/period`, en markeert gewijzigde
|
||||
entiteiten dirty. Het `history`-veld in het statusbericht is ongewijzigd (24
|
||||
waarden, `None` tot de eerste). Een sensortegel gaat de eerste keer zonder
|
||||
`history` de deur uit en krijgt hem seconden later; firmware toont dan de grafiek.
|
||||
- **Diagnostiek (firmware).** De sensor `Uptime` (seconden, elke 15 s) is weg;
|
||||
ervoor in de plaats `Opgestart` (`platform: uptime`, `type: timestamp`, device
|
||||
class timestamp, één waarde per opstart; `time:` is al aanwezig). Bewust een nieuwe
|
||||
entiteit: het entity-register van Home Assistant houdt bij de oude de eenheid `s`
|
||||
vast en weigert dan een tijdstempel ("has a unit of measurement ... non-numeric
|
||||
device class: timestamp", gezien op 2026-09-14). De ESPHome-integratie verwijdert
|
||||
de oude `sensor.<scherm>_uptime` zelf zodra het scherm met de nieuwe firmware
|
||||
verbindt. Verder `debug: update_interval` 300 s en de vier template-numbers op
|
||||
`update_interval: never`, gepubliceerd vanuit `apply_screen_settings` als de waarde
|
||||
afwijkt van hun laatste state (dus ook eenmaal na opstarten).
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# Testresultaten app 0.2.39 / firmware 0.2.33 (2026-09-14)
|
||||
|
||||
Dagelijkse efficiëntie met veel schermen: aanpassingen 1, 2, 4, 5 en 6 uit de
|
||||
schaalcheck (incrementeel doorrekenen, historie gebundeld op de achtergrond, keepalive
|
||||
als ping, één API-actie per bericht, rustige diagnostiek). Zie CHANGELOG 0.2.39 en
|
||||
RELEASING "Compatibiliteit 0.2.39".
|
||||
|
||||
## Wat veranderde
|
||||
|
||||
- App: `HomeAssistant.dirty` + `Manager.sync_one(..., dirty)` bouwt alleen gewijzigde
|
||||
tegels en de bovenbalk als die er een toont; `Manager.screens()` (gecachte
|
||||
schermlijst uit alleen de ESPHome-schermentiteiten) vervangt `inventory()[0]` in de
|
||||
lus, de SSE-stream en de updater; `history_loop` + `refresh_histories` (één
|
||||
`recorder/statistics_during_period` per venster, REST-terugval, dirty-markering);
|
||||
`ping()` elke 120 s met `rev`, volledige herhaling per uur of bij een inbox-status
|
||||
uit `RESEND_STATES`; `HomeAssistant.send(..., action)` roept
|
||||
`esphome.<node>_screen_message` aan voor firmware 0.2.33+.
|
||||
- Firmware: `runtime_tiles::layout_rev`, `op: ping`, herhaalde ongewijzigde layout
|
||||
antwoordt `Gesynchroniseerd`; API-actie `screen_message`; `Opgestart` (uptime als
|
||||
tijdstempel) vervangt `Uptime`; `debug` 300 s; instellingsgetallen publiceren alleen
|
||||
bij verandering vanuit `apply_screen_settings`.
|
||||
|
||||
## Geautomatiseerd
|
||||
|
||||
- Python (`.venv-portal`): 130 tests OK, waarvan 9 nieuw in `test_scaling.py`
|
||||
(encode/revisie/actienaam, bucketing, alleen dirty tegels herbouwd en verstuurd,
|
||||
bovenbalk volgt eigen entiteit, `dirty=None` stuurt verschillen, `force` alles,
|
||||
ping-inhoud, oude firmware zonder actie en met volledige keepalive, de echte
|
||||
`run()`-lus: eerste ronde, stille wake, ping na 120 s, hersturen na
|
||||
`Indeling opnieuw nodig` met guard, uurlijkse herhaling, één dirty tegel;
|
||||
schermcache alleen opnieuw bij register of schermdiagnose en met kopieën;
|
||||
statistiekbundel per venster, REST-terugval, dirty alleen bij gewijzigde waarden,
|
||||
cache opgeruimd; `HomeAssistant.statistics` met ms-tijdstempels, `mean`/`state`,
|
||||
lopende uur doorgetrokken).
|
||||
- C++ (clang++ -std=c++17 -Wall -Wextra -Werror -I.): 13/13 PASS (ongewijzigd).
|
||||
- `generate_packages.py --check` groen; bench-kopieën opnieuw gegenereerd.
|
||||
- ESPHome 2026.6.2 compile: `easy-guition-device.yaml` SUCCESS (RAM 32,5%, flash
|
||||
18,6%), `easy-cyd-device.yaml` SUCCESS (RAM 31,5%, flash 77,4%); alleen de bekende
|
||||
enum-waarschuwing op `runtime_tiles.h:596`.
|
||||
|
||||
## Op de bordjes (USB, beide op de bench; HA 2026.9.1 op de Yellow)
|
||||
|
||||
- Firmware rechtstreeks via de ESPHome-API (`screen_message`-actie, beide borden):
|
||||
layout → `Indeling ontvangen`, states → `Tegels laden`/`Gesynchroniseerd`,
|
||||
dezelfde layout nogmaals → `Gesynchroniseerd` (geen wissel), ping met juiste
|
||||
revisie → `Gesynchroniseerd`, verkeerde revisie → `Indeling opnieuw nodig`, ping
|
||||
zonder `rev` → `Fout: ongeldig bericht`, bericht van 3 KB in één actie → verwerkt.
|
||||
- Add-on 0.2.39 als lokale add-on op de Yellow (via de SMB-share en de Supervisor),
|
||||
GitHub-add-on 0.2.38 tijdelijk gestopt, de echte indelingen (CYD 8 tegels met drie
|
||||
sensortegels en weer, Guition 9 tegels) via ingress opgeslagen: beide schermen
|
||||
`Gesynchroniseerd`, Guition-render (`capture_ui.py`) toont Woonkamer met live
|
||||
waarden.
|
||||
- Eerste poging met `Uptime` als `type: timestamp` onder dezelfde naam faalde in HA:
|
||||
"has a unit of measurement ... non-numeric device class: timestamp" (het register
|
||||
houdt eenheid `s` vast). Opgelost met de nieuwe entiteit `Opgestart`; na de flash
|
||||
toont die een tijdstempel en verwijdert HA `sensor.<scherm>_uptime` zelf.
|
||||
- Herstart (USB-flash van beide borden terwijl de monitor liep): inbox
|
||||
`Klaar voor tegelconfiguratie` op t=41 s, volledige herzending op t=42 s (10
|
||||
berichten CYD, 11 Guition), `Gesynchroniseerd` binnen 1 s; daarna pings op
|
||||
t=168 s (beide), ertussen alleen de gewijzigde tegel `sensor.3d_printer_vermogen`.
|
||||
Alle verkeer als `esphome.*_screen_message`, nul `text.set_value`.
|
||||
- Statistieken: twee van de drie CYD-sensoren hebben statistiek (23 uurrijen),
|
||||
`sensor.3d_printer_netfrequentie` is `unavailable` (geen rijen) en loopt via de
|
||||
REST-terugval; geen waarschuwingen in het add-onlog.
|
||||
|
||||
## Lange-termijntest (lokale add-on 0.2.39, beide schermen, HA 2026.9.1)
|
||||
|
||||
- 35 minuten (2100 s) gemonitord via de HA-websocket (`call_service` en
|
||||
`state_changed`): 100 berichten in totaal, 70 statusberichten (alleen de gewijzigde
|
||||
tegels, vooral `sensor.3d_printer_vermogen` op de CYD, dat elke paar seconden
|
||||
verandert, en lampen op de Guition) en 30 pings (15 per scherm); nul
|
||||
layout-herzendingen, nul wissels van de inbox-status, nul beschikbaarheidswissels;
|
||||
geen `text.set_value`. Add-oncontainer: 0,0% CPU, 41 MB. Schermdiagnostiek in HA:
|
||||
alleen heap (per 5 min) en wifi-signaal; de instellingsgetallen bleven stil.
|
||||
- Gevonden en opgelost: na de registerverversing van de app (elke 10 min) werd alles
|
||||
herbouwd zonder verschil, wat de pingtimer resette; de ping kwam dan na ~210 s in
|
||||
plaats van ~120 s. Nu volgt `last` alleen een echte volledige verzending en `pinged`
|
||||
elk verzonden bericht (elk bericht ververst het feed-venster van het scherm).
|
||||
Regressietest in `test_scaling.py`. Add-on herbouwd en nog 700 s gemonitord: per
|
||||
scherm was de langste stilte 122 s (CYD) en 127 s (Guition), ruim binnen het
|
||||
venster van 300 s van de firmware.
|
||||
- Guition-capture na de hele test: pagina 2/2 met live waarden (script "Koppel
|
||||
Speakers" Laatst 20:51, dezelfde minuut als de `media_player.join`-aanroepen in de
|
||||
monitor).
|
||||
- Bekend, niet uit deze ronde: `weather.buienradar` ondersteunt geen uurverwachting;
|
||||
de `weather.get_forecasts`-aanroep daarvoor logt elke 30 minuten een ERROR in de
|
||||
HA-kernlog (gedrag sinds 0.2.23). `Opgestart` toonde op beide borden een
|
||||
tijdstempel dat ongeveer een minuut na het moment van ontvangst ligt (ESPHome's
|
||||
eigen berekening); stabiel, niet aangepast.
|
||||
- Afsluiting: lokale add-on gestopt, GitHub-add-on 0.2.38 weer gestart (werkt ook
|
||||
met firmware 0.2.33: tekstblokjes en volledige herhaling). Max werkt de add-on in
|
||||
de winkel bij naar 0.2.39.
|
||||
Reference in New Issue
Block a user