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>
This commit is contained in:
Max Gramser
2026-09-17 15:31:11 +02:00
parent 9567ab591a
commit d60a0f122b
31 changed files with 1847 additions and 117 deletions
+84
View File
@@ -0,0 +1,84 @@
# Camera images on a Guition
App 0.2.66 with firmware 0.2.57 shows camera images on a Guition 4848S040:
- **A camera tile.** Add a `camera.*` or `image.*` entity as a tile. A tap opens the image full
screen, with the round back key at the top left like every card. The image is refreshed every
four seconds while it is open. It is not video: ESPHome has no video decoder.
- **An alert with a picture.** Add `camera: camera.front_door` to the `esp_screens_show_alert`
event. The card shows the picture of that moment across its top (it stays that picture); a tap
on it opens the camera full screen over the alert, and Back returns to the alert.
The CYD has no memory for images (a 320×180 image needs 115 KB in one piece, the CYD's largest
free block is about 45 KB). It shows the alert without the picture, and the editor doesn't offer
camera tiles for it.
## A doorbell
```yaml
triggers:
- trigger: state
entity_id: event.front_door_ding
actions:
- event: esp_screens_show_alert
event_data:
title: Someone is at the door
icon: doorbell
camera: camera.front_door
timeout: 60
```
Any `camera.*` entity works, and so does an `image.*` entity, such as the snapshot a doorbell or
motion integration keeps of its last event.
## How the image gets to the screen
The screen never talks to Home Assistant about images, and it never holds a Home Assistant token.
1. The screen asks ESP Screen Manager for a camera (the event `esphome.screen_camera`), or the app
sends the picture of an alert by itself.
2. The app fetches the snapshot from Home Assistant with its own access (the same pictures the
Home Assistant frontend shows), and makes it exactly as large as the screen draws it: at most
480×480 full screen, 392×220 on an alert card, proportions kept.
3. It serves the result as an uncompressed 24-bit BMP on **port 8098** under a random link, and
sends the link to the screen. ESPHome's `online_image` loads it.
While a camera is open, the screen loads its link every four seconds, one image at a time. The app
serves the last snapshot at once and starts fetching the next one, so each load gets a picture one
load younger: the picture changes at the screen's steady pace. (A fetch on its own clock next to the
screen's made the picture change after 1.5 s one time and 6 s the next.) A slow camera makes the
images older, never the screen slower, and nothing queues up. Nobody loading means nothing fetched.
A link that nobody loads for two minutes stops working; an alert's picture stays for half an hour.
**Why BMP.** ESPHome decodes a BMP piece by piece while it downloads (4 KB per round of its main
loop). A JPEG of the full screen took 0.6 s in one piece on the Guition, during which the screen
missed taps. A full-screen BMP is about 390 KB; on the LAN that takes one to three seconds.
## Network
- **Home Assistant OS:** the app publishes port 8098 on the Home Assistant host. Keep it at 8098 in
the app's network settings; the screens need to reach Home Assistant's address on that port.
- **Docker** (docs/DOCKER.md): the container uses the host network, so 8098 is open as is. When
the screens reach the host under another address, set `SCREEN_CAMERA_URL`, for example
`http://192.168.1.20:8098`.
- The images travel unencrypted over the LAN, like the screens' other HTTP traffic. Links are
random, short-lived, and only issued for a camera on that screen's tiles or in a recent alert.
## Memory and speed (Guition, measured 2026-09-17)
- Full screen: 480×270 RGB565 is 259 KB of PSRAM; the alert picture 172 KB. Both are freed when
the camera or the alert closes. A new alert closes an open camera first.
- The internal heap stays level while a camera refreshes: 77.2 KB free after 91 images in six minutes,
and PSRAM unchanged.
- Standby, **Back to page 1** and a new layout close the camera; nothing loads in standby.
## For developers
- `screen_manager/app/camera_feed.py`: fetching, sizing, links and the port.
- `components/smart_display/camera_view.h`: when to ask for a link and when to load again
(`tests/test_camera_view.cpp`).
- `components/smart_display/runtime_tiles.h`: the full-screen view, the alert picture and the
`camera` message.
- `guition-4848s040.yaml`: the two `online_image` components, the alert frame, and the diagnostic
action `preview_camera` (an entity opens it, an empty entity closes it).
- `tests/test_camera.py`: the app side and the words both sides share.