Skip to content

feat(server): per-node state pipeline for multi-node sensing (#249)#326

Merged
ruvnet merged 2 commits intomainfrom
fix/issue-249-multi-node-state
Mar 27, 2026
Merged

feat(server): per-node state pipeline for multi-node sensing (#249)#326
ruvnet merged 2 commits intomainfrom
fix/issue-249-multi-node-state

Conversation

@ruvnet
Copy link
Copy Markdown
Owner

@ruvnet ruvnet commented Mar 27, 2026

Summary

  • Replaces single shared state with HashMap<u8, NodeState> per-node tracking
  • Each ESP32 node gets independent frame history, classification, vitals, and person count
  • Aggregate person count across all active nodes (seen within 10 seconds)
  • Fixes the Best Way to Block #1 user-reported issue — detection now differentiates per-node contributions

Architecture (ADR-068)

UDP frames → node_states[node_id] → per-node pipeline → aggregate → WebSocket

Each NodeState contains: frame_history, smoothed_person_score, smoothed_motion, vital_detector, baseline_motion, debounce state, hr_buffer, br_buffer, and rssi_history.

Scaling

Nodes Memory Notes
1 ~50 KB Identical to current
3 ~150 KB Typical home
10 ~500 KB Small office
100 ~5 MB Large deployment
256 ~12.8 MB Max (u8 node_id)

Validation

  • cargo check — 0 errors, 17 pre-existing warnings
  • Single-node path unchanged (HashMap has one entry)
  • Simulated data path backward compatible
  • QEMU swarm test (triggered by this PR)

Test plan

  • QEMU 3-node mesh: verify distinct per-node classifications
  • QEMU 5-node star: verify aggregate person count
  • Single-node regression: verify identical behavior to v0.5.1

Closes #249
Refs #237, #276, #282

🤖 Generated with claude-flow

ruvnet added 2 commits March 27, 2026 17:45
Documents the architectural change from single shared state to per-node
HashMap<u8, NodeState> in the sensing server. Includes scaling analysis
(256 nodes < 13 MB), QEMU validation plan, and aggregation strategy.

Also links README hero image to the explainer video.

Co-Authored-By: claude-flow <ruv@ruv.net>
…#249)

Replaces the single shared state pipeline with per-node HashMap<u8, NodeState>.
Each ESP32 node now gets independent:
- frame_history (temporal analysis)
- smoothed_person_score / prev_person_count
- smoothed_motion / baseline / debounce state
- vital sign detector + smoothing buffers
- RSSI history

Multi-node aggregation:
- Person count = sum of per-node counts for active nodes (seen <10s)
- SensingUpdate.nodes includes all active nodes
- estimated_persons reflects cross-node aggregate

Single-node deployments behave identically (HashMap has one entry).
Simulated data path unchanged for backward compatibility.

Closes #249
Refs #237, #276, #282

Co-Authored-By: claude-flow <ruv@ruv.net>
@ruvnet ruvnet merged commit 3c02f6c into main Mar 27, 2026
taylorjdawson added a commit to taylorjdawson/RuView that referenced this pull request Mar 28, 2026
Complements ruvnet#326 (per-node state pipeline) with additional features:

- Dynamic adaptive classifier: discover activity classes from training
  data filenames instead of hardcoded array. Users add classes via
  filename convention (train_<class>_<desc>.jsonl), no code changes.
- Per-node UI cards: SensingTab shows individual node status with
  color-coded markers, RSSI, variance, and classification per node.
- Colored node markers in 3D gaussian splat view (8-color palette).
- Per-node RSSI history tracking in sensing service.
- XSS fix: UI uses createElement/textContent instead of innerHTML.
- RSSI sign fix: ensure dBm values are always negative.
- GET /api/v1/nodes endpoint for per-node health monitoring.
- node_features field in WebSocket SensingUpdate messages.
- Firmware watchdog fix: yield after every frame to prevent IDLE1 starvation.

Addresses ruvnet#237, ruvnet#276, ruvnet#282

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Help Ruvnet! Detection Window showing the same thing regardless of position and people in room.

1 participant