18 Commits

Author SHA1 Message Date
Xandrossian 9857cc3bda Add the Elecrow CrowPanel 7.0" as a third board, and take the packages and the add-on from Gitea (0.2.93)
CI / checks (push) Successful in 12m50s
CI / firmware (add-on) (push) Successful in 18m19s
CI / firmware (min_version) (push) Successful in 17m55s
A board file for the Elecrow CrowPanel 7.0" (DIS08070H, ESP32-S3-WROOM-1-N4R8): 800x480 through mipi_rgb, GT911 on the
ESP32-S3's USB pins (elecrow_usb_phy.h frees them, behind a flag only this board sets), the Guition's vertical sizes
across a wider page, no rotation. Its 4 MB of flash take the CYD's budget: a partition table of the component's
(smart_display: partitions: 4mb_wide_slots, 1,984 KB slots), the icon fonts at 2 bits a pixel and the TLS client only
bring the firmware to 1,865,440 bytes, 91.8 % of a slot, with camera images kept. docs/ELECROW.md has the numbers and
the trade.

The add-on reads a large board's name from the type sensor's value, the editor offers the board under New screen and
draws the wide preview, tools/check.sh builds it with the budget, render_topbar and capture_ui take the panel's size.
Firmware 0.2.79; the CYD image is unchanged (1,633,760 bytes).

This fork builds from gittea.trippedonmy.name/Xandrossian/homeassistant_espscreen: the packages, the fonts, the
component and the add-on repository point there instead of GitHub.
2026-09-20 23:18:01 -07:00
Max Gramser efbab04b39 Show the album cover on a media tile, in the same strip as the live camera pictures (0.2.92)
A single or double-width media player tile takes Display -> Album cover
on a Guition: the cover of what plays in the icon's place, like Home
Assistant's own tile. It rides in the page's strip of 0.2.91: the request
and the answer are the same, a media player is simply among the tiles.
The app fetches a player's picture only when its address changes; a page
with a camera loads at the camera's pace with the cover reused, a page of
media tiles alone loads once, and a new track (the picture's mark in the
state, part of the page's wish) asks again at once. A player without a
picture keeps its icon and is not asked for; the double-width tile keeps
its controls; the tile over the whole page keeps the card's big cover.
Firmware 0.2.78.

Host harness 31 checks (docs/TEST_RESULTS_0292.md). CYD firmware
1,633,760 B, 89.0 %.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-20 13:46:46 +02:00
Max Gramser 306636434b Show a live picture on a camera tile, run an action from the alert button, roll long media titles, and keep full-page tiles in their own colour (0.2.91)
Live picture (issue #4): a camera or image tile on a Guition takes
Display -> Live picture with a pace of 15 or 30 s. The camera tiles of a
page share one download: the screen asks ESP Screens for them together
(esphome.screen_camera with tiles, size and bg) and the app serves one
BMP, a strip of squares with the corners rounded over each tile's own
colour; every tile draws its square out of it with LVGL's image offset
(LV_IMAGE_ALIGN_TOP_LEFT: the default centres a taller source). A third
online_image on the Guition holds the strip; it loads after the alert's
picture, a cover and the camera full screen, never under a card, in
standby or under a finger. The strip is served whole every time: ESPHome's
http_request logs a 304 as a failed request. Firmware 0.2.77.

Alert button: esp_screens_show_alert takes action and data; the app
performs the action once when the button's report (esphome.screen_alert,
ok) comes from any screen. show_alert keeps its seven fields, so every
firmware from 0.2.31 has it.

Media card and full-page media tile: a title or artist line that is too
wide rolls by (LV_LABEL_LONG_SCROLL_CIRCULAR) instead of ending in dots.

Full-page tiles are white or their own pastel like every other tile; the
tint in the state colour of firmware 0.2.62 to 0.2.76 is gone.

Host harness (27 checks) and bench Guition + local add-on on the Yellow:
docs/TEST_RESULTS_0291.md. CYD firmware 1,633,728 B, 89.0 %.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-20 12:47:44 +02:00
Max Gramser 022a384ec3 Say how a screen built outside ESP Screens gets its language
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 22:32:22 +02:00
Max Gramser 125346d94e Notation like Home Assistant, each screen in its own language, and the language in every build
From the end-to-end test on the bench boards and an independent review:
- Units spaced as Home Assistant does (54% / 54 % in German and French, 18°, 21.5 °C), in the firmware and the app.
- Grouping from five digits where the language does (1234 but 12.345 in Spanish, Polish, Portuguese): the layout
  message carries group_min and percent_space; an unknown number style no longer refuses a layout.
- Automatic follows Home Assistant's own language for the clock and numbers, also without a translation (Swedish:
  24 hours, 1 234,5; pt-BR: 1.234,5): regions.json from the CLDR for all 63 languages Home Assistant offers.
