From b327010025269afbc6eecee7150130470da894ab Mon Sep 17 00:00:00 2001 From: Max Gramser Date: Sat, 12 Sep 2026 18:48:49 +0200 Subject: [PATCH] Add readable pastel tile backgrounds and refresh setup documentation --- README.md | 137 +++++++++++++++++++++-- components/smart_display/runtime_model.h | 2 +- components/smart_display/runtime_tiles.h | 23 ++-- components/smart_display/tile_palette.h | 19 ++++ docs/EASY_SETUP.md | 108 +++++++++--------- docs/GUITION.md | 15 +-- docs/RELEASING.md | 10 ++ docs/TEST_RESULTS_0210.md | 24 ++++ guition-4848s040.yaml | 2 +- home-like-2432s028.yaml | 2 +- packages/cyd.yaml | 2 +- packages/guition.yaml | 2 +- screen_manager/CHANGELOG.md | 6 + screen_manager/app/core.py | 18 ++- screen_manager/app/server.py | 7 +- screen_manager/app/static/app.js | 25 ++++- screen_manager/app/static/style.css | 10 ++ screen_manager/config.yaml | 2 +- tests/test_tile_palette.cpp | 9 ++ tests/test_tile_palette.py | 39 +++++++ 20 files changed, 370 insertions(+), 92 deletions(-) create mode 100644 components/smart_display/tile_palette.h create mode 100644 docs/TEST_RESULTS_0210.md create mode 100644 tests/test_tile_palette.cpp create mode 100644 tests/test_tile_palette.py diff --git a/README.md b/README.md index 0203173..a0c0ace 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,132 @@ # Home Assistant ESP Screens -**Nieuw scherm installeren? Begin met [Easy Setup](docs/EASY_SETUP.md).** -Installeer ESP Screen Manager in Home Assistant, download de YAML voor CYD of -Guition, bouw en flash vanuit dezelfde app via USB op je Raspberry en kies je tegels in de beheerpagina. -Zoeken op entiteit/apparaat/ruimte, slepen, opslaan — zonder opnieuw flashen. +Een Home Assistant-bedieningsscherm dat je zelf indeelt. **ESP Screen Manager** +beheert je tegels én bouwt en installeert de ESPHome-firmware vanuit Home Assistant. +Geen blueprint, MQTT of long-lived token nodig voor normaal gebruik. -Updates van de app behouden je indelingen. Nieuwe firmware installeer je via -ESPHome OTA met behoud van je eigen naam, wifi en sleutels. -Zie [de nieuwe kaarten, inspector en firmwarepagina](docs/WHATS_NEW_020.md) en -[updates publiceren](docs/RELEASING.md). +**Nieuw scherm? Volg de [complete installatiehandleiding](docs/EASY_SETUP.md).** +Voor elke nieuwe gebruiker en elk nieuw apparaat maak je een eigen profiel. -De handleiding hieronder blijft beschikbaar voor handmatige installatie via een -computer. Voor de handmatige Guition-route: [Guition](docs/GUITION.md). +## Ondersteunde schermen + +| Scherm | Resolutie | Display / touch | +| --- | --- | --- | +| CYD ESP32-2432S028 | 320 × 240 | ILI9341 / resistieve XPT2046 | +| Guition ESP32-S3-4848S040, 4 inch | 480 × 480 | ST7701S RGB / capacitieve GT911 | + +Gebruik deze exacte bordvarianten: gelijkende productnamen kunnen andere +controllers of aansluitingen hebben. Wallbox-relais worden niet aangestuurd. +De firmware en ingebouwde CLI zijn getest met **ESPHome 2026.6.2**. + +## Wat je kunt instellen + +- **Tot twintig tegels**, verdeeld over maximaal vier vaste pagina's met zes + tegels. Zoek op entiteit, apparaat of ruimte en sleep om te ordenen. +- **Instellingen per tegel:** eigen naam, klikgedrag, een kleine slider waar + ondersteund, of een grote waarde voor bijvoorbeeld temperatuur en verbruik. +- **Pastel achtergronden per tegel:** kies rood voor een alles-uit-script, + groen voor alles-aan, of een andere kleur. Titel en status blijven donker en + leesbaar. De kleur verschijnt ook in het schermvoorbeeld; **Standaard** herstelt + de normale kleuren. Vereist firmware 0.2.10 of nieuwer. +- **Lampbediening:** helderheid, regenboogkleur en wittemperatuur volgens de + mogelijkheden van de lamp. Open de detailbediening met een lange aanraking. +- **Meer kaarten:** climate, vacuum, fan, cover, media player, sensoren, + select/input_select, number/input_number, schakelaars, scènes, scripts en + buttons. Een sensor kan een historiekaart voor 1, 6 of 24 uur openen. +- **Scherminstellingen:** standby-tijd, normale en gedimde helderheid, + nachturen, klok, terug naar de hoofdpagina en optioneel swipen tussen pagina's. +- **Guition-rotatie:** 0°, 90°, 180° of 270°, direct vanuit de beheerpagina. + De native LVGL-rotatie draait beeld en touch samen. De CYD behoudt zijn vaste + oriëntatie en eigen kalibratie. +- **Inspector:** controleer entiteiten, status en configuratie in ESP Screens. + Actiefeedback laat zien dat een opdracht onderweg is. + +Functies hangen af van de mogelijkheden die Home Assistant voor een entiteit +meldt. De app moet blijven draaien om de schermen van actuele gegevens te voorzien. + +## Installeren vanuit Home Assistant + +Voor Home Assistant OS met Apps/Add-ons op **aarch64 of amd64**: + +1. Open de appwinkel en voeg deze repository toe: + `https://github.com/MaxGramser/homeassistant_espscreen`. +2. Installeer **ESP Screen Manager**, start de app en open **ESP Screens**. + ESPHome Device Builder is optioneel: de ESPHome-CLI zit al in deze app. +3. Kies **Nieuw scherm**, selecteer CYD of Guition en geef een unieke naam. + Gebruik **Bewaar profiel in ESP Screens**. Bestaande `wifi_ssid` en + `wifi_password` in ESPHome `secrets.yaml` worden hergebruikt; bij een verse + installatie vraagt de wizard de wifi eenmalig. API- en OTA-sleutels worden + uniek aangemaakt en in je eigen apparaat-YAML bewaard. +4. Sluit het scherm met een USB-datakabel aan op de **Home Assistant-machine**. + Open **Firmware & USB**, kies het eigen profiel en de juiste USB-poort en + start **Bouwen & installeren**. Een eerste build kan meerdere minuten duren. +5. **CYD:** doorloop de kalibratie op het scherm. **Guition:** gebruikt GT911 + zonder resistieve kalibratie. Koppel daarna het ontdekte ESPHome-apparaat in + **Instellingen → Apparaten & diensten**. Gebruik bij een sleutelvraag de + `api.encryption.key` uit je eigen YAML. Geef het apparaat toestemming om + Home Assistant-acties uit te voeren. +6. Selecteer het scherm in ESP Screens, kies je tegels en klik + **Opslaan & naar scherm**. Test vervolgens de fysieke bediening. + +Je kunt later vanuit **Firmware & USB → Wifi / OTA** nieuwe firmware installeren. +Gebruik voor een bestaand scherm altijd het bestaande profiel; opnieuw een +installatieprofiel aanmaken genereert nieuwe sleutels. + +## Tegels en kleuren aanpassen + +Open **Tegels instellen**, klik een tegel in het schermvoorbeeld en open +**Bediening & weergave instellen**. Kies bij **Pastel achtergrond** een kleur, +zoals rood of groen. Pas eventueel de naam, klikactie, mini-slider of grote +waarde aan. Klik **Opslaan & naar scherm** om de wijzigingen toe te passen. +Dit vereist na de eerste ondersteunende firmware-update geen nieuwe flash. + +Een kleur is een vaste keuze voor die tegel: hij blijft dus bijvoorbeeld rood +wanneer je het alles-uit-script gebruikt. De entiteitsstatus en actiefeedback +blijven afzonderlijk zichtbaar. + +## Updates en behoud van je instellingen + +| Wijziging | Actie | +| --- | --- | +| Tegels, namen, kleuren, volgorde of scherminstellingen | Opslaan in ESP Screens; geen firmwareflash | +| Nieuwe versie van de beheerpagina | ESP Screen Manager updaten in de HA-appwinkel | +| Nieuwe functie op het fysieke scherm | Bestaand profiel bijwerken via Firmware & USB → Wifi / OTA | + +De eigen YAML en wifi/API/OTA-instellingen blijven in de ESPHome-configmap. +Tegelindelingen en opties staan in de permanente appdata. CYD-kalibratie en +schermvoorkeuren blijven op het apparaat opgeslagen. Updates vervangen deze +gebruikersgegevens niet. Maak wel normale Home Assistant-back-ups en bewaar je +apparaatprofielen; een app verwijderen of flashgeheugen wissen is geen update. + +Zie [releasegeschiedenis](screen_manager/CHANGELOG.md) en +[releases en protocolcompatibiliteit](docs/RELEASING.md). + +## Handleidingen en hulp bij installatie + +- [Complete installatie vanuit ESP Screens](docs/EASY_SETUP.md) +- [Guition-hardware, montage en rotatie](docs/GUITION.md) +- [CYD-kalibratie en USB-diagnose](docs/CALIBREREN.md) +- [Fysieke acceptatietest](docs/ACCEPTATIE.md) +- [Instructies voor developers en LLM's](AGENTS.md) + +Geef een developer of LLM een schone kopie van deze repository en bijvoorbeeld: + +> Lees AGENTS.md, README.md en docs/EASY_SETUP.md. Help me dit CYD- of +> Guition-scherm via USB op mijn Home Assistant te installeren. Identificeer +> het bord en gebruik mijn bestaande profiel als dat er al is. Begeleid +> kalibratie, HA-koppeling, tegelkeuze en fysieke tests. Houd sleutels lokaal +> en geef aan welke controles werkelijk zijn uitgevoerd. + +Een build bewijst niet dat fysieke touch of het paneelbeeld goed is. De eigenaar +moet het beeld controleren en de gevraagde tikken uitvoeren. + +
+Oudere handmatige CYD-installatie via een computer + +Onderstaande route gebruikt het oudere handmatige profiel met maximaal tien +tegels. De positiebeperkingen hiervan gelden niet voor de twintig runtime-tegels +van ESP Screen Manager. Gebruik voor nieuwe installaties bij voorkeur de route +hierboven; de handmatige instructies blijven beschikbaar voor onderhoud. # CYD Home Assistant-bedieningsscherm @@ -234,3 +349,5 @@ Project-, ESPHome-driver- en fontlicenties staan respectievelijk in `LICENSE`, `components/xpt2046/LICENSE` en `fonts/`. Historische borddiagnose staat in [CYD_STABILITY.md](CYD_STABILITY.md); volg voor een **nieuwe** installatie de handleidingen hierboven. + +
diff --git a/components/smart_display/runtime_model.h b/components/smart_display/runtime_model.h index 92a8977..aa251f4 100644 --- a/components/smart_display/runtime_model.h +++ b/components/smart_display/runtime_model.h @@ -36,7 +36,7 @@ struct Tile { std::array history{}; bool has_history = false; float battery = NAN, volume = NAN; - uint32_t supported = 0; + uint32_t supported = 0, background = 0; std::string revision, pending_revision; uint32_t pending_since = 0; bool pending = false, confirmed = false, local_feedback = false; diff --git a/components/smart_display/runtime_tiles.h b/components/smart_display/runtime_tiles.h index 6cffdf7..2f3d7c2 100644 --- a/components/smart_display/runtime_tiles.h +++ b/components/smart_display/runtime_tiles.h @@ -1,5 +1,6 @@ #pragma once #include "runtime_model.h" +#include "tile_palette.h" #include "screen_settings.h" #include "esphome/core/preferences.h" #include "cyd_ui.h" @@ -136,6 +137,7 @@ inline std::string receive(const std::string &payload) { std::string revision = string(root["state"]); serializeJson(a, revision); tile.observe(revision); auto options = root["o"]; + tile.background = tile_palette::color(string(options["background"],16)); tile.tap = string(options["tap"]); if (tile.tap.empty()) tile.tap="auto"; tile.display = string(options["display"]); if (tile.display.empty()) tile.display="standard"; tile.inline_control = string(options["inline"]); if (tile.inline_control.empty()) tile.inline_control="none"; @@ -531,19 +533,20 @@ inline void render(lv_obj_t *room) { auto color=lv_color_hex(accent); if(t.domain()=="light" && on && t.has_hs_color) color=lv_color_hsv_to_rgb(t.hue%360,t.saturation,100); - auto circle_color=available?lv_color_mix(color,lv_color_hex(light_theme?0xFFFFFF:0x263B50),light_theme?38:65):lv_color_hex(light_theme?0xF0F0F0:0x263B50); + bool dark_text=light_theme || t.background!=0; + auto circle_color=available?lv_color_mix(color,lv_color_hex(dark_text?0xFFFFFF:0x263B50),dark_text?38:65):lv_color_hex(dark_text?0xF0F0F0:0x263B50); // Darken the foreground slightly: very pale bulbs still need a visible icon. - auto icon_color=available?lv_color_mix(color,lv_color_hex(light_theme?0x333333:0xFFFFFF),light_theme?205:185):lv_color_hex(0x9E9E9E); + auto icon_color=available?lv_color_mix(color,lv_color_hex(dark_text?0x333333:0xFFFFFF),dark_text?205:185):lv_color_hex(0x9E9E9E); lv_obj_set_style_bg_color(w.slider,color,LV_PART_INDICATOR); - lv_obj_set_style_bg_color(w.slider,lv_color_mix(color,lv_color_hex(light_theme?0xFFFFFF:0x263B50),30),LV_PART_MAIN); - lv_obj_set_style_bg_color(w.tile, lv_color_hex(light_theme ? 0xFFFFFF : (on ? 0xF5F1E8 : 0x526C85)), 0); + lv_obj_set_style_bg_color(w.slider,lv_color_mix(color,lv_color_hex(dark_text?0xFFFFFF:0x263B50),30),LV_PART_MAIN); + lv_obj_set_style_bg_color(w.tile, lv_color_hex(t.background ? t.background : (light_theme ? 0xFFFFFF : (on ? 0xF5F1E8 : 0x526C85))), 0); lv_obj_set_style_border_width(w.tile, 1, 0); lv_obj_set_style_border_opa(w.tile, LV_OPA_COVER, 0); - lv_obj_set_style_border_color(w.tile, lv_color_hex(light_theme ? 0xDDDDDD : (on ? 0xF5F1E8 : 0x9CB3C8)), 0); + lv_obj_set_style_border_color(w.tile, t.background ? lv_color_mix(lv_color_hex(t.background),lv_color_hex(0x000000),220) : lv_color_hex(light_theme ? 0xDDDDDD : (on ? 0xF5F1E8 : 0x9CB3C8)), 0); lv_obj_set_style_bg_color(w.circle,circle_color,0); lv_obj_set_style_text_color(w.icon,icon_color,0); - lv_obj_set_style_text_color(w.title, lv_color_hex(light_theme ? 0x1B1B1B : (on ? 0x172232 : 0xF3F5F7)), 0); - lv_obj_set_style_text_color(w.value, lv_color_hex(light_theme ? 0x616161 : (on ? 0x46525E : 0xF0F4F8)), 0); + lv_obj_set_style_text_color(w.title, lv_color_hex(dark_text ? 0x1B1B1B : (on ? 0x172232 : 0xF3F5F7)), 0); + lv_obj_set_style_text_color(w.value, lv_color_hex(t.background ? 0x46525E : (light_theme ? 0x616161 : (on ? 0x46525E : 0xF0F4F8))), 0); } } @@ -563,6 +566,12 @@ inline bool check_tile_geometry() { fits=fits && value.y2 +#include + +namespace tile_palette { +// Match the editor palette; all backgrounds are chosen for dark text. +inline uint32_t color(const std::string &name) { + if(name=="red")return 0xFADADD; + if(name=="orange")return 0xFFE1C6; + if(name=="yellow")return 0xFFF0C2; + if(name=="green")return 0xD9EEDC; + if(name=="mint")return 0xD5F0EA; + if(name=="blue")return 0xD9EAFB; + if(name=="purple")return 0xE9DDF5; + if(name=="pink")return 0xF7DDEC; + if(name=="gray")return 0xE5E7EB; + return 0; // Automatic/default, including unknown future palette names. +} +} diff --git a/docs/EASY_SETUP.md b/docs/EASY_SETUP.md index 3fa6b77..e6baa2f 100644 --- a/docs/EASY_SETUP.md +++ b/docs/EASY_SETUP.md @@ -1,12 +1,6 @@ -# Installeren vanuit ESP Screens (vanaf 0.2.0) +# Installeren en beheren vanuit ESP Screens -De makkelijkste route is nu één app: **ESP Screen Manager**. Deze kan zelf -ESPHome-profielen bewaren, bouwen en via USB of OTA installeren. Zie de -[complete stappen voor deze route](WHATS_NEW_020.md#firmware-zonder-een-tweede-beheerpagina). -De instructies hieronder blijven bruikbaar als je ESPHome Device Builder wilt -blijven gebruiken. Beide routes behouden dezelfde eigen YAML en secrets. - -# Een nieuw scherm, van USB naar dagelijks gebruik +Een nieuw scherm, van USB naar dagelijks gebruik Met **ESP Screen Manager** kies je je tegels in Home Assistant. Je zoekt op naam, apparaat, ruimte of entity-ID, zet ze in de gewenste volgorde en klikt @@ -14,7 +8,8 @@ op **Opslaan & naar scherm**. Daarna blijft de status automatisch actueel. Je hoeft voor andere tegels **niet opnieuw te flashen**. Dit werkt met Home Assistant OS op een 64-bits Raspberry Pi of een amd64-machine, -ESPHome Device Builder en een van deze exacte schermvarianten: +en een van deze exacte schermvarianten. De ESPHome-CLI zit in ESP Screen Manager; +ESPHome Device Builder is optioneel: | Keuze | Hardware | | --- | --- | @@ -25,63 +20,55 @@ Andere schermen met ongeveer dezelfde naam kunnen andere pinnen hebben. Gebruik het bordprofiel dat bij de hardware hoort. Gebruik een USB-kabel die data ondersteunt. De wallbox-relais worden niet gebruikt. -## 1. Installeer de twee apps +## 1. Installeer ESP Screen Manager 1. Open **Instellingen → Apps → Installeer een app** (in oudere HA-versies: **Instellingen → Add-ons → Add-onwinkel**). -2. Installeer **ESPHome Device Builder**, start deze en zet hem in de zijbalk. - Gebruik ESPHome **2026.6.2 of nieuwer**. De release is met 2026.6.2 getest. -3. Open in de appwinkel het menu rechtsboven → **Repositories**. Voeg toe: +2. Open het menu rechtsboven → **Repositories** en voeg toe: `https://github.com/MaxGramser/homeassistant_espscreen`. -4. Zoek **ESP Screen Manager**, installeer en start deze. Zet **Starten bij - opstarten** en **Tonen in zijbalk** aan. Open de webinterface. +3. Installeer en start **ESP Screen Manager**. Zet **Starten bij opstarten** + en **Tonen in zijbalk** aan. Open de webinterface **ESP Screens**. -De beheerpagina draait binnen Home Assistant en gebruikt je HA-aanmelding. -Je hoeft geen extra gebruiker, MQTT, blueprint of long-lived token in te stellen. -Installeer voor normaal gebruik de GitHub-versie: een handmatig gekopieerde lokale -test-add-on ontvangt geen updates uit GitHub. +Deze app bevat de geteste ESPHome 2026.6.2-CLI en draait binnen je HA-aanmelding. +Een tweede ESPHome-beheerpagina, MQTT, blueprint of long-lived token is niet nodig. +Gebruik de GitHub-versie voor updates; een lokale test-add-on is een andere app. -## 2. Download je eigen installatie-YAML +## 2. Maak en bewaar je eigen apparaatprofiel -Klik in ESP Screens op **Nieuw scherm**. Kies CYD of Guition, een herkenbare naam -en een unieke apparaatnaam zoals `scherm-keuken`. Klik **Maak installatie-YAML**. Gebruik **Kopieer YAML** om de tekst meteen in -ESPHome te plakken, of **Download bestand**. Op een HTTP-verbinding kan Chrome -downloads blokkeren; de kopieeroptie blijft bruikbaar. +Klik **Nieuw scherm**. Kies CYD of Guition, een herkenbare naam en een unieke +apparaatnaam, bijvoorbeeld `scherm-keuken`. Klik **Bewaar profiel in ESP Screens**. -Bij **Bewaar profiel in ESP Screens** controleert de wizard automatisch de bestaande -ESPHome `secrets.yaml`. Zijn `wifi_ssid` en `wifi_password` aanwezig, dan hoef je -geen wifi in te vullen. Alleen bij een eerste installatie zonder secretsbestand -vraagt hij die gegevens één keer. Bestaande secrets worden niet overschreven. +De wizard controleert de bestaande ESPHome `secrets.yaml`. Met `wifi_ssid` en +`wifi_password` aanwezig hoef je geen wifi in te vullen. Alleen als er nog geen +secretsbestand is, vraagt de wizard je 2,4GHz-wifi eenmalig. Een bestaand bestand +met ontbrekende of ongeldige wifi-sleutels moet je eerst herstellen; het wordt +niet stilzwijgend overschreven. -Dit bestand bevat unieke API- en OTA-sleutels. Bewaar het. Maak voor ieder nieuw -scherm een nieuw bestand. Download voor een bestaand scherm niet telkens een nieuw -bestand: daarmee zou je nieuwe sleutels genereren. +Je apparaat-YAML bevat unieke API- en OTA-sleutels. Bewaar dit profiel en gebruik +het opnieuw bij updates. Voor een bestaand scherm telkens een nieuw profiel +maken genereert nieuwe sleutels en is niet de updateroute. -Open **ESPHome Device Builder → Secrets** en vul eenmaal je 2,4GHz-wifi in: - -```yaml -wifi_ssid: "Jouw wifi" -wifi_password: "Jouw wifiwachtwoord" -``` - -Andere bestaande secrets mogen blijven staan. Gebruik geen gedeelde API-sleutel -voor alle nieuwe schermen; de gedownloade YAML bevat al een eigen sleutel. +Wil je ESPHome Device Builder gebruiken, kies dan **Maak installatie-YAML** en +kopieer/download die YAML naar een eigen apparaat daar. Beide routes gebruiken +dezelfde firmwarepakketten. Wifi blijft in ESPHome `secrets.yaml`; API- en +OTA-sleutels staan in het eigen apparaatprofiel. ## 3. Eerste flash via USB op de Raspberry -1. Klik in ESPHome op **New device**, gebruik dezelfde unieke naam en sla de - directe installatie over. Kies zo nodig ESP32 als tijdelijke wizardkeuze. -2. Klik **Edit** bij het nieuwe apparaat. Vervang de **hele inhoud** door je - gedownloade YAML en sla op. Het pakket levert zelf de juiste hardwareconfiguratie. -3. Sluit het scherm met USB aan op de Raspberry waarop Home Assistant draait. -4. Klik **Install → Plug into the computer running ESPHome Device Builder**. - Kies de USB-seriële poort van dit scherm. Bij meerdere schermen: sluit ze voor - de eerste installatie één voor één aan. -5. Wacht op een geslaagde build én upload. De eerste build kan op een Raspberry - lang duren. Laat deze afronden. Het scherm maakt daarna verbinding met wifi. +1. Sluit het scherm met een **USB-datakabel** aan op de machine waarop Home + Assistant draait. Bij meerdere borden: identificeer eerst de juiste poort, + of sluit ze voor de eerste installatie één voor één aan. +2. Open **Firmware & USB** in ESP Screens en kies het zojuist bewaarde profiel. +3. Kies bij **Installeren naar** de USB-poort van dit scherm. +4. Klik **Bouwen & installeren** en wacht op een geslaagde build én upload. + De eerste build kan op een Raspberry meerdere minuten duren. +5. Het scherm herstart en verbindt met wifi. Latere firmware-updates kunnen via + **Wifi / OTA** in dezelfde pagina, met het bestaande profiel. -Een browseroptie **Plug into this computer** bedoelt de computer waarop je browser -draait, niet de Raspberry. Kies die alleen wanneer het scherm aan die computer zit. +Een USB-kabel aan je laptop is niet zichtbaar als USB-poort van de Raspberry. +Gebruik voor die route de ESPHome-CLI op de laptop met je eigen profiel, of de +browserinstallatie van ESPHome Device Builder. De stappen hierboven gebruiken +uitsluitend ESP Screens op de HA-machine. **CYD:** bij de eerste start verschijnt de kalibratie. Tik het zichtbare kruisje drie keer rustig aan, houd elke tik kort vast en volg steeds het volgende kruisje. @@ -112,7 +99,9 @@ domeinfilters met gekleurde iconen. Je kunt maximaal twintig tegels toevoegen. Het schermvoorbeeld toont hun plaats: twee kolommen, zes tegels per pagina. Sleep een tegel naar een andere tegel om te ordenen. Klik op een tegel voor een eigen naam, de pijltjes voor volgorde en **Bediening & weergave instellen**: -klikgedrag, een mini-slider of een grote waarde waar ondersteund. Een lege +klikgedrag, een mini-slider of een grote waarde waar ondersteund. Kies bij +**Pastel achtergrond** een eigen kleur met donkere tekst; **Standaard** herstelt +de normale weergave. Hiervoor is firmware 0.2.10+ nodig. Een lege tegel brengt je naar de zoekbalk; toevoegen vult de eerstvolgende vrije positie. Het voorbeeld toont de indeling, geen live sensorwaarden. Klik **Opslaan & naar scherm** om je wijzigingen door te sturen. @@ -144,7 +133,7 @@ zodra het scherm terugkomt. De app moet blijven draaien voor actuele tegeldata. | --- | --- | --- | | Andere entiteiten, namen of volgorde | Opslaan in ESP Screens | Wifi, sleutels, kalibratie | | Nieuwe beheerpagina/appversie | Appwinkel → ESP Screen Manager → Update | Alle indelingen in `/data/screens.json` | -| Nieuwe schermfunctie/kaart | ESPHome → bestaand apparaat → Install → Wirelessly | Eigen YAML, sleutels en CYD-kalibratie; app stuurt tegels opnieuw | +| Nieuwe schermfunctie/kaart | Firmware & USB → bestaand profiel → Wifi / OTA | Eigen YAML, sleutels en CYD-kalibratie; app stuurt tegels opnieuw | De eigen YAML verwijst naar de firmwarepakketten in `main`. Bij een nieuwe build haalt ESPHome de nieuwste gepubliceerde pakket- en componentcode op. Je vervangt @@ -152,7 +141,7 @@ je eigen YAML dus niet door een nieuw downloadbestand. Wifi, naam en sleutels staan buiten het gedeelde pakket en blijven gelijk. Maak vóór updates een Home Assistant-back-up inclusief ESP Screen Manager en -ESPHome Device Builder. **Verwijderen/herinstalleren** van een app is niet hetzelfde +de eigen ESPHome-configuraties. **Verwijderen/herinstalleren** van een app is niet hetzelfde als updaten; daarmee kun je de gegevensmap wissen. Houd de apparaatnaam en de entity-ID van **Tegelinstellingen** gelijk, zodat de bestaande indeling gekoppeld blijft. @@ -207,7 +196,9 @@ Hierna vragen wijzigingen aan deze instellingen geen nieuwe firmwareflash. | Helderheid nacht | 0–100%, maximaal normale helderheid | 10% | | Klok tonen | Aan/uit | Aan | | Tijdnotatie | 24 of 12 uur, zonder AM/PM | 24 uur | -| Terug naar pagina 1 | Bij standby; anders huidige pagina onthouden | Uit | +| Terug naar pagina 1 | Sluit ook detailmenu’s bij standby | Uit | +| Vegen tussen pagina’s | Native horizontale swipe, firmware 0.2.7+ | Uit | +| Guition draaien | 0°, 90°, 180°, 270°, firmware 0.2.9+ | 0° | Nachturen gebruiken de tijdzone van het ESPHome-apparaat en de tijd uit HA. Zonder geldige tijd gebruikt het scherm de gewone standbyhelderheid; gelijke @@ -226,5 +217,6 @@ Bij oudere firmware toont de beheerpagina dat eerst een update nodig is. De tegels blijven bruikbaar. Handmatige YAML-profielen blijven hun substitutions gebruiken; voor beheer via deze app gebruik je het Easy Setup-pakket. -De gemelde Guition-paneelstrepen worden apart onderzocht. Deze instellingenupdate -wijzigt geen displaytimings of driver en is geen bewezen oplossing voor die strepen. +De huidige Guition gebruikt de native ST7701S-configuratie; zie +[de hardwarevergelijking](GUITION_FACTORY_REFERENCE.md). Instellingen en +tegelkleuren veranderen geen paneeltimings. Controleer beeld en touch fysiek. diff --git a/docs/GUITION.md b/docs/GUITION.md index a7673a1..ead615e 100644 --- a/docs/GUITION.md +++ b/docs/GUITION.md @@ -39,15 +39,16 @@ alleen zichtbaar voor de Guition nadat zijn nieuwe firmware door HA is ontdekt. De CYD blijft op zijn bestaande oriëntatie met zijn eigen kalibratie. Zes tegels van **218 × 108 pixels** per pagina, 12px tussenruimte en een -aparte navigatiestrook. Vanaf zeven tegels verschijnt pagina twee; tot zes -verdwijnt de navigatie. Grotere letters, iconen, dimmers en kleurkeuzes; de -climatekaart heeft een grotere temperatuurweergave. Een egaal blauwgrijze -achtergrond, duidelijk omlijnde blauwe uitgeschakelde tegels en lichte actieve tegels maken -de status herkenbaar. Standby begint na tien minuten zonder aanraking. +aparte navigatiestrook. In ESP Screen Manager passen twintig tegels op maximaal +vier pagina’s; tot zes verdwijnt de navigatie. De huidige interface heeft een +lichtgrijze achtergrond, witte kaarten en gekleurde domeiniconen. Vanaf 0.2.10 kun +je per tegel een pastel achtergrond kiezen met donkere tekst. Standby begint +standaard na tien minuten zonder aanraking en is instelbaar in de beheerpagina. De bestaande tegelacties, climatebediening en vacuumkaart zijn behouden. -De vacuumkaart blijft gekoppeld aan tegel 6. Posities 8/10 zijn eenvoudige -actietegels; zie [TEGELS.md](TEGELS.md) voor de ondersteunde bindingen. +Alle kaarttypen zijn beschikbaar op alle twintig runtime-posities. Alleen in +het oude handmatige profiel blijft de vacuumkaart op tegel 6 en hebben posities +8/10 beperkingen; zie [TEGELS.md](TEGELS.md). ## Nieuwe installatie diff --git a/docs/RELEASING.md b/docs/RELEASING.md index ea9b49f..84502d4 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -111,3 +111,13 @@ De firmware bewaart de hoek als afzonderlijke uint32 op key `0x524F5431`; de bestaande Settings-structuur en CYD-kalibratie blijven ongewijzigd. Alleen de Guition activeert de rotatiecallback. De diagnostische entity `Guition schermtype` maakt deze capability herkenbaar, ook als het scherm offline of hernoemd is. + +### Compatibiliteit 0.2.10 + +`tiles[].options.background` is een optionele paletnaam binnen opslagversie 1. +Op de draad staat dit in het bestaande `o`-object. Oudere firmware negeert het +veld; nieuwe firmware valt bij onbekende namen terug op de normale kleuren. +De app accepteert uitsluitend het lichte palet uit `TILE_BACKGROUNDS`. Een oude +editor die `background` weglaat behoudt de opgeslagen kleur voor dezelfde entity; +expliciet `auto` herstelt de standaard. Geen gewijzigde voorkeurstructuur of +sleutels, geen nieuwe firmwareflash nodig voor latere kleurkeuzes. diff --git a/docs/TEST_RESULTS_0210.md b/docs/TEST_RESULTS_0210.md new file mode 100644 index 0000000..8ea2235 --- /dev/null +++ b/docs/TEST_RESULTS_0210.md @@ -0,0 +1,24 @@ +# 0.2.10 — pastel tegelkleuren en actuele documentatie + +De editor levert negen lichte kleuren plus Standaard. Dezelfde paletwaarden +worden in firmware gebruikt. De gekozen achtergrond blijft vast bij een +statuswisseling; iconen, status en actiefeedback blijven de entiteit volgen. +Titels zijn bij een eigen kleur donker op zowel Guition als CYD. + +## Uitgevoerd + +- 51 Python-tests geslaagd, inclusief overeenkomst tussen editor- en + firmwarepalet, minimaal 7:1 titelcontrast en 4,5:1 statuscontrast, validatie + van kleuren en behoud bij appherstart/opslaan vanuit een oude editor. +- Alle negen C++-testprogramma's geslaagd; JavaScript-syntax gecontroleerd. +- Beide runtimefirmwares gebouwd met ESPHome 2026.6.2 en via OTA op de vooraf + geïdentificeerde Guition en CYD gezet. Eigen sleutels en kalibratie behouden. +- Ook beide handmatige firmwareprofielen bouwen succesvol. +- Op beide schermen met hun bestaande indeling: tien paginacontroles, + vijftig overlaycycli en de slidertest geslaagd. +- De renderdiagnose controleert bij gekleurde tegels ook de werkelijk + toegepaste LVGL-achtergrond en donkere titelkleur. + +De README en Easy Setup beschrijven nu de één-app-route met de ingebouwde +ESPHome-CLI. De oude handmatige CYD-route blijft ingeklapt beschikbaar en wordt +expliciet onderscheiden van de runtime-indeling met twintig tegels. diff --git a/guition-4848s040.yaml b/guition-4848s040.yaml index 276f59f..e86454b 100644 --- a/guition-4848s040.yaml +++ b/guition-4848s040.yaml @@ -1,7 +1,7 @@ # Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911. # Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile. substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.9" + SCREEN_FIRMWARE_VERSION: "0.2.10" DYNAMIC_TILES: "false" DASHBOARD_INBOX_INTERNAL: "true" DEVICE_NAME: "guition-wallbox" diff --git a/home-like-2432s028.yaml b/home-like-2432s028.yaml index 845f24e..29b31ba 100644 --- a/home-like-2432s028.yaml +++ b/home-like-2432s028.yaml @@ -58,7 +58,7 @@ ############################################################ substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.9" + SCREEN_FIRMWARE_VERSION: "0.2.10" DYNAMIC_TILES: "false" DASHBOARD_INBOX_INTERNAL: "true" DEVICE_NAME: "cyd-new" diff --git a/packages/cyd.yaml b/packages/cyd.yaml index 15ce60c..04c3b42 100644 --- a/packages/cyd.yaml +++ b/packages/cyd.yaml @@ -59,7 +59,7 @@ ############################################################ substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.9" + SCREEN_FIRMWARE_VERSION: "0.2.10" DYNAMIC_TILES: "true" DASHBOARD_INBOX_INTERNAL: "false" DEVICE_NAME: "cyd-new" diff --git a/packages/guition.yaml b/packages/guition.yaml index 0503497..37702eb 100644 --- a/packages/guition.yaml +++ b/packages/guition.yaml @@ -2,7 +2,7 @@ # Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911. # Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile. substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.9" + SCREEN_FIRMWARE_VERSION: "0.2.10" DYNAMIC_TILES: "true" DASHBOARD_INBOX_INTERNAL: "false" DEVICE_NAME: "guition-new" diff --git a/screen_manager/CHANGELOG.md b/screen_manager/CHANGELOG.md index c4a03db..383f45e 100644 --- a/screen_manager/CHANGELOG.md +++ b/screen_manager/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.10 + +- Kies per tegel een pastel achtergrond: rood, oranje, geel, groen, mint, blauw, paars, roze of grijs. Standaard herstelt de normale kleuren. De keuze is zichtbaar in het schermvoorbeeld en werkt met donkere tekst op Guition én CYD. +- Tegelkleuren blijven behouden bij appupdates en bij opslaan vanuit een oudere beheerpagina. Installeer firmware 0.2.10 op het scherm om de kleuren weer te geven. +- README en Easy Setup beschrijven de huidige één-app-installatie, twintig tegels, inspector, rotatie en updates via de ingebouwde ESPHome-CLI. + ## 0.2.9 - Guition: kies 0°, 90°, 180° of 270° onder Scherminstellingen. Na opslaan draait de interface direct mee, inclusief touch. De hoek blijft bewaard na herstart; een nieuwe flash per hoek is niet nodig. diff --git a/screen_manager/app/core.py b/screen_manager/app/core.py index 1b743c4..ad8a522 100644 --- a/screen_manager/app/core.py +++ b/screen_manager/app/core.py @@ -10,6 +10,20 @@ REPO = 'https://github.com/MaxGramser/homeassistant_espscreen' REFS = {'cyd': 'main', 'guition': 'main'} ATTRS = frozenset('brightness percentage current_position current_temperature temperature current_humidity min_temp max_temp target_temp_step supported_color_modes hvac_modes hs_color color_temp_kelvin min_color_temp_kelvin max_color_temp_kelvin fan_speed_list unit_of_measurement battery_level fan_speed volume_level media_title options min max step temperature_unit supported_features'.split()) + +TILE_BACKGROUNDS = { + 'auto': {'label': 'Standaard', 'color': None}, + 'red': {'label': 'Rood', 'color': '#FADADD'}, + 'orange': {'label': 'Oranje', 'color': '#FFE1C6'}, + 'yellow': {'label': 'Geel', 'color': '#FFF0C2'}, + 'green': {'label': 'Groen', 'color': '#D9EEDC'}, + 'mint': {'label': 'Mint', 'color': '#D5F0EA'}, + 'blue': {'label': 'Blauw', 'color': '#D9EAFB'}, + 'purple': {'label': 'Paars', 'color': '#E9DDF5'}, + 'pink': {'label': 'Roze', 'color': '#F7DDEC'}, + 'gray': {'label': 'Grijs', 'color': '#E5E7EB'}, +} + # Additive schema 1 extension. An absent object retains old firmware/YAML defaults. SETTING_RULES = { 'standby_enabled': (True, None, None), @@ -72,8 +86,10 @@ def validate_layout(data): item = {'entity': tile['entity'], 'name': name.strip()} if 'options' in tile: options = tile['options'] - if not isinstance(options, dict) or set(options) - {'tap', 'display', 'inline', 'history_hours'}: + if not isinstance(options, dict) or set(options) - {'tap', 'display', 'inline', 'history_hours', 'background'}: raise ValueError('Onbekende tegelinstellingen.') + if 'background' in options and (not isinstance(options['background'],str) or options['background'] not in TILE_BACKGROUNDS): + raise ValueError('Kies een pastel achtergrondkleur uit het palet.') choices = {'tap': ('auto', 'detail', 'toggle', 'none'), 'display': ('standard', 'watch'), 'inline': ('none', 'slider')} domain = tile['entity'].split('.')[0] for key, allowed in choices.items(): diff --git a/screen_manager/app/server.py b/screen_manager/app/server.py index db30be1..19b489c 100644 --- a/screen_manager/app/server.py +++ b/screen_manager/app/server.py @@ -12,7 +12,7 @@ import math from firmware import Firmware from aiohttp import ClientSession, ClientTimeout, WSMsgType, web -from core import discover, installation_yaml, packets, state_message, validate_layout, validate_settings +from core import TILE_BACKGROUNDS, discover, installation_yaml, packets, state_message, validate_layout, validate_settings LOG = logging.getLogger('screen_manager') @@ -191,6 +191,9 @@ class Manager: raise ValueError('Rotatie vereist een Guition met firmware 0.2.9 of nieuwer.') old_tiles = {t['entity']:t for t in self.layouts.get(inbox,{}).get('tiles',[])} for tile in layout['tiles']: + old_options=old_tiles.get(tile['entity'],{}).get('options',{}) + if 'options' in tile and 'background' not in tile['options'] and 'background' in old_options: + tile['options']['background']=old_options['background'] if 'options' not in tile and 'options' in old_tiles.get(tile['entity'],{}): tile['options'] = old_tiles[tile['entity']]['options'].copy() known = {e['id'] for e in self.inventory()[1]} @@ -320,7 +323,7 @@ def create_app(manager, development=False): for screen in screens: screen['layout'] = manager.layouts.get(screen['id'], {'title': 'Thuis', 'tiles': []}) screen['delivery'] = manager.status.get(screen['id'], 'Kies je eerste tegels') - return web.json_response({'csrf': csrf, 'connected': manager.ha.online, 'screens': screens, 'entities': entities}) + return web.json_response({'csrf': csrf, 'connected': manager.ha.online, 'screens': screens, 'entities': entities, 'backgrounds': TILE_BACKGROUNDS}) async def save(request): manager.save(request.match_info['inbox'], await request.json()) return web.json_response({'saved': True}) diff --git a/screen_manager/app/static/app.js b/screen_manager/app/static/app.js index 7768cff..361d986 100644 --- a/screen_manager/app/static/app.js +++ b/screen_manager/app/static/app.js @@ -249,6 +249,8 @@ function renderPreview() { const card = node("button", undefined, "preview-tile"); if (tile) { const name = tile.name || inventory.entities.find(e => e.id === tile.entity)?.name || tile.entity; + const background=inventory.backgrounds?.[tile.options?.background]?.color; + if(background)card.style.backgroundColor=background; card.append(domainBadge(tile.entity), node("strong", name)); card.draggable = true; card.ondragstart = (e) => { dragIndex = slot; e.dataTransfer.setData("text/plain", String(slot)); }; @@ -358,6 +360,27 @@ function renderTiles() { if (!e.target.closest("input, select, button, summary, .tile-options")) options.open = !options.open; }; + const palette = node("fieldset", undefined, "tile-palette"); + palette.append(node("legend", "Pastel achtergrond")); + const swatches = node("div", undefined, "palette-swatches"); + for(const [key, choice] of Object.entries(inventory.backgrounds || {})) { + const button=node("button", undefined, "palette-choice"); + button.type="button"; + button.setAttribute("aria-label", `Achtergrond: ${choice.label}`); + button.setAttribute("aria-pressed", String((tile.options?.background || "auto") === key)); + const sample=node("span", undefined, "palette-sample"); + if(choice.color)sample.style.backgroundColor=choice.color; + else sample.classList.add("palette-auto"); + button.append(sample,node("span",choice.label)); + button.onclick=()=>{ + tile.options={...tile.options,background:key}; + for(const other of swatches.children)other.setAttribute("aria-pressed",String(other===button)); + markDirty();renderPreview(); + }; + swatches.append(button); + } + palette.append(swatches,node("small", "Donkere tekst blijft leesbaar. Kies Standaard voor de normale kleuren. Vereist schermfirmware 0.2.10+.")); + options.append(palette); const controls = {}; const domain = tile.entity.split(".")[0]; const fields = [ @@ -803,7 +826,7 @@ async function inspect(entity) { card.append( node( "small", - `Kleine slider: ${options.inline === "slider" ? "ja" : "nee"} · Weergave: ${options.display === "watch" ? "grote waarde" : "standaard"}`, + `Kleine slider: ${options.inline === "slider" ? "ja" : "nee"} · Weergave: ${options.display === "watch" ? "grote waarde" : "standaard"} · Achtergrond: ${inventory.backgrounds?.[options.background || "auto"]?.label || "Standaard"}`, ), ); $("#inspection-summary").append(card); diff --git a/screen_manager/app/static/style.css b/screen_manager/app/static/style.css index 0333b93..0c9f6be 100644 --- a/screen_manager/app/static/style.css +++ b/screen_manager/app/static/style.css @@ -720,3 +720,13 @@ pre { #tiles > .selected-tile { background: #f8fafc; border-color: #aac4df; } .picker { position: sticky; top: 16px; } @media (max-width: 800px) { .picker { position: static; } } + +.tile-palette { margin: 12px 0; padding: 12px; border: 1px solid #d8dfe5; border-radius: 12px; } +.tile-palette legend { font-weight: 650; padding: 0 5px; } +.palette-swatches { display: grid; grid-template-columns: repeat(auto-fit, minmax(66px, 1fr)); gap: 8px; margin-bottom: 10px; } +.palette-choice { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 6px; color: #1b1b1b; background: white; border: 2px solid transparent; border-radius: 10px; font-size: 12px; } +.palette-choice[aria-pressed="true"] { border-color: #1674ae; background: #edf6ff; } +.palette-choice:focus-visible { outline: 3px solid #1674ae; outline-offset: 2px; } +.palette-sample { width: 36px; height: 28px; border-radius: 7px; border: 1px solid #0002; } +.palette-auto { background: linear-gradient(135deg, #fff 50%, #e5e7eb 50%); } +.tile-palette small { color: #52616e; } diff --git a/screen_manager/config.yaml b/screen_manager/config.yaml index e1063e8..97e1829 100644 --- a/screen_manager/config.yaml +++ b/screen_manager/config.yaml @@ -1,5 +1,5 @@ name: ESP Screen Manager -version: "0.2.9" +version: "0.2.10" slug: esp_screen_manager description: Kies tegels voor je CYD en Guition touchscreen, zonder opnieuw flashen. url: https://github.com/MaxGramser/homeassistant_espscreen diff --git a/tests/test_tile_palette.cpp b/tests/test_tile_palette.cpp new file mode 100644 index 0000000..10e18d2 --- /dev/null +++ b/tests/test_tile_palette.cpp @@ -0,0 +1,9 @@ +#include "components/smart_display/tile_palette.h" +#include +int main() { + assert(tile_palette::color("auto")==0); + assert(tile_palette::color("")==0); + assert(tile_palette::color("unknown-future-choice")==0); + assert(tile_palette::color("red")!=0); + assert(tile_palette::color("green")!=tile_palette::color("red")); +} diff --git a/tests/test_tile_palette.py b/tests/test_tile_palette.py new file mode 100644 index 0000000..d47a00a --- /dev/null +++ b/tests/test_tile_palette.py @@ -0,0 +1,39 @@ +import re +import tempfile +import unittest +from pathlib import Path +import test_portal +from core import TILE_BACKGROUNDS, validate_layout + +def luminance(color): + rgb=[int(color[i:i+2],16)/255 for i in (1,3,5)] + linear=[v/12.92 if v<=0.04045 else ((v+0.055)/1.055)**2.4 for v in rgb] + return sum(v*w for v,w in zip(linear,(.2126,.7152,.0722))) + +class PaletteTests(unittest.IsolatedAsyncioTestCase): + def test_palette_matches_firmware_and_has_readable_text(self): + header=(Path(__file__).resolve().parents[1]/'components/smart_display/tile_palette.h').read_text() + native=dict(re.findall(r'name=="(\w+)"\)return 0x([A-F0-9]+)',header)) + expected={k:v['color'][1:] for k,v in TILE_BACKGROUNDS.items() if v['color']} + self.assertEqual(native,expected) + for color in expected.values(): + for foreground,minimum in (('#1B1B1B',7),('#46525E',4.5)): + self.assertGreaterEqual((luminance('#'+color)+.05)/(luminance(foreground)+.05),minimum) + + async def test_old_editor_preserves_color_and_explicit_auto_clears(self): + with tempfile.TemporaryDirectory() as tmp: + m=test_portal.ManagerTests().setup_manager(Path(tmp)/'screens.json') + layout={'title':'Thuis','tiles':[{'entity':'light.a','options':{'background':'red','inline':'slider'}}]} + m.save('text.screen',layout) + m.save('text.screen',{'title':'Nieuw','tiles':[{'entity':'light.a','options':{'inline':'none'}}]}) + fresh=test_portal.ManagerTests().setup_manager(m.path) + tile=fresh.layouts['text.screen']['tiles'][0] + self.assertEqual(tile['options'],{'background':'red','inline':'none'}) + await fresh.sync_one('text.screen',fresh.layouts['text.screen']) + self.assertEqual(fresh.ha.messages[1][1]['o']['background'],'red') + fresh.save('text.screen',{'title':'Nieuw','tiles':[{'entity':'light.a','options':{'background':'auto'}}]}) + self.assertEqual(fresh.layouts['text.screen']['tiles'][0]['options']['background'],'auto') + + def test_unapproved_colors_rejected(self): + for value in ('#000000','url(test)','unknown',None,{},42): + with self.assertRaises(ValueError):validate_layout({'title':'Thuis','tiles':[{'entity':'light.a','options':{'background':value}}]})