Commit Graph

7 Commits

Author SHA1 Message Date
arsen 432753e188 feat(adr-107): progress bar in raw.html calibrate button
Replaces the text-pill status with a 140×14 px progress bar that
fills from 0 → 99% over CALIB_DURATION_SEC (90s default). On
complete it flashes to 100% with "done" label, then hides itself
after 3s; on error it surfaces a text pill so failure modes stay
visible.

Closes the last Open Item in ADR-107.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-17 16:34:14 +07:00
arsen eec3ca6ce2 feat(adr-104): per-sub drift in WS + raw.html sparkline + staleness watch
Three related ADR-104 follow-ups:

1. Expose per-node drift_score on PerNodeFeatureInfo (skip-if-none
   so legacy v1 baseline.json — no per_subcarrier_mean — emits
   nothing instead of misleading 0.0).

2. raw.html drift sparkline below the RSSI/broadband trace, fixed
   Y range [0, 0.30] with dashed presence (0.10) + warning (0.15)
   thresholds so operators can read off-axis presence across nodes
   without re-scaling. Stat pill "drift" shows the live numeric.

3. baseline_staleness_watch background task: when the on-disk
   baseline is older than --baseline-stale-age-sec (default 4 h)
   AND drift > 1.5× presence threshold for ≥3 consecutive 5-min
   ticks while the classifier reports `absent`, logs a warning
   suggesting recalibration. Rate-limited via
   --baseline-stale-warn-cooldown-sec (default 1 h). Independent
   from auto-recalibrate: that one needs a quiet room; this one
   fires when the operator is *in* the room while the channel
   itself has physically shifted (AP moved, furniture, etc.).

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-17 14:14:13 +07:00
arsen 45c1464cc0 feat(adr-107): raw.html calibrate button + ADR
UI side of ADR-107: green "calibrate empty" button in raw.html next
to the existing reset/log-y controls. Click → confirm dialog tells
the operator to step out → POST /api/v1/baseline/calibrate with
90 s capture window → polls GET /api/v1/baseline every 2 s, surfaces
"recording… N/90 s" then "baseline updated ✓".

ADR-107 documents:
  D1  in-process capture_baseline_to_disk (port of record-baseline.py)
  D2  BASELINE_BUS broadcast forwarder so capture stays decoupled from
      WS clients
  D3  POST /api/v1/baseline/calibrate (immediate ack, background work)
  D4  GET /api/v1/baseline (current state + cooldown + status)
  D5  auto_recalibrate_task — 30-min absent+low-CV trigger, 1-h cooldown
  D6  raw.html button + polling
2026-05-17 12:15:09 +07:00
arsen 764388c0bf docs+fix: ESPectre technique reference + revert stale-amp UI fill
* docs/references/espectre-techniques.md — catalogues every Pace
  technique from Part-2 against what RuView has implemented, doesn't
  have, or has differently. Includes ranked open-items list.
* sensing-server: revert feature_state path to vec![] amplitudes.
  The previous fix made bars LOOK live by reissuing the last raw-CSI
  vector on every feature_state tick — operator reported this made
  the bars misleading (visually busy but unresponsive to movement).
  raw.html already skips empty-amp updates so bars now refresh only
  on actual fresh CSI, which is honest.
* raw.html: comment on the skip-empty branch for future-me.
2026-05-17 09:08:09 +07:00
arsen c22dfcd256 fix(raw.html): guard zero RSSI + correct per-node fps counter
* nodes[].rssi_dbm of 0 used to display literally as "0.0 dBm",
  misleading the operator when rssi_history was empty on the first
  few ticks. Now coerce to "--" and skip pushing zeros to the trace.
* per-node fps was 1/dt instantaneous, blown up to 235 by multiple
  SensingUpdate emit paths firing back-to-back. Replaced with a
  1-second windowed counter — now matches the real ~38 fps per node.
2026-05-17 02:37:05 +07:00
arsen c3126c39a3 feat(raw.html): per-node classification badges (ADR-101)
Surfaces the raw-amplitude classifier's per-node decision in
node_features[].classification so the UI can show which sensor is
actually seeing motion at any moment. Lets the operator visually find
the best sensor placement without physically moving things — just walk
around and watch which badge lights up.

Server side: adds amp_node_level() pure helper + amp_node_snapshot()
that reads AMP_LATEST, then plugs it into build_node_features so the
existing PerNodeFeatureInfo.classification carries the new labels.

UI: adds a global badge in the top bar and a per-node badge inline in
each h2, color-coded (grey/absent, blue/present_still, green/moving,
red/active) plus the live per-node CV %.
2026-05-17 01:01:10 +07:00
arsen 8aef82069b deploy(esp32s3): PHY gain-lock for baseline-stable CSI + raw signals UI
Ports Francesco Pace's ESPectre gain-lock (GPLv3) to RuView FW: medians
AGC and FFT scale over the first 300 packets after boot, then freezes
them via phy_force_rx_gain / phy_fft_scale_force. With both sensors
locked and proper AP→body→sensor geometry, a 30-s × 3-state capture
(empty / still / walk) now separates by ×3.4–×5.9 instead of ±0.02
within ±0.10 noise as in ADR-099.

Adds static/raw.html — per-node 56-subcarrier amplitude bars + RSSI/
broadband traces, no DSP, for live calibration.

ADR-100 documents the technique, boot calibration values for the
operator's deployment (AGC=42/44, both APPLIED), and the verified
three-state separation table.
2026-05-17 00:31:07 +07:00