- 12-hour clock: the top bar says 3:48 PM, the clock card 3:48 (not 03:48), Last runs follow the clock.
- The climate setpoint font has the decimal comma; the value fonts have ², ³ and µ (m³ was a box).
- Weather days: at most three letters without the dot (mié, sáb, czw); the screen took three bytes.
- Texts fall back per key through the base language (pt-BR -> pt -> en) in the firmware and the app.
- Each screen gets the app's words in the language its firmware speaks; firmware from before the languages gets
  English and its own letters, not boxes.
- set_language re-reads what it writes (indentation, comments, quoted keys, CRLF, !include) and every build writes
  the language first; the 24-hour pin no longer hits a fresh install and waits for the old clock switches.
- Tests: region and notation, plural parity with the C++ rules, set_language edge cases, the pin, PUT /api/language.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 16:52:34 +02:00
Max Gramser c2cf3391d6 Say in the guides that the clock is set for every screen under Language & region
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 14:45:19 +02:00
Max Gramser ff9d3af9f8 Show a spinner while a screen starts and while a camera loads, bring a camera's first picture sooner, and round the alert's camera picture (0.2.87)
Starting screen: until the first layout, render() keeps the status text
("Connecting to Home Assistant", "Waiting for ESP Screens") and a spinner
as one block in the middle of the page; the first layout deletes both.
The room label stays empty meanwhile, and ROOM_NAME defaults to "".

Camera: the full screen shows a spinner instead of "Loading image". The
screen asks when the camera opens and loads a link as soon as it comes
(camera_load, never under a finger) instead of waiting for the 250 ms
tick twice, and online_image reads 16 KB per loop instead of 4 KB. On the
bench Guition with the EZVIZ camera: cold 5.8 -> 4.55 s, warm 3.4 -> 2.06 s.

Alert picture: the image takes the frame's radius (18, the alert card's);
LVGL's software renderer clips it row by row, without a layer.

One spinner_create() makes the busy sheet's, the starting screen's and the
camera's spinner; theme role CAMERA_TRACK colours the camera's ring. The
README gets a row of camera pictures; docs/CAMERA.md, RELEASING.md and
TEST_RESULTS_0287.md describe the measurements.

