ADR-021 already publishes `vital_signs` inside SensingUpdate but the
raw calibration console had no readout — the operator had to curl
/api/v1/vital-signs to see breathing/HR. Add two pills (🫁 + 💓)
next to the mmWave one and update them on every WS tick.
Confidence < 20 % dims the pill so noise-floor estimates don't read
as real values. Missing/zero rates fall back to "— BPM".
Mirrored ui/raw.html → static/raw.html so both deployment paths
serve the same console.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds a hidden-by-default 📡 mmWave pill next to the global badge + CV
stat. Polls /api/v1/mmwave/latest at 5 Hz (~200 ms) — well above the
HLK-LD2402's 6 Hz native cadence so no information is lost. Pill shows:
📡 mmWave 152 cm · 60 ms
Distance + age (ms since last reading). Fades to 50% opacity when age
>1.5 s, hides entirely when the server reports `available: false`
(port absent or stale >2 s).
Synced both copies — ui/raw.html (deploy mirror) + static/raw.html
(canonical source referenced by ADR-104 / ADR-107).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously raw.html lived only at v2/crates/wifi-densepose-sensing-server/static/raw.html.
When the server is started with --ui-path /Users/arsen/Desktop/RuView/ui
(the SPA path) the calibration console returns 404 on /ui/raw.html.
Copy the file into ui/ alongside index.html so a single --ui-path
covers both the SPA and the engineer-facing raw view. The static/
copy in the crate stays as the canonical source (referenced by ADRs
104/107); ui/raw.html is a deploy mirror.
Live at http://localhost:8080/ui/raw.html.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>