c3234028951c6303dc06b3afeb448c50c064fe99
The share QR's URL carried no auth params at all, so it silently fell back through require_device's legacy-token resolution to whichever frame happened to still be flagged legacy -- working only by accident for a single frame, sharing the wrong frame's photos for any other, and going fully dead once that frame's legacy flag was cleared. Move the endpoint to manage.py, keyed on the frame's own manage_token (same pattern /m/<manage_token> already uses) instead of device auth. Since the server now resolves assets itself instead of trusting a caller-supplied asset_id, it naturally generalizes to gather every photo widget's current photo into one Immich share link, not just one "primary" widget's.
ESPresso Frame
A DIY e-ink photo frame: an ESP32-C6 pulls photos from your Immich library and displays them on a 7.3" full-color e-paper panel, waking on a timer to refresh and spending the rest of its time in deep sleep.
- No cables to a computer, no SD card shuffling. Provisioning is a captive portal with a QR code drawn on the panel itself -- scan, join, fill in your WiFi and server address, done.
- The frame never decodes an image. A small self-hosted server does all the work (pulling from Immich, cropping, dithering, packing into the panel's exact pixel format) and hands the device a stream it can write straight to SPI. The ESP32-C6 has no PSRAM and not much SRAM to spare -- keeping it a dumb display client is what makes that workable.
- Crops toward faces, not just the center, using face bounding boxes Immich already computed for its own People feature -- no bundled face detector.
- Refresh interval and album are configurable from a web UI, no reflashing needed to change them.
Hardware
- ESP32-C6 dev board (8MB flash)
- Waveshare 7.3" E Ink Spectra 6 (E6) panel -- 800x480, 6-color, SPI
See docs/hardware.md for wiring,
docs/architecture.md for how the two halves talk
to each other, and docs/widgets.md for the server's
placeable photos/calendar/whiteboard widget system.
Getting started
server/-- run the FastAPI server first (Docker Compose, points at your Immich instance). Seeserver/README.md.firmware/-- build and flash the ESP32-C6, then scan the QR codes it draws on first boot to provision it. Seefirmware/README.md.
Repo layout
firmware/ ESP-IDF project for the ESP32-C6
server/ FastAPI server: Immich -> crop/dither/pack -> the frame
docs/ Wiring and architecture notes
License
MIT -- see LICENSE. A few small pieces of vendored
third-party code (a QR code generator, a bitmap font table) keep their
own permissive licenses; see LICENSE for details.
Built with substantial assistance from Claude Code.