Tiles get an absolute grid slot instead of a packed order: a tile lands exactly
where it is dropped, dropping on another tile swaps the two, everything else
stays put, and empty cells and empty pages persist. The mockup previews the
result while dragging, a new page waits below the last one, "Pagina toevoegen"
keeps an empty page, empty cells accept the next tile from the picker, and the
mouse no longer selects text while dragging.
Storage and protocol stay version 1: `tiles[].slot` (0-47) and `pages` (1-8)
are additive, the layout message carries `slots` and `pages`. Firmware 0.2.26
places tiles on those slots (`place()` next to `pack()`); older firmware packs
in order as before and the editor says so.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Page swipes were an LVGL gesture anywhere on the screen: 50 px, fast only,
and almost always starting on a tile that lit up as pressed. On the Guition
a touch that starts within 32 px of the left or right edge and travels
40 px inward, clearly sideways, now flips one page (from the right edge
leftwards is next, from the left edge rightwards previous), at any speed
and in every rotation; a swipe that starts in the middle does nothing, so
taps and drags on tiles can no longer change the page by accident. The
whole-screen gesture is removed from the Guition profile; the CYD keeps
it. Firmware 0.2.24 for both boards, the app only reworded the setting.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The touch guard dropped a tap as soon as the finger drifted more than
18 px (under 3 mm) from its very first contact point, on both boards and
regardless of the page-swipe setting; LVGL itself never cancelled these
clicks (no scrollable ancestors, gestures do not suppress clicks). A finger
that flattens or rolls while pressing was enough, and the tap vanished
without a trace in the log.
The limit is now about one centimetre per board (TOUCH_MOVE_LIMIT_PX:
Guition 67 px, CYD 56 px), measured from a reference that settles over the
first four samples; only the contact that started the touch is followed,
so a second finger no longer counts as movement; the minimum contact time
is per board too (TOUCH_MIN_PRESS_MS: 60 ms resistive, 20 ms capacitive).
Every refused tap is logged on INFO with its reason (moved, too short,
already used, bounce). Firmware 0.2.23 for CYD and Guition.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
"Nieuw scherm" used to span two dialogs plus a copy/download of the
installation YAML. It is now one dialog: board, name (node name derived,
editable), wifi only when secrets.yaml lacks it, the detected USB port,
and Installeren. The add-on writes the profile with unique API/OTA keys,
merges just the missing wifi lines into secrets.yaml (comments and other
secrets untouched, result re-parsed before writing), then builds and
flashes with the live ESPHome log and stage in the same dialog; a failed
build offers a retry without a second profile. The YAML download
endpoint is gone: the profile already lives in the ESPHome folder.
Pairing happens in Home Assistant itself, so the done view and a sidebar
card per not-yet-paired profile say so, with a button to Apparaten &
diensten, the API key to copy and the reminder to allow HA actions.
One profile per screen; the dialog says that too.
Tests: wifi merge cases, install pre-checks, pending list, profile
metadata; the date-anchored hourly forecast test now follows the clock.
Firmware 0.2.22 stays current.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Since 0.2.20 the manager repeats a layout every 120 s, while the firmware
treated anything older than 95 s (sized for the original 25 s keepalive) as
stale: on a quiet screen every card read "Niet beschikbaar" and the header
"HA niet verbonden" for 25-45 s of each two-minute round, on both boards.
"HA niet verbonden" now follows ESPHome's own api_is_connected(); the feed
watchdog uses the cadence the layout message declares ("keepalive", seconds,
120 s when absent) and tolerates one missed round plus loop slack before
showing "ESP Screens niet actief". The tick redraws once when either flips.
Firmware 0.2.22 for CYD and Guition.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
App 0.2.25 / firmware 0.2.21. The 600 ms touch-guard lockout dropped a second
tap on the same -/+ key; stepper keys now use a 150 ms bounce guard, repeat
while held (3 per second), and still send one call after 700 ms of rest.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
App 0.2.23 / firmware 0.2.19.
- Wide cards of climate, switch, light, fan, vacuum, cover, media_player,
number, select, timer, scene, script and button show Home Assistant style
controls on the right (keys, -/+ pill with debounced send, slider with
handle, toggle, run key); per-tile choice `options.controls` in the editor
with mockup preview; the add-on sends only the set a card really shows.
- Weather card: now + next hours and coming days with rain, from daily and
hourly forecasts; scenes/scripts/buttons show when they last ran.
- Climate card: power key, tap-to-toggle option, fan and swing rows in a
redesigned mode picker (grey backdrop, white chips, accent selection).
- Busy state as a spinner on a translucent sheet; render guards so only
changed styles reach LVGL; dark theme removed from the runtime code.
- supported_features above 1e6 reaches the screen; middle dot in text fonts;
18 control glyphs in the icon fonts; diagnostics services
preview_climate_picker and preview_busy; demo layout --controls.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
/api/events streams the light inventory whenever the sync loop or a save
changes it (3 s check during firmware updates). The page stops polling
while the stream is open and falls back to the 10 s poll otherwise. The
websocket close is logged with duration, close code and exception.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The sync loop now wakes only for state changes of entities on a layout or
belonging to a screen. Registries refresh on HA registry events with a
10 minute fallback instead of every 30 s. The page polls a light inventory
(screens + update status) every 10 s and the full catalogues every 5 min or
when the tab becomes visible. The full keepalive interval is 120 s.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
/api/inventory re-read every ESPHome profile with pure-Python PyYAML up to
four times per request, which blocked the event loop for seconds on a Pi.
Profiles are now cached per file on (inode, mtime_ns, size), parsed with
libyaml when available, and read once per request. The sync loop computes
the inventory once per iteration. The page pauses polling while hidden.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- screen_manager/app/tile_icons.py is the single icon list (12 groups, 20 media
and music icons); tools/generate_icons.py writes it into the three icon fonts
of both boards and builds the editor's subset font.
- Firmware 0.2.18 shows o.icon when its fonts carry the glyph, else the domain
icon. The app sends the chosen icon, or Home Assistant's own mdi icon on auto.
- Tile sheet gets an icon picker with search; the mockup shows the icon the
screen actually draws.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Screens now report their ESPHome name and IP address, so the add-on can
match each screen to its YAML profile and OTA address itself. The screen
list shows an update badge with a Bijwerken button, an update-all action
and a nightly checkbox; updates run one screen at a time, wait for the
new version to report back and stop the round on the first failure.
App 0.2.16, firmware 0.2.17.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Firmware 0.2.16: the analog clock uses index strokes with 12/3/6/9
numerals on large cards and shows a calendar block (weekday, big day,
short month) beside the dial on single tiles; wide cards keep the digital
time and date. New palette key 'none' hides only the card fill and
border: geometry, padding and the pressed flash stay identical. Skeleton
frames and the render self-test honour the transparency.
App 0.2.15: 'Geen' in the background palette with a dashed mockup tile,
min_firmware 0.2.16 for such layouts, demo layout with the bare calendar
clock (--wide for the double-width clock). README and AGENTS note that
every push is a release and bumps the add-on version.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Firmware 0.2.15: trend graphs use a Catmull-Rom curve with a soft fill
drawn by the card's draw event; sun.sun gets a wide sun-path card with
horizon, arc and the sun at its current position; page switches show
the new page's card frames immediately and fill them from a one-shot
timer; the navigation is one full-width bar without a divider; the CYD
adopts the Guition light palette in styles and overlays.
App 0.2.13: pointer-based drag & drop (mouse and touch) to reorder tiles
in the mockup and to drop entities from the list, sticky save bar, a new
header with explained actions and a three-step guide, clearer firmware
dialog. New sun, weather and clock tiles start wide in their best view.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Any tile can now be double width: pack() in runtime_model.h places wide
tiles in the left column and the manager preview follows the same rules.
New cards: built-in clock (digital or analog, screen.clock), five-day
weather forecast on a wide weather card fed by weather.get_forecasts,
history sparkline for sensors, sunrise/sunset (sun.sun), live kitchen
timer (timer.*, tap starts or pauses) and presence (person.*). The
manager pre-computes time-zone and forecast extras in a new 'x' object
and refuses layouts with new domains until the screen runs 0.2.14.
The self-test follows the packing, checks custom card parts and wide
widths, and diagnostics/send_layout.py pushes a demo layout of every
card type for render checks without Home Assistant. App 0.2.12,
firmware 0.2.14.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>