tfaour a358045cea
Build and push server image / build-and-push (push) Successful in 32s
Fix "Show next" staleness bug; add location/date/share-QR to manage overlay
Two changes, bundled since they landed in the same session and touch
overlapping files:

1. Fix: "Show next" sent the browser's full queue snapshot to
   POST /api/queue/reorder, which hard-rejected if the server's queue
   had shifted since the last fetch (e.g. right after a queue-length
   trim). New POST /api/queue/promote moves one photo to the front
   authoritatively, with no dependency on client staleness. /reorder
   itself is now tolerant too -- unrecognized IDs are dropped and
   missing ones appended, instead of rejecting the whole request.

2. Feature: the manage button's overlay now also shows the photo's
   location (top-left, only if Immich reverse-geocoded it from GPS
   EXIF), the date it was taken (bottom-right), and a QR code (bottom-
   left) linking to a 30-minute public Immich share link -- created
   lazily when someone actually scans it, not when the button's
   pressed. New server endpoints GET /frame/photo-info and
   GET /frame/share/{asset_id} (scoped to the frame's current/queued
   photos, not any arbitrary Immich asset). Firmware-side, the overlay
   mechanism generalizes from one spliced region to up to four
   (manage_qr_overlay.c), each its own small buffer, still never
   holding the full frame in RAM.
2026-07-19 01:28:25 -04:00

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

See docs/hardware.md for wiring and docs/architecture.md for how the two halves talk to each other.

Getting started

  1. server/ -- run the FastAPI server first (Docker Compose, points at your Immich instance). See server/README.md.
  2. firmware/ -- build and flash the ESP32-C6, then scan the QR codes it draws on first boot to provision it. See firmware/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.

S
Description
No description provided
Readme MIT
17 MiB
v1.5.0
Latest
2026-08-04 19:27:00 -04:00
Languages
Python 62.9%
C 19.2%
JavaScript 7.4%
HTML 5.6%
CSS 1.7%
Other 3.2%