Files
Max Gramser 66b1590184 Download a screen's firmware and put it on from your own computer (0.2.68)
GitHub issue #8: Home Assistant on a server or virtual machine is out of
reach of the screen. New screen and Firmware & USB get a Download choice:
ESP Screens builds the profile's firmware as always and offers ESPHome's
factory image, which the owner flashes with ESPHome Web in Chrome or Edge.

- Firmware: a download job compiles without uploading; only the image of
  the profile's latest successful build in this process is served, a new
  job withdraws it, and a build without a factory image fails.
- USB on the Home Assistant machine stays first in both lists, also before
  a board is plugged in; Download and Later stay chosen once picked.
- The not-yet-in-Home-Assistant card knows a downloaded screen.
- The device name pattern is valid again under Chrome's v flag.
- Docs: README, DOCS, EASY_SETUP, DOCKER, TROUBLESHOOTING. App only;
  firmware stays 0.2.58.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 16:00:06 +02:00

7.7 KiB
Raw Permalink Blame History

Test results app 0.2.68 / firmware 0.2.58 (2026-09-17)

GitHub issue #8 asked for a firmware download, because Home Assistant runs on a Proxmox server and plugging the screen into it is awkward. ESP Screens already builds a profile's firmware with its own ESPHome CLI and flashes it over USB; this release adds a third choice: build, download the file, and put it on the screen from your own computer with ESPHome Web. Max's calls: the three routes are "build and flash on the Home Assistant machine", "build and flash in the browser" (later) and "build and download" (this release); USB on the Home Assistant machine must always stay visible, also before a board is plugged in, "or people think it isn't possible at all". App only. Built on 0.2.67 (6809d3b).

ESPHome, read first

  • ESPHome 2026.6.2 components/esp32/__init__.py get_download_types: the "Factory format (Previously Modern)" is firmware.factory.bin next to firmware.bin, "For use with ESPHome Web and other tools"; the dashboard's download handler serves it from firmware_bin_path.parent. core/config.py: ESPHOME_BUILD_PATH becomes <build path>/<node>, so the app's data/build/<profile> holds <node>/.pioenvs/<node>/firmware.factory.bin (PlatformIO) or <node>/build/firmware.factory.bin (espidf/toolchain.py, native ESP-IDF). Both are searched; the newest wins and links are skipped.
  • ESPHome's own install dialog (esphome_dashboard source maps, install-choose-dialog.ts) offers Wirelessly, Plug into this computer, Plug into the computer running ESPHome Device Builder and Manual download. Browser flashing needs "serial" in navigator and window.isSecureContext (HTTPS); otherwise it falls back to the download plus https://web.esphome.io/?dashboard_install. ESP Screens links to that same address.
  • ESPHome Web's words (esphome/device-builder-frontend src/translations/en.json): "Connect your device below, then click Install to flash your downloaded project", Connect, Install, "Select the factory binary you want to install on your device", and holding BOOT when it fails to initialise. The steps in the window and the docs use those words.

Automated

  • Python (.venv-portal): 386 tests OK (377 on 0.2.67).
    • New tests/test_firmware_download.py (9), with a stand-in ESPHome CLI that writes the factory image where ESPHome 2026.6.2 does: the Download target is checked (CLI, busy slot, unknown targets) before anything is written; the download job compiles without uploading and offers <profile>.factory.bin; a build without a factory image fails instead of offering nothing; the native ESP-IDF layout is found; a new job withdraws the old file until it succeeds, so a failed rebuild offers nothing; Build only offers the file and Check does not; only a file built by this process is served (not one left from before a restart, not another name, not a link); the newest image wins after a node rename; and the HTTP route: CSRF on the create, 400 while building, application/octet-stream, attachment; filename="kitchen.factory.bin", no-store, identical bytes, and the not yet in Home Assistant card turning to "downloaded".
  • node --check screen_manager/app/static/app.js clean.

Real ESPHome builds (2026.6.2, Mac)

Through Firmware.install(target='download') itself, with the app's environment (ESPHOME_BUILD_PATH per profile, PLATFORMIO_CORE_DIR under data), a profile made by installation_yaml and the remote packages from main:

  • CYD (download-check-cyd): success after 132 s, Succeeded: download, the image found at data/build/download-check-cyd/download-check-cyd/.pioenvs/download-check-cyd/firmware.factory.bin, 1,602,272 bytes. Layout checked: padding to 0x1000, bootloader magic 0xE9 at 0x1000, partition table at 0x8000 (otadata, phy_init, app0 at 0x10000, app1 at 0x1D0000, nvs at 0x390000), app at 0x10000: esptool image-info checksum valid, validation hash valid, project download-check-cyd, ESP-IDF 5.5.4; the image contains firmware version 0.2.58. The file ends far below NVS, so flashing it keeps a CYD's touch calibration, as a USB install does.
  • Guition (download-check-guition): success after 126 s, 1,841,760 bytes at the same place. Bootloader magic 0xE9 at 0x0 (ESP32-S3), partition table at 0x8000 (app0 at 0x10000 and app1 at 0x7D0000, 0x7C0000 each; nvs at 0xF90000), app at 0x10000 with a valid checksum and validation hash, project download-check-guition, firmware 0.2.58 inside.

Editor, clicked through

Demo home with the real app code (fake Home Assistant, stand-in CLI with ESPHome's log lines, USB ports from a file), desktop 1280×900 and phone 375×812:

  • New screen without a board: Install via lists USB · no board found on the Home Assistant machine yet first and selects it, Install waits (disabled) and the hint says where to plug in or to choose Download.
  • A board plugged in: the list shows its port within a poll and selects it; Install is enabled. A second board: "More than one board connected". Unplugged while chosen: back to the waiting USB entry.
  • Download or Later chosen: kept while boards come and go. Button: Build & download / Save profile.
  • Build & download: POST firmware/profiles with target: download, "Building firmware…" with the spinner; closed and reopened during the build, the window shows the running build again and ends on the download. Done: "Ready to download.", Download garage-screen.factory.bin (api/firmware/profiles/garage-screen.yaml/download, fetched from the page: 200, application/octet-stream, attachment name, no-store, 1,504,097 bytes; not clicked, so nothing landed in Downloads), the ESPHome Web link to ?dashboard_install with target="_blank", the CYD calibration note, the API key and the pairing steps.
  • A failing build: "That didn't work." / "Build failed" with the error line; Retry posts action: download without a target. Later: "Profile saved." with the new text that points to Firmware & USB and Download.
  • The card under My screens: "Firmware downloaded, not yet in Home Assistant…".
  • Firmware & USB: Wi-Fi / OTA, the USB entry (waiting or the ports, refreshed while open), Download; with Download the host field hides and the button says Build & download; a profile never built shows no link; after the build, Download kitchen-screen.factory.bin appears; back to Wi-Fi / OTA: Build & install with the host field.
  • Phone width: the page does not scroll sideways; the download box wraps.
  • Found on the way: the device name field's pattern="[a-z][a-z0-9-]{0,29}" is invalid under the v flag that current Chrome uses for pattern, so Chrome skipped the check and logged an error. Now [a-z][a-z0-9\-]{0,29}: "Bad Name", "9lives" and 31 characters are flagged while typing, "living-room" and "ok-2" pass.

Home Assistant ingress (read only)

The Yellow runs the store add-on 0.2.66. Its existing zip download (api/claude-skill.zip, the same kind of GET with Content-Disposition) fetched through /api/hassio_ingress/… with an ingress session: 200, application/zip, attachment; filename="esp-screens.zip", no-store, Content-Length kept and a valid zip. The firmware file takes the same path (below Home Assistant's 4 MB limit for a buffered response).

Not tested / for the owner

  • Nothing was flashed. A real flash with ESPHome Web in Chrome, with a file downloaded from the add-on in Home Assistant, is still to do: New screen (or Firmware & USB → Download) → Build & download → Download → web.esphome.io → Connect → Install → select the file. A board keeps its identity when the file comes from its own profile.
  • The first build on the Yellow takes minutes, as with USB.