scripts/ota-deploy.sh
Python 3 helper (the earlier bash version tripped over macOS bash 3.2's
missing associative arrays). One invocation with no arguments:
1. discovers nodes in the local /24 via ARP + /ota/status:8032 probe;
2. POSTs the firmware blob to every node in parallel;
3. waits for reboot, polls /ota/status until running_partition flips,
and fails-loud if any node stays on the old partition (typical
symptom of a panic on first boot from the new slot).
Supports `--build` (idf.py build first), `--no-verify`, explicit IP
list, and OTA_PSK=<token> for the ADR-050 Bearer auth path.
Measured cycle: ~25 s end-to-end for both room01 + room02.
static/mobile.html
Mobile-first sibling of static/raw.html. The desktop page is unreadable
on a 360-420 px screen — bars chart fights the narrow viewport, 11-12 px
font, controls overlap the badge. The mobile page:
- sticky global badge (30 px) + connection pill + reset (44 px tap);
- per-node card with 22 px node badge, 18 px stat tiles, 90 px trace;
- drops the bars chart (useless under 600 px wide);
- viewport-fit=cover, theme-color, apple-mobile-web-app meta tags;
- high-contrast palette tuned for outdoor light;
- reuses the /ws/sensing contract verbatim — anything that lights up
raw.html lights this up too.
main.rs ServeDir route
Adds `.nest_service("/static", ServeDir::new(.../static))` so
raw.html / mobile.html / calibrate.html / spectrum.html are served on
the main 8080 port. Previously they needed a separate
`python -m http.server :8091`, which the operator had to remember to
start by hand on every deploy. Now there's exactly one URL per device.
Reachable from a phone on the LAN:
http://<mac>:8080/static/mobile.html
http://<mac>:8080/static/raw.html
Co-Authored-By: claude-flow <ruv@ruv.net>