01b9e9f1d0980d2dbf2cbd03aa90910b8ac28040
Build and push server image / build-and-push (push) Successful in 51s
A single noisy ADC/regulator glitch (see firmware/main/battery.c) survives the existing recharge filter: whichever way it reads, one of the two steps around it (into a dip, or out of a spike) still looks like an ordinary drop and got averaged straight into the remaining- time estimate, letting one bad reading swing it dramatically. Added a MAD-based modified z-score outlier check on top of the existing recency-weighted average. Had to special-case the standard MAD degenerating to exactly 0, which happens whenever more than half the steps share the same value -- the norm for battery data (most wakes cost the same small integer percent), and exactly the shape a single spliced-in glitch among a steady discharge rate has, so the naive case would have let the outlier this is for sail straight through. Falls back to mean absolute deviation there instead. Verified against constructed glitch scenarios in both directions (spurious dip and spurious spike): estimate now comes out identical to the same series with the glitch removed entirely.
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 and
docs/architecture.md for how the two halves talk
to each other.
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.