v0.53.2 — REST transport (no broker required)
The headline change since v0.51.9: Tesserae now has a full REST transport, and REST is the default for new installs. No more MQTT broker setup friction; battery devices register with a pairing code (or auto-claim via MAC), then poll /api/v1/device/<id>/frame/<fmt> with If-None-Match and post heartbeats to /api/v1/device/<id>/status. MQTT keeps working unchanged; existing installs and existing devices are not migrated.
Highlights
REST transport (zero-broker path)
- New
/api/v1/device/*surface:register,frame/<fmt>(ETag + 304),status,discover,log. - Per-device bearer tokens (
Authorization: BearerwithX-Tesserae-Tokenfallback), minted server-side with 20-charnativestrength when a REST device registers. - 6-digit pairing codes with 10-min TTL, single-use, constant-time compare, sliding-window rate limit on the register endpoint (10 attempts / 60s per IP, X-Forwarded-For aware).
- Discover-then-claim flow: a device announces itself, the host shows it in the Discovered strip with a "REST, auto-claim on register" pill, and registering it binds the MAC so the firmware never has to be re-typed.
- Per-device transport flip from the device card: switch any registered device between MQTT and REST without re-creating the instance; status/config topics are kept on the manifest so the flip is one click each direction.
Onboarding
- Default transport for new installs is REST; the wizard surfaces a transport radio with conditional broker fields. MQTT is still selectable for users who want the broker.
- Step-pip icon class fixed (was missing the check on completed steps).
- Welcome copy updated to mention Transport instead of Broker.
Bug fixes
- REST device "last seen" stuck at epoch 0 — status writes now go through a shared
record_status_heartbeathelper, so MQTT and REST agree on the cache shape ({received_at, parsed}). /send500 when a device hadpanel.w == 0orpanel.h == 0(e.g. a firmware build with no panel attached) — guard arounddevice_panel(dev)in_device_options, plus registration-path guards that drop zero-width / zero-height overrides instead of writing them to the manifest.- Lint + CI fixes for the test suite added in v0.52.x.
Docs
- New
docs/install/rest-transport.mdwith the full REST API, capability mapping table (MQTT ↔ REST), and the pairing / discover-claim flows.
Plumbing
transports/is now a discoverable folder (Phase 1c): metadata manifests live intransports/mqtt/transport.jsonandtransports/rest/transport.json, loaded viaapp/transport_loader.py. Implementations stay where they live.
Devices firmware
Reference firmware: tesserae-esp32-bin-client for ESP32-IDF, and the Pico SDK client. Updated firmware prompts ship as a sibling delta for the discover-claim addition; existing pairing-code firmware still works unchanged.
Upgrade notes
- Existing MQTT installs: no action needed. The new transport is opt-in per device.
- Existing devices: unchanged. Use the per-device "Switch to REST" button on the device card to migrate one at a time.
- Fresh installs: the onboarding wizard picks REST by default; the embedded MQTT broker is no longer started unless you explicitly choose MQTT.
What's next
A devices settings UI cleanup pass (issues #16–#22) was backlogged in this release; nothing in v0.53.2 blocks on it.
Includes git tags v0.52.0 through v0.53.2.