Checked with tools/check.sh (473 Python tests, 19/19 C++, editor) and
--firmware: CYD 1,678,816 B (91.5 %, +1,312 B), Guition 2,055,280 B
(25.3 %). Host renders of both boards in both looks; four OTA builds on
the bench Guition Wallbox, which runs this firmware.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 08:50:08 +02:00
Max Gramser 311fa2a7fd Show the screens and ESP Screens as they are now in the README pictures (docs only)
Rendered again from firmware 0.2.71 and the editor of 0.2.85 on the demo homes, with the render tooling
brought over to the core and board files of 0.2.84: the tile pages with 0.2.85's colours (a running timer
amber, a docked robot and idle scripts grey, the full-page speaker lit while it plays), the cards with the
icon edges of 0.2.75, and the editor with 48 tiles, the icon-left tiles of 0.2.76, Size and Page in the
tile drawer, Perform action on the curtains as the caption says, and every Screen settings row. The camera
pictures show a free Unsplash photo by Virginia Marinova, credited in the README. The two photos at the top
carry the current firmware on their screen: the page with scenes, scripts, the robot and the table lamp,
and the vacuum card with its cleaning mode.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 00:54:10 +02:00
Max Gramser 6fb60b34d2 Bring the guides up to date with the code of the last releases (docs only)
README_EXTENDED rendered everything from "Direct control" to "Override YAML" as raw text on
GitHub since 0.2.74: the full-page pictures ended without a blank line. It also gains the
media card, Page buttons, the ··· menu's Identify/Copy/Export/Import, Try it, and where
SCREEN_FIRMWARE_VERSION lives now. EASY_SETUP's settings table drops Show clock and gets
Back to page 1; SETTINGS.md points at web/src/store.ts and packages/core.yaml; GUITION.md
had the GT911 mirrored and cache settings that left the profile on 2026-09-12;
TROUBLESHOOTING still named TILE_COUNT and files deleted in 0.2.50; CALIBRATING put
Calibrate touch in ESP Screens instead of Home Assistant. RELEASING gets the compatibility
notes of 0.2.73 to 0.2.85 and the GitHub release step.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 00:11:40 +02:00
Max Gramser 9391d1b0ac Grey out what Home Assistant calls off and colour the rest like Home Assistant, so an airco that is off no longer looks on (0.2.85)
The airco tile stayed orange while the airco was off. The firmware kept its own
short list of what turns grey and gave an off climate Home Assistant's orange,
but Home Assistant has no colour for a climate that is off: its cards fall back
to the inactive grey. Other tiles had the same fault: an off fan, a closed
blind, a docked robot, a player in standby, an idle script, a paused timer and
a camera that isn't streaming all kept their colour.

Tile::active() is now a port of the frontend's stateActive() for the domains a
tile can show, and every tile that is not active is grey. An airco that is off
reads Off, with the room's temperature when the device reports one, as Home
Assistant's tile does. tile_controls::accent() follows stateColorCss(): alarm
binary sensors red, a battery green, orange or red by its charge, a running
script or timer and a streaming camera amber, the weather per condition, the
sun amber and indigo, someone in a zone blue. Scenes, selects, numbers and
sensors keep their own colour per kind. A full-page tile lights up only for
tiles that can be off (Tile::lights_up), and a closed blind's slider keeps its
colour. The top bar's alarm classes are Home Assistant's eleven.

Checked with tools/check.sh (471 Python tests, 19/19 C++ with 58 state cases
and every colour rule) and compiled for both boards: CYD 1,677,488 B (91.4 %,
+576 B), Guition 2,054,640 B (25.3 %).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 23:31:10 +02:00
Max Gramser e7e173d3b7 Give a lamp's modes a page: the effects, palettes, presets, speed and intensity of a WLED behind its colour card, with a drum picker and the effect's name on the tile (0.2.83)
A light that offers effects gets a sparkles key at the top right of its colour
card. It opens a page with a row per thing the lamp offers, all from Home
Assistant: the light's effect and the select entities of its device (a WLED's
colour palette, preset and playlist) with what they are set to, and a slider per
number entity of the device (speed, intensity). Names are Home Assistant's own
English entity translations, icons its frontend's; nothing about a brand is
hardcoded beyond a preferred order of translation keys.

A row opens LVGL's roller with every name Home Assistant lists at that moment,
asked for when the picker opens (esphome.screen_options, answered with
op: options, one page of names per message), the effects alphabetically with
Solid on top. The check key at the top right sends the choice as one action;
the back key sends nothing. A slider sends number.set_value when let go. While
an effect runs, the tile names it instead of the brightness.

Firmware 0.2.70: effects_page.h (built when it opens, gone when it closes),
Extra.effect/option_rows/number_rows, options_request, a hidden roller widget
so ESPHome compiles LVGL's roller, five firmware-only glyphs. App 0.2.83:
light_effects.py, the effect attribute, the device rows in the state message,
card_options_loop. Checked on the host with a virtual finger (35/35 on both
boards) and compiled for both ESP32 boards; CYD 1,675,424 B (91.3 %).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 21:38:20 +02:00
Max Gramser 1a6308aba7 Fix what a full test round of today's releases found: a ticking single clock, a switch that works in standby, no taps from a swipe (0.2.78)
A test and code-analysis round of 0.2.72 to 0.2.76 (suites at every tag, sanitizers, ESP32 and GitHub builds, host
harnesses on both boards, the editor in a browser, best practice checked against ESPHome, LVGL, Home Assistant and
Vue) found these, fixed here with Max's choices for the product questions:

- Firmware 0.2.65: the second hand of a single analog clock moves again; on a page that is one full on/off tile the
  waking push also switches it; on the Guition a flick is never a tap and a finger that slides off a tile doesn't tap
  it; Previous/Next react to a firm press; the same Go to page tile may sit on several pages; a layout the screen has
  no memory for is refused instead of crashing; 64-bit redraw mask for 48 tiles; Montserrat 14 no longer built.
- App: Save refuses a layout too long for one message or too big for eight pages; an offline screen keeps its
  firmware version from the device registry; HA refusals reach the editor; 128 KB requests; changelog out of the
  live stream; cached hashed assets; tini as init and a clean stop; changelog parsing without asterisks or crashes.
- Editor: clicking the open screen keeps unsaved edits, edits during a save stay unsaved, a Page row and phone
  dragging to other pages, repeated page tiles, limits from the server, HA's error messages, a type-checked build.
- tools/check.sh + GitHub Actions + a CYD flash budget; docs match 48 tiles and the new editor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 17:25:23 +02:00
Max Gramser bb25353089 Forty-eight tiles, a tile over the whole page and tiles that go to a page (0.2.74)
Max asked for many more tiles, a tile that takes the whole page as a light
switch you push without looking, and tiles that go to a page. The limit is
one tile per slot of the eight pages, 48, and the firmware keeps its tile
list on the heap sized to the layout (PSRAM on a Guition). A tile's size can
be `full`: one big button that lights up in the state colour while on, or the
double-width card's head with its small slider, direct controls or graph at
the bottom and the value the double-width card had no room for in between;
the clock, the forecast (with an hours strip) and the sun path fill the page.
Navigation tiles are the built-in entities screen.page_1 to screen.page_8:
an arrow or a chosen icon, the name and "Page n", a tap opens that page.
The app sends the three only to firmware 0.2.62+, the editor (the Vue port of
this round by the editor session, 00c9a4e) offers Normal / Double-width /
Full page and "Goes to page", and Claude in Home Assistant gets size: full and
the page tiles. Built-in tiles now send a chosen icon as its codepoint.

Found and fixed by the new host harness before release: the one-second tick
moved the analog clock's second hand (part 18) on a full forecast's hour label
during a page switch and corrupted it. Firmware 0.2.62; both C++ and Python
suites, host harness 37/37 on both boards, hardware pass on both bench boards
in docs/TEST_RESULTS_0274.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 08:44:44 +02:00
Max Gramser 42bf5811f7 Show the settings on the screen, tap actions and Override YAML in the README
The README pictures now match the released screens and ESP Screens: the light pages had the sliders
and clock from before 0.2.43, the editor showed firmware 0.2.34, and the vacuum and climate cards
carried Dutch names. New pictures show the settings page on the screen with Dark mode, the Screen
settings cards, Perform action in the tile settings and Override YAML; the full reference gets the
same and short notes on tap actions, Home Assistant's words and icons, and Override YAML.

Rendered from the host firmware and the real add-on on the demo home, like the earlier pictures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 16:04:37 +02:00
Max Gramser d60a0f122b Show who is at the door: camera images on the Guition (0.2.66)
An alert from esp_screens_show_alert takes a `camera` (a camera.* or image.* entity): a Guition with firmware
0.2.57 shows that moment's picture across the top of the card, and a tap opens the camera full screen. A camera
or image tile opens the same full-screen view, refreshed every four seconds at a steady pace.

ESP Screen Manager fetches the snapshot with its own access, sizes it for the screen and serves a 24-bit BMP
under a random, short-lived link on port 8098; the screen loads it with ESPHome's online_image and holds no
Home Assistant token. BMP because ESPHome decodes it per chunk, where a full-screen JPEG held the loop 0.6 s.
The CYD keeps its alerts without the picture and gets no camera tiles.

The Guition also builds with ESPHome 2026.8+ again: backlight_fade.h derived from ESPHome's LEDC output, which
2026.8 made final, so the backlight now dims through ESPHome's own light transition.

Tested on the bench boards and a local add-on on the Home Assistant Yellow; docs/TEST_RESULTS_0266.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 15:31:11 +02:00
Max Gramser dfd1a26d69 Let Wake only light the screen, and open ESP Screens without a chosen screen (0.2.65)
Wake from Home Assistant counted as a tap: it reset last_touch_ms, the one
clock that standby and Back to page 1 both read. An automation pressing Wake
on every motion therefore held an open card or page 2 up for as long as
someone moved in the room. Back to page 1 now has its own clock, last_use_ms,
written only by the boot, the touchscreen triggers, open_settings from Home
Assistant and the UI self test. Wake, an alert ending and Auto standby on
still restart the standby time, and Wake still brings back the brightness and
the second hand.

The rule moved from the interval into the script back_to_page_1_when_due.
Wake runs it right after waking a dimmed screen, so a page whose time ran out
during standby lights up on page 1 instead of jumping there a second later.

ESP Screens no longer opens the first screen by itself. Until one is picked
the page says "Choose a screen", and with no screens it still offers the
install; both cards start hidden so neither flashes while the page loads.

Checked with 48 host API checks per board, both ESP32 builds, 314 Python and
16 C++ tests, and the editor on the demo home. Firmware 0.2.56.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 12:41:19 +02:00
Max Gramser bc2a754706 Add Dark mode for a screen beside the bed, with every colour in one table (0.2.63)
Dark mode is a new switch under Brightness on the screen's settings page, in
the Screen settings of ESP Screens and as switch.<screen>_dark_mode in Home
Assistant, so an automation can turn it on at bedtime. The screen changes
look at once, open cards and an alert included, and keeps it after a
restart. The design stays the same: a black page, graphite cards with a
hairline, soft white text, Home Assistant's state colours where they tell
something, and pastel card colours as deeper versions of themselves.

Every colour the firmware chooses now lives in components/smart_display/
theme.h: roles with a light and a dark value, the named card colours and
Home Assistant's state colours. The board profiles give widgets colourless
shared styles that theme.h fills, so a change of look refills those styles
and draws again what code painted by state. The light look is unchanged
apart from merges below one panel step. Dark mode costs 440 bytes of static
RAM on the CYD, and the LVGL tree of the host build is 416 bytes smaller; tests
keep colours out of every other file.

Comparing a screen that switched looks with one that booted in it also
found two older bugs, now fixed: a settings switch that was on showed its
knob at the left whenever its page was drawn, and the sun card's sunlit
area turned orange after a palette change. Firmware 0.2.54.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 12:07:10 +02:00
Max Gramser 8971ab07e1 Keep the README to the pitch, the pictures and the install, and move the rest to README_EXTENDED
The README had grown into the full documentation. It now opens with a short
why, what and how, shows the screens and ESP Screens in pictures, and keeps
the installation steps. Every card, setting, alert and update detail moves
unchanged to README_EXTENDED.md.

The license now names Max Gramser; the README credits Adrian Kuehlewind's
ESPHome-touch-display-mount, where the first version started. The unused
background images from that project are gone.

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