- New `docs/observability.md`: descriptive (present-tense) write-up of the Cloud Logging + Cloud Monitoring pipelines as currently shipped. Replaces the historical `logs-plan.md` + `monitoring-plan.md` planning docs. - New `docs/setup.md`: prerequisites, first flash, day-to-day Make targets, and the optional GCP setup (lifted out of the README so the README can stay terse). Includes the Python 3.12-shim explanation from the old `notes.txt`. - Move `ota.md` → `docs/ota.md`. - Move `eink-plan.md` → `docs/eink-plan.md`. Per-feature plans still use the `<feature>-plan.md` name; once shipped they get rewritten in present tense alongside the other docs. - Delete `logs-plan.md`, `monitoring-plan.md`, `notes.txt`. Their user-facing content is now in `docs/setup.md`; their LLM-relevant bits (architectural rationale, partition-table CMake quirk, Python shim, no-LED, `make` conventions, NVS key length cap) are in `CLAUDE.md`. - Trim `README.md` to a top-level overview + links into `docs/`. - Update internal cross-references (Makefile, ota.md, eink-plan.md, tools/provision/src/main.rs doc-comment). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 KiB
E-ink display — plan
The Inland ESP-WROOM-32 dev board doesn't have a software-controllable LED
(see setup.md), so the visible-output story for this
project is an e-ink display. This file captures the hardware choice,
the Rust graphics stack we'll use, and a shortlist of projects to
build on top.
Hardware
- Display: Inland 2.13" e-ink (Micro Center SKU 632694).
- 250×122 mono, SPI, ~Waveshare 2.13" rebrand
- 8-pin male header:
VCC,GND,DIN,CLK,CS,DC,RST,BUSY - Pre-soldered headers — no soldering required
- Refresh characteristics (SSD1680 driver, typical for this panel):
- Full refresh ~2s, with the black/white flash that clears ghosting
- Partial refresh ~300ms, no flash, but ghosting accumulates
- Run a full every 5–10 partials
- No grayscale, no animation. "Update once, look at it for a while."
- Supporting hardware: half-size solderless breadboard, Dupont jumper assortment (F-F at minimum). Both boards are 3V3, no level shifter needed.
Wiring sketch (pins on the ESP32 are conventional for SPI2/HSPI, adjust as needed once the panel arrives):
e-ink ESP32
----- -----
VCC -> 3V3
GND -> GND
DIN -> GPIO23 (MOSI)
CLK -> GPIO18 (SCK)
CS -> GPIO5
DC -> GPIO17
RST -> GPIO16
BUSY -> GPIO4
Rust graphics stack
All no_std-friendly, all sit on top of the existing esp-idf-svc setup —
just add deps to Cargo.toml and draw onto the display via the
embedded-graphics DrawTarget that epd-waveshare implements.
embedded-graphics— primitives, baseDrawTargettraitepd-waveshare— Waveshare e-ink driver, includes the 2.13" panelu8g2-fonts— large font collection, far better than the embedded-graphics built-insembedded-text— text wrapping / multi-line layout in a bounding boxembedded-layout— vertical/horizontal stacking, alignment helpers (no Flexbox, but covers most positioning we'll need)tinybmp— renderinclude_bytes!'d 1-bit BMPs as embedded-graphics images; the easy path for iconsembedded-iconoir— optional, ready-made Iconoir icons
Default starting set: embedded-graphics + u8g2-fonts + embedded-text + tinybmp. Pull in embedded-layout once positioning gets tedious.
Heavier option: Slint
Slint has an MCU backend with explicit e-ink support.
Write .slint markup, get live layout preview. Workable on the
ESP32-WROOM-32 but noticeable flash/RAM footprint. Reach for it only if
iterating on layout becomes a bottleneck with the embedded-graphics stack.
Project shortlist
Ordered by cool : effort ratio.
- Wi-Fi info screen — weather, next calendar event, GitHub PR count, refreshed every 5–10 minutes. Best first project: smallest end-to-end exercise of Wi-Fi + HTTP + JSON + e-ink rendering. Once it works, the rest are variations on the same skeleton.
- Build status badge — last commit's CI state for one or more repos. Sits on the desk, nags when CI breaks.
- Pomodoro timer — two physical buttons, big "WORK 17:32" / "BREAK 04:00" text. E-ink wins because no backlight to distract.
- Now-playing card — Spotify Web API. Refresh slowness fits since tracks last minutes.
- Door / desk status sign — "available / heads-down / on a call", toggled from phone via tiny HTTP server on the ESP32. Battery + e-ink = days of runtime.
- Home Assistant / MQTT subscriber — display whatever the home automation system publishes.
- Conference badge / desk name tag — name + handle + QR code, updateable over Wi-Fi.
- Status dashboard for a personal service — uptime, last-deploy time, error count from one of Jason's own services.
Crate stack already in place
The current Cargo.toml has esp-idf-svc 0.51 with binstart + native
features, plus log and anyhow. That covers Wi-Fi, HTTP client, NTP,
NVS storage. For the e-ink work we just add the embedded-graphics family
of crates listed above and an SPI driver from esp-idf-hal.