Add stable CYD firmware, USB calibration wizard and complete setup guide

This commit is contained in:
Max Gramser
2026-09-12 10:18:49 +02:00
parent 1eb65d8f71
commit 94546cf727
43 changed files with 9312 additions and 45 deletions
+81
View File
@@ -0,0 +1,81 @@
# Acceptatietest en oplevering
Noteer datum, bordvariant/MAC, Git-commit, ESPHome-versie, apparaatnaam en de
namen van de twee meetbestanden. Neem geen wachtwoorden in het rapport op.
## Zonder echte HA-acties
1. Kalibreer met [CALIBREREN.md](CALIBREREN.md); flash de uitkomst en voer een
nieuwe, onafhankelijke meting met `verify` uit. Een geslaagde fit alleen
bewijst niet dat de firmwarecoördinaten kloppen.
2. Flash de normale modus. Controleer dat het meetscherm verdwijnt.
3. Controleer elk zichtbaar vak en de randen: geen andere tegel mag reageren.
Tik rustig en snel achter elkaar, maar verwacht geen herhaling binnen de
bewuste debounceperiode. Een veeg mag geen tegelactie achteraf veroorzaken.
4. Bij 1–6 tegels: geen paginaknop. Bij 7–10: herhaal minstens twintig keer
Volgende → tegel → Vorige. De onderste tegel mag niet reageren op de
paginaknop. Open/sluit overlays; een tik daarin mag niet doorlekken.
5. Draai de ingebouwde renderproef via de versleutelde API:
```sh
python diagnostics/run_ui_test.py --host display-keuken.local --name display-keuken
```
Vereist tien geslaagde paginacontroles, vijftig overlaycycli en voortgang
van echte draw-callbacks. Dit test geen fysieke touch of HA-acties.
6. Laat het bord minstens 15 minuten aan. Controleer dat het niet herstart,
dat standby pas na tien minuten zonder aanraking begint en dat de eerste
tik het scherm wekt zonder een apparaat te schakelen.
## Met Home Assistant
Schakel directe acties pas nu in, flash opnieuw en kies veilige testapparaten.
Controleer elke geconfigureerde tegel met zijn echte HA-entiteit:
- Een tik voert precies één bedoelde actie uit; de terugmelding klopt.
- Veranderen vanuit HA wordt ook op het scherm zichtbaar.
- Lichtslider/kleur, climate-setpoint en ondersteunde modi werken waar gebruikt.
- Vacuumacties en snelheden werken waar ondersteund. Noteer ontbrekende functies.
- Na stroomonderbreking komen wifi en HA terug; naam, kalibratie en tegels blijven.
- Na een korte wifi-/HA-onderbreking herstelt de verbinding zonder USB-flash.
Bewaar logs alleen lokaal. Controleer op resets, watchdogmeldingen, herhaalde
connectiefouten en opvallend trage componenten. Een korte renderproef bewijst
geen stabiliteit over dagen; noteer de werkelijk geobserveerde duur.
## Geautomatiseerde ontwikkelchecks
Vanuit de repo, met de Python-omgeving actief:
```sh
python -m unittest discover -s tests -p 'test_*.py'
c++ -std=c++17 -Wall -Wextra -pedantic tests/test_cyd_ui.cpp -o /tmp/test_cyd_ui
/tmp/test_cyd_ui
c++ -std=c++17 -Wall -Wextra -pedantic tests/test_touch_filter.cpp -o /tmp/test_touch_filter
/tmp/test_touch_filter
python -m esphome config device.yaml
python -m esphome compile device.yaml
```
De C++-commando's hierboven zijn voor macOS/Linux met een compiler. Op Windows
kan de developer een beschikbare C++17-toolchain gebruiken. Flash alleen het
gecontroleerde profiel naar het geïdentificeerde bord.
## Opleverrapport
```text
Bord / MAC:
Git-commit / ESPHome-versie:
Apparaatnaam / HA-entiteiten:
Kalibratiemeting + onafhankelijke verificatie:
Renderproef:
Fysieke paginering/touch/standby:
Werkelijke HA-acties:
Geobserveerde stabiele duur:
Beperkingen / nog niet getest:
Lokale profielbestanden veilig bewaard:
```
Geef de eigenaar de drie lokale YAML-bestanden en de meetbestanden via een
passend privé-kanaal. Gebruik voor een andere eigenaar de schone repository
of starter-ZIP, zodat die eigen sleutels en eigen paneelkalibratie krijgt.
+127
View File
@@ -0,0 +1,127 @@
# Een nieuw paneel kalibreren
Dit protocol is voor **320×240, LVGL-rotatie 90°, swap_xy=false,
mirror_x=true, mirror_y=false**. Andere oriëntaties, GT911-touch en andere
controllers vereisen een apart profiel. Verander rotatie of mirroring niet
halverwege de meting.
De filter in deze repo stabiliseert de XPT2046-metingen. Kalibratie corrigeert
vervolgens offset, schaal en scheefstand. Kalibratie repareert geen defect
paneel, losse verbinding, instabiele voeding of willekeurige uitschieters.
## Voorbereiden
1. Gebruik `device.yaml` van `tools/new_device.py`, met een eigen
`calibration.yaml` die begint als identiteit. De persoonlijke correctie
in het historische basisprofiel mag niet worden overgenomen.
2. Controleer de datakabel en de USB-poort met `python -m serial.tools.list_ports`.
3. Flash vanaf de reporoot:
```sh
python -m esphome -s CALIBRATION_ON_BOOT true run device.yaml --device <USB_POORT>
```
4. Controleer fysiek het **donkere scherm met vijf witte + tekens**.
Het blijft aan en de tegelacties zijn hier niet toegankelijk.
5. Stop de ESPHome-loglezer met Ctrl+C. Laat het bord en de USB-kabel zitten.
Slechts één programma mag tegelijk de seriële poort gebruiken.
Wifi/HA zijn voor deze USB-route niet nodig. Als het bord al op wifi staat,
kan het scherm ook via de versleutelde API worden geopend:
```sh
python diagnostics/control_ui.py touch_diagnostics --host display-keuken.local --name display-keuken
```
Dat verandert de startmodus niet. Gebruik voor een nieuwe installatie de
USB-route hierboven, zodat de kalibratiemodus ook na een reset actief blijft.
## Meting A: gegevens verzamelen
```sh
python tools/calibrate.py capture --port <USB_POORT> --device-name display-keuken --output measurements-before.json
```
De wizard begeleidt **één doel tegelijk**:
1. Lees in de terminal welk kruisje aan de beurt is.
2. Druk op Enter en tik daarna alleen dat kruisje **drie keer**.
3. Houd elke tik circa een halve seconde vast en laat tussendoor volledig los.
4. Wacht op de volgende terminalprompt. Ga niet zelf alvast naar een andere hoek.
Volgorde: linksboven, rechtsboven, rechtsonder, linksonder, midden.
Gebruik een geschikte stompe stylus of een kleine, bewuste vingertik; geen
scherpe punt. De doelen staan op `(20,20)`, `(299,20)`, `(299,219)`, `(20,219)`
en `(160,120)`.
De wizard leest alleen touchlogs met `calibration=1`. Hij flasht niets, maakt
geen netwerkverbinding en stuurt geen HA-acties. Een onvolledige meting wordt
niet als geldig bestand opgeslagen. Bij een verkeerde tik: Ctrl+C en opnieuw
beginnen. Gebruik een nieuwe bestandsnaam als een meting al bestaat.
## Een correctie berekenen
```sh
python tools/calibrate.py fit measurements-before.json --output calibration.yaml --replace
```
Het script:
- neemt per hoek de mediaan van de drie ruwe ADC-metingen;
- bepaalt een affine correctie uit de vier hoeken;
- controleert het **niet voor de fit gebruikte middenpunt**;
- weigert te grote fouten (>12 px), spreiding (>18 px) en onbruikbare meetgeometrie;
- bewaart de bestaande `calibration.yaml` als een gedateerde `.bak` voordat
een nieuwe, complete versie wordt geplaatst.
De output bevat alleen de vier basisgrenzen en zes affine coëfficiënten in
een ESPHome-substitutions-map. `device.yaml` importeert deze als calibration-
package. Verander de coëfficiënten niet op gevoel en voeg geen tweede correctie
in de driver toe. De `raw=`-logs bevatten de gefilterde **fysieke ADC-waarden**,
ook als al een correctie is ingesteld; opnieuw kalibreren telt dus niet dubbel op.
Een geslaagde fit op bestaande data is nog geen geslaagde fysieke test.
## Meting B: de geflashte uitkomst onafhankelijk testen
Flash de correctie, nog steeds met het meetscherm:
```sh
python -m esphome -s CALIBRATION_ON_BOOT true run device.yaml --device <USB_POORT>
```
Sluit de loglezer met Ctrl+C en verzamel **nieuwe tikken**:
```sh
python tools/calibrate.py capture --port <USB_POORT> --device-name display-keuken --output measurements-after.json
python tools/calibrate.py verify measurements-after.json
```
`verify` gebruikt de echte `native=`-coördinaten van de firmware, draait die
naar de schermcoördinaten en vergelijkt ze met de doelen. Hij voert **geen
nieuwe fit** uit. Alle vijf punten moeten slagen. Gebruik niet per ongeluk
het bestand van vóór de flash voor deze controle.
Lukt dit niet? Bekijk welk punt faalt, controleer de volgorde/druk, meet opnieuw
en lees [PROBLEMEN.md](PROBLEMEN.md). Verhoog niet alleen de tolerantie om de
test groen te krijgen. Rapporteer een resterende hardwareafwijking eerlijk.
## Terug naar normale bediening
```sh
python -m esphome run device.yaml --device <USB_POORT>
```
Hier is **geen** `-s CALIBRATION_ON_BOOT true` opgegeven. In `device.yaml` blijft
de instelling `false`. Controleer de werkelijke tegels en navigatie volgens
[ACCEPTATIE.md](ACCEPTATIE.md).
Als de kalibratiemodus uitsluitend via de API was geopend, kun je hem sluiten:
```sh
python diagnostics/control_ui.py end_touch_diagnostics --host display-keuken.local --name display-keuken
```
Bewaar beide meetbestanden en `calibration.yaml` bij dit fysieke scherm.
Na vervangen van het paneel opnieuw beginnen; geef alleen de neutrale
starterbestanden aan een volgende eigenaar.
+32
View File
@@ -0,0 +1,32 @@
# Problemen oplossen
| Symptoom | Eerst controleren |
|---|---|
| Geen USB-poort | Datakabel, andere USB-poort, bordvoeding; vergelijk `python -m serial.tools.list_ports` voor/na aansluiten. Installeer zo nodig de driver van de USB-chipfabrikant. |
| Permission denied op Linux | Toegang tot de seriële devicegroep (vaak `dialout`); opnieuw inloggen na een groepswijziging. |
| Poort bezet | Stop ESPHome-logs, IDE-monitor en andere seriële lezers. Eén lezer tegelijk. |
| Upload blijft verbinden | Controleer juiste bord/poort. Houd BOOT ingedrukt tijdens verbinden en laat daarna los als het bord dat vereist. |
| Build faalt | Python 3.11–3.14 en ESPHome 2026.6.2; volledige uitgepakte map, lokale fonts/components aanwezig, internet en schijfruimte. Bewaar eerste echte fout uit de buildlog. |
| Wit/zwart of verkeerd gedraaid beeld | Controleer ILI9341 + XPT2046-variant. Niet willekeurig de pinnen, rotatie of SPI-instellingen van een ander CYD-model kopiëren. |
| Geen meetscherm | De upload moet klaar zijn, niet alleen de build. Flash met `-s CALIBRATION_ON_BOOT true`. Zoek in USB-logs `USB calibration ready`; normaal opstarten toont geen kruisjes. |
| Geen metingen | Vijf kruisjes zichtbaar, andere loglezer dicht, juiste poort. Druk eerst Enter in de wizard en tik daarna drie keer hetzelfde gevraagde punt, met loslaten ertussen. |
| Tik springt naar andere plek | Controleer onafhankelijke `verify`, eigen `calibration.yaml` en vaste oriëntatie. Niet dezelfde tikken gebruiken om zowel te fitten als te verifiëren. |
| Fit meldt spreiding/fout | Meet opnieuw volgens de prompts. Instabiele ADC-metingen niet oplossen door de tolerantie te verhogen; controleer voeding, kabel en touchhardware. |
| Dubbele HA-actie | Controleer zowel touchlogs als HA-automations. Gebruik niet tegelijk directe acties én een automation op de actie-sensor voor dezelfde handeling. |
| Wifi verbindt niet | 2,4GHz, juiste lokale secrets, netwerkbereik. USB-kalibratie heeft HA niet nodig. |
| HA ziet het bord niet | Handmatig IP uit logs gebruiken; poort 6053 bereikbaar, juiste encryptiesleutel, geen gastnetwerkisolatie. |
| Status werkt maar actie niet | HA-optie voor toegestane apparaat-acties, `DIRECT_ACTIONS: "true"`, echte entity-ID en ondersteunde actie controleren. |
| Vacuum/climate deels bruikbaar | Ondersteunde modi/attributen verschillen per integratie; zie TEGELS.md en test dezelfde actie eerst in HA. |
| Verkeerde paginering | `TILE_COUNT` is 1–10; tot zes verborgen knoppen, vanaf zeven twee pagina's. Opnieuw flashen na wijzigen. |
| Vastloper/reset | USB-log bewaren, resetreden/voeding controleren en renderproef draaien. Noteer handeling en tijdstip. |
Voor een USB-log (stop andere lezers):
```sh
python diagnostics/capture_serial.py --port <USB_POORT> --seconds 120
```
De bestaande `CYD_STABILITY.md` en `TEST_RESULTS.md` beschrijven eerder
onderzoek aan één specifiek bord. Hun meetwaarden zijn geen kalibratie voor
een nieuw bord. Begin bij [README.md](../README.md), behoud een werkende
lokale configuratie en verander één oorzaak tegelijk.
+144
View File
@@ -0,0 +1,144 @@
# Tegels instellen voor jouw Home Assistant
Bewerk `device.yaml`, binnen de bestaande `substitutions:`. De basiscode hoef
je voor de onderstaande voorbeelden niet aan te passen. Elke wijziging vraagt
opnieuw bouwen en flashen. Doorloop eerst de [installatie](../README.md).
## Entity-ID's verzamelen
Open in HA **Ontwikkelaarstools → Statussen**. Zoek de gewenste entiteit en
kopieer de volledige ID, bijvoorbeeld `light.keuken`. Controleer status en
attributen. De schermtitel is vrij te kiezen; de entity-ID moet exact kloppen.
Test onder **Ontwikkelaarstools → Acties** de gewenste actie met die entiteit.
Een actie kan het echte apparaat bedienen: kies een geschikte test.
Zie [HA-acties](https://www.home-assistant.io/docs/scripts/perform-actions/).
Maak eerst een lijst met positie, titel, entity-ID, tikactie en lange-drukactie.
Gebruik bestaande HA-scripts/scènes voor meerdere apparaten of complexe logica.
## Posities en grenzen
| Posities | Bedoeld gebruik in deze firmware |
|---|---|
| 1–6 | Hoofdtegels; light, switch, scene, script, fan, cover en climate |
| 6 | Ook de vacuumkaart; de kaart is specifiek met tegel 6 verbonden |
| 7 en 9 | Extra lichttegels met helderheid/kleurbediening |
| 8 en 10 | Extra status-/actietegels; geen volledige numerieke/climatekaart |
`TILE_COUNT: "1"` tot `"10"` bepaalt hoeveel **opeenvolgende** posities zichtbaar
zijn. Tot en met zes zijn Vorige/Volgende verborgen; vanaf zeven staat 1–6 op
pagina één en de rest op pagina twee. Vrij scrollen is vervangen door vaste
pagina's. Laat ongebruikte posities op de neutrale voorbeeldentiteiten staan.
Verander geen rastermaten om tegels toe te voegen.
## Belangrijkste instellingen
| Instelling (`N` = tegelnummer) | Betekenis |
|---|---|
| `TILEN_ENTITY` | Entiteit waarop de actie wordt uitgevoerd |
| `TILEN_STATE_ENTITY` | Entiteit voor status/attributen; meestal dezelfde |
| `TILEN_TITLE` | Korte titel, liefst maximaal circa 12 tekens |
| `TILEN_TYPE` | Domein, bijvoorbeeld `light`, `scene`, `climate` |
| `TILEN_TAP_ACTION` | `auto`, `toggle` of `custom` voor onderstaande voorbeelden |
| `TILEN_TAP_SERVICE` | Expliciete HA-actie bij custom, bijvoorbeeld `script.turn_on` |
| `TILEN_LONGPRESS` | `none`, `slider` of (alleen tegel 6) `vacuum` |
| `TILEN_LONGPRESS_SLIDER` | `auto`; kiest passende regeling op basis van type |
| `TILEN_LABEL_ON/OFF` | Tekst voor eenvoudige aan/uitstatus |
De voorbeeldconfig vult ook de overige velden in. Laat die staan tenzij je
ze bewust gebruikt. `STATE_ENTITY` kan bij een scène/script een echte lamp of
schakelaar volgen; een scène heeft zelf geen betrouwbare aan/uitstatus.
## Voorbeelden
Wijzig deze sleutels in de bestaande map; plak niet nogmaals `substitutions:`.
Dimbare lamp op positie 1 (tik schakelt, lang indrukken opent de regeling):
```yaml
TILE1_ENTITY: "light.keuken"
TILE1_STATE_ENTITY: "light.keuken"
TILE1_TITLE: "Keuken"
TILE1_TYPE: "light"
TILE1_TAP_ACTION: "auto"
TILE1_LONGPRESS: "slider"
```
Een niet-dimbare lamp/schakelaar krijgt `LONGPRESS: "none"`. Kleurbediening
vereist dat de lamp de betreffende kleurmodus ondersteunt.
Scène op positie 3:
```yaml
TILE3_ENTITY: "scene.avond"
TILE3_STATE_ENTITY: "light.keuken"
TILE3_TITLE: "Avond"
TILE3_TYPE: "scene"
TILE3_TAP_ACTION: "auto"
TILE3_LONGPRESS: "none"
```
Script op positie 4:
```yaml
TILE4_ENTITY: "script.alles_uit"
TILE4_STATE_ENTITY: "script.alles_uit"
TILE4_TITLE: "Alles uit"
TILE4_TYPE: "script"
TILE4_TAP_ACTION: "auto"
TILE4_LONGPRESS: "none"
```
Airco op positie 5 (lang indrukken opent climate):
```yaml
TILE5_ENTITY: "climate.woonkamer"
TILE5_STATE_ENTITY: "climate.woonkamer"
TILE5_TITLE: "Airco"
TILE5_TYPE: "climate"
TILE5_TAP_ACTION: "toggle"
TILE5_TAP_SERVICE: "climate.toggle"
TILE5_LONGPRESS: "slider"
```
Controleer `min_temp`, `max_temp`, `target_temp_step`, `hvac_modes` en de
ondersteunde fan-/swingmodes in HA. Deze kaart is primair voor een **enkel
setpoint**, niet een thermostaat die uitsluitend een temperatuurinterval
gebruikt. Test de modi van jouw integratie afzonderlijk; een andere airco
kan andere mogelijkheden hebben.
Robotstofzuiger op positie 6 (tik start; lang indrukken opent de kaart):
```yaml
TILE6_ENTITY: "vacuum.robot"
TILE6_STATE_ENTITY: "vacuum.robot"
TILE6_TITLE: "Stofzuiger"
TILE6_TYPE: "vacuum"
TILE6_TAP_ACTION: "custom"
TILE6_TAP_SERVICE: "vacuum.start"
TILE6_LONGPRESS: "vacuum"
```
De vacuumkaart gebruikt start/pauze/stop/terugkeren/lokaliseren en de
snelheidsnamen `quiet`, `balanced`, `turbo`, `max`. Vergelijk deze met de
ondersteunde acties en `fan_speed_list` in HA. De snelheidsknoppen moeten in
de basiscode aangepast worden als jouw integratie andere namen verwacht.
Dit is geen universele kaart voor ieder robotmodel.
## Acties inschakelen en controleren
Zet na kalibratie en HA-koppeling `DIRECT_ACTIONS: "true"`. Geef in de
ESPHome-integratie toestemming voor Home Assistant-acties. Gebruik geen
HA-automation die dezelfde schermactie daarnaast nogmaals uitvoert; dat kan
een dubbele toggle veroorzaken. Bij `DIRECT_ACTIONS: "false"` kan de
actie-sensor nog gebeurtenissen publiceren voor eigen automations.
Flash `device.yaml` en test één tegel tegelijk: juiste status, juiste fysieke
actie, terugmelding vanuit HA en lange druk. Controleer ook dat externe
wijzigingen in HA op het scherm verschijnen. Voer daarna de
[acceptatietest](ACCEPTATIE.md) uit.
Extra iconen vereisen een glyph in de `materialdesign_icons`-fontlijst. De
bundel bevat de fonts lokaal. De oudere uitgebreide
[TILE_CONFIGURATION.md](../TILE_CONFIGURATION.md) beschrijft ook het oude
scrollprofiel; gebruik die niet als hardware-/layoutinstructie voor dit bord.