Files
homeassistant_espscreen/AGENTS.md
T
Max Gramser 3b15e7f7a3 Build the screens with ESPHome 2026.9 and keep its build memory in the app's own storage, give the CYD 94 KB more room, and stop a timer from counting one second too many (0.2.89)
The add-on ships ESPHome 2026.9.0: it builds an ESP32 with ESP-IDF itself
and keeps a compiler cache. firmware.py gives the CLI its own storage in
/data (ESPHOME_DATA_DIR /data/esphome, which the ESPHome Device Builder no
longer wipes on start; ESP-IDF and ccache in /data/idf, at most 1 GB;
compilers limited to the core count as PlatformIO ran them), removes the
unused PlatformIO once before the first ESP-IDF build, and leaves the new
folders out of backups.

Firmware 0.2.75: assertion_level SILENT in every board's esp32 block, the
core logs from INFO, and clock_parts() in runtime_model.h replaces sscanf.
timer_left() caps a running timer at its duration (the screen's clock runs
up to a second behind Home Assistant's). The packages keep min_version
2026.6.2, the top-level online_image and OTA passwords for new screens, so
an add-on or Device Builder that isn't updated yet keeps building every
screen; CI now builds both boards with the add-on's ESPHome and with
min_version. ESP-IDF's error names stay on, and build_flags stay under
platformio_options, because ESPHome 2026.9's LVGL reads only those.

tools/check.sh: 478 Python tests, 19/19 C++, editor; --firmware PASS with
ESPHome 2026.6.2 (CYD 87.7 %), 2026.8.1 (88.3 %) and 2026.9.0 (86.4 %,
was 91.5 %). Both bench screens OTA'd and watched for half an hour;
ESP Screens as a local add-on on the Yellow built both profiles
(CYD 1,037 s first build, 41 s unchanged). Details:
docs/TEST_RESULTS_0289.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 12:35:49 +02:00

7.2 KiB
Raw Blame History

Easy Setup and releases

The preferred route for new users is docs/EASY_SETUP.md: ESP Screen Manager plus remote ESPHome packages. No token or blueprint needed. Tiles live in the persistent add-on data; Wi-Fi/API/OTA stay in the device's own ESPHome YAML. Read docs/RELEASING.md before publishing updates. Main distributes both boards. Every push to GitHub is a release: always also bump the add-on version in screen_manager/config.yaml (with a CHANGELOG line), otherwise HA won't see an update. A screen's YAML is packages/core.yaml (shared by every board) plus one file under packages/boards/; packages/.yaml and the two profiles in the root only include them. Read docs/PROFILES.md before touching them: a board-dependent number is a ${NAME} in the board file, board-only code inside a shared lambda is a hook substitution there, and tools/check_packages.py (run by tools/check.sh) keeps the boards complete. A screen gets its tiles from the add-on while it runs: every card works in all 48 positions (eight pages of six, firmware 0.2.62+), and no Home Assistant entity belongs in a board profile. Preserve the data schema, protocol compatibility, unique keys, and CYD preferences. Test updates against existing data. Don't publish an unknown storage version without a migration. Production Ingress needs no long-lived token or public port.

Guition board

The Guition 4848S040 has its own board file packages/boards/guition-4848s040.yaml with 480×480, ST7701S RGB, and GT911 (guition-4848s040.yaml in the root only includes it). Read docs/GUITION.md. Don't carry over the CYD layout or the XPT2046 calibration. Verify touch with tools/verify_gt911.py and keep the CYD regressions green. Don't configure wallbox relays as part of display support.

Working instructions for LLMs and developers

This project drives two boards: the CYD ESP32-2432S028 with ILI9341 + XPT2046 (320×240, LVGL 90°) and the Guition above. Read README.md, README_EXTENDED.md and docs/ before installing. The owner can physically tap; an agent cannot replace that with software coordinates.

Installing a new screen

  1. Install it from ESP Screens (docs/EASY_SETUP.md): the add-on writes the screen's own ESPHome YAML with its name, Wi-Fi reference and unique keys, and flashes it over USB. Identify the USB port and board variant first, and check whether a profile for this screen already exists; never overwrite a working one. The add-on builds with ESPHome 2026.9.0 (screen_manager/Dockerfile, Python 3.12-3.14); the packages also build with their min_version (2026.6.2). Don't show keys in logs or chat.
  2. CYD: the screen shows its calibration on first boot; the owner taps the crosshairs. tools/calibrate.py with docs/CALIBRATING.md is the USB route for a panel that needs measuring; ask for physical taps per target, and wait for confirmation that the measurement screen is visible. A successful build is not a flash. Guition: GT911 reports pixels; verify with tools/verify_gt911.py, no ADC calibration.
  3. Pair with the owner's own Home Assistant through the ESPHome integration. Read real entity IDs and supported attributes; don't make up entities.
  4. Choose the tiles in ESP Screens. Don't test real device actions without the owner's permission, and report which checks were actually carried out, the limitations, and how long the screen stayed up.

Owner's machine

On the owner's machine, git-ignored .esphome/owner-access.md says how to reach his Home Assistant and screens for lookups and tests. If that file is missing you are not on his machine: ask, don't guess.

Code and regressions

  • Keep the shared UI in packages/core.yaml and a board's hardware and sizes in its file under packages/boards/; personal data belongs in the gitignored local profiles.
  • The editor is web/ (Vue 3 + Vite, TypeScript; app 0.2.73+). screen_manager/app/static is its build output: change web/src, run cd web && npm test && npm run build, and commit both. Keep every URL the page asks for relative (api/...), so it works behind Home Assistant's ingress path. Tests read the source through tests/editor_sources.py; docs/RELEASING.md "Local development" has the dev-server recipe.
  • Colours live in one table: components/smart_display/theme.h (firmware 0.2.54+). Every role has a light and a dark value, board profiles name paints (styles: paint_card) instead of writing a colour, and firmware code asks for a role (theme::color(theme::INK)). Never write a hex colour in a profile or another header; docs/THEME.md is the recipe, tests/test_theme.py and tests/test_theme.cpp guard it.
  • Screen settings live in one table: components/smart_display/settings_screen.h draws the page on the screen, SETTING_RULES in the add-on validates the same keys. Firmware 0.2.49+ owns them: every writer (the page, the entities in packages/core.yaml) goes through settings_screen::set(), and the add-on changes them through the entities in SETTING_ENTITIES, never through the layout message. docs/SETTINGS.md is the end-to-end recipe for adding one; never widen the eleven-key settings block older firmware insists on.
  • Preserve fixed pages, hidden navigation at six tiles or fewer, and a minimum default standby of 600 seconds. Don't reintroduce free scrolling without physically testing for touch/navigation regressions.
  • Preserve the touch filter and event guard before actions; calibration processes filtered physical ADC values. Don't apply the affine correction twice, in both the driver and the UI.
  • The calibration wizard assumes swap_xy=false, mirror_x=true, mirror_y=false, and LVGL 90°. A changed orientation also requires a new projection/tests.
  • Run tools/check.sh on code changes (the Python tests, every C++ test, the package check, the icon generator's check, the editor's tests, types and build); on a firmware change also tools/check.sh --firmware, which compiles both boards and applies the CYD's flash budget (docs/RELEASING.md step 2). CI runs the same script. Firmware tests and hardware acceptance are different checks.
  • diagnostics/run_ui_test.py renders without HA actions; don't touch the screen during that test. Use --name for the expected device identity. diagnostics/send_layout.py pushes a demo layout with every card type to a screen via the API inbox (no HA actions); the manager restores the real layout within ~25 s. Guition: capture_ui.py saves the LVGL render as a PNG. Without a screen: tools/render_topbar.py renders the real top-bar code for both boards via the ESPHome host + SDL2 to .esphome/render-topbar/out/sheet.png.
  • Share through Git. Don't stage secrets, measurements, binaries, logs, build caches, or local device profiles.
  • No automatic firmware upload to an arbitrary connected port. With multiple boards, first determine the intended port.
  • Profiles with the same DEVICE_NAME share .esphome/build/<name>. Never compile or upload them concurrently; check the firmware.bin path in the upload log, and then the compile time via device_info. A wrong profile knocks the screen out of ESP Screen Manager.

Historical diagnostics are background context, not proof that a new panel works correctly. During onboarding, don't make claims about physical tests that weren't actually performed.