wifi-densepose/v2/crates/wifi-densepose-desktop
arsen b292c7d869 deploy: tp-link wisp ap + rssi-Δ presence detector + live calibration ui
Operator's household environment showed CSI-variance presence detection
failing — empty room produced HIGHER variance than an occupied room because
ambient WiFi noise (neighbour APs, retransmits, BT-coex) dominated the
broadband-variance signal at multi-meter range.

Deployed a TP-Link TL-WR841N in WISP mode as a dedicated isolated AP for
the sensors:
* Sensors associate only with TP-Link_8340 (clean channel)
* TP-Link bridges to the household AP, NAT-forwards sensor UDP to the Mac
* Mac keeps its primary household-AP association — no LAN reconfig needed
* Empty-room variance dropped 50.7 → 35.8 (-30%)

Replaced presence classification with RSSI MAD-Δ override:
* Per-node rolling 120-sample (~10 s @ 12 Hz) window of frame RSSI
* Metric: mean(|Δrssi|) between consecutive frames — robust to int8
  quantisation jitter
* Thresholds tuned for the operator's geometry:
   d < 0.20  → absent
   < 0.55    → present_still
   < 1.10    → present_moving
   >= 1.10   → active
* Confidence field temporarily carries raw d for in-field threshold tuning
* CSI-based features (variance, motion_band_power, spectral_power) remain
  in features.* for vital-sign signal-quality and multi-node fusion paths

UI / tooling:
* New static/spectrum.html — live signal console: combined classification,
  all host-computed features (variance, motion_band, spectral, breathing
  band, RSSI, dominant_freq, change_points), per-node FW signals, and a
  60-second variance trace. Served via `python -m http.server 8091`.
* static/calibrate.html — simpler per-node motion/presence/RSSI bars
  with peak-hold.

Desktop UI / discovery hardening (rolled in here because they came up
during this debug session):
* commands/discovery.rs: HTTP sweep limited to 2..=60 hosts (was 1..=254),
  mDNS + UDP-broadcast paths disabled (current RuView FW doesn't advertise
  them and they were burning CPU every poll cycle). Per-request timeout
  set to 1500 ms with overall budget enforced via tokio::time::timeout +
  futures::join_all (replaces the previous sequential select loop that
  blocked on slow IPs).
* ui/hooks/useNodes.ts: poll interval 10 s → 30 s.
* ui/pages/Dashboard.tsx + NetworkDiscovery.tsx: merge new scan results
  into existing list instead of replacing — discovery races sometimes miss
  a node that was found a moment ago.

Firmware tuning:
* edge_processing.c: broadband-variance divisor /3.0 → /30.0 → /5.0
  iterated; final /5.0 chosen for multi-meter geometry (sensor 1-3 m
  from activity zone). DEBUG_MOTION_DSP scaffolding removed.
* csi_collector.c: CSI_MIN_SEND_INTERVAL_US 20 ms → 4 ms so the host can
  see every available frame (real ceiling is the WiFi CSI callback rate).

Documentation:
* docs/adr/ADR-099 — full forensic write-up: measurement tables for sit/
  walk/empty, the RSSI-Δ rationale, the WISP setup procedure, calibration
  protocol for new deployments, and open items.

Verified end-to-end on hardware (sensors at 192.168.1.17/.19 → TP-Link at
192.168.1.14 → Mac at 192.168.1.21):
* UDP/5006 packets arrive ~12 Hz combined from both nodes
* Empty-room baseline d ≈ 0.49 measured (next: capture sit + walk to
  finalize thresholds)
* Vital signs continue to populate (breathing 9–11 BPM stable)
* Two consecutive OTA round-trips remain functional after the change

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 11:26:07 +07:00
..
.claude-flow chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
capabilities chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
gen/schemas chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
icons chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
src deploy: tp-link wisp ap + rssi-Δ presence detector + live calibration ui 2026-05-15 11:26:07 +07:00
tests chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
ui deploy: tp-link wisp ap + rssi-Δ presence detector + live calibration ui 2026-05-15 11:26:07 +07:00
Cargo.toml chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
README.md chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
build.rs chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00
tauri.conf.json chore(repo): rename rust-port/wifi-densepose-rs → v2/ (flatten to one level) (#427) 2026-04-25 21:28:13 -04:00

README.md

RuView Desktop

Work in Progress — This crate is under active development. APIs and UI are subject to change.

Cross-platform desktop application for managing ESP32 WiFi sensing networks. Built with Tauri v2 (Rust backend) and React + TypeScript (frontend), following the ADR-053 design system.

Overview

RuView Desktop provides a unified interface for node discovery, firmware management, over-the-air updates, WASM edge module deployment, real-time sensing data visualization, and mesh network topology monitoring — all from a single native application.

Pages

Page Description Status
Dashboard System overview with live stat cards, server panel, quick actions, and node grid Done
Nodes Sortable table of discovered ESP32 nodes with expandable detail rows Done
Flash 3-step serial firmware flash wizard (select port, pick firmware, flash + verify) Done
OTA Update Single-node and batch over-the-air firmware updates with strategy selection Done
Edge Modules WASM module upload, lifecycle management (start/stop/unload) per node Done
Sensing Server start/stop, live log viewer (pause/clear), activity feed with confidence bars Done
Mesh View Force-directed canvas graph showing mesh topology with click-to-inspect nodes Done
Settings Server configuration (ports, bind address, discovery interval, theme) Done

Architecture

wifi-densepose-desktop/
├── src/
│   ├── main.rs              # Tauri app entry point
│   ├── lib.rs               # Command registration
│   ├── commands/            # Tauri IPC command handlers
│   │   ├── discovery.rs     # Node discovery (mDNS/UDP probe)
│   │   ├── flash.rs         # Serial firmware flashing
│   │   ├── ota.rs           # OTA update (single + batch)
│   │   ├── wasm.rs          # WASM module management
│   │   └── server.rs        # Sensing server lifecycle
│   └── domain/              # DDD domain models
│       ├── node.rs           # DiscoveredNode, NodeRegistry, HealthStatus
│       └── config.rs         # ProvisioningConfig with validation
├── ui/                       # React + TypeScript frontend
│   ├── src/
│   │   ├── App.tsx           # Shell with sidebar nav, live status bar
│   │   ├── design-system.css # ADR-053 design tokens and components
│   │   ├── types.ts          # TypeScript types mirroring Rust domain
│   │   ├── components/       # Shared UI components (StatusBadge, NodeCard)
│   │   ├── hooks/            # React hooks (useServer, useNodes)
│   │   └── pages/            # 8 page components
│   └── index.html
└── tauri.conf.json           # Tauri v2 configuration

Tauri Commands

Group Command Description
Discovery discover_nodes Scan network for ESP32 nodes via mDNS/UDP
Flash list_serial_ports List available serial ports
detect_chip Detect connected chip type
start_flash Flash firmware via serial
OTA ota_update Push firmware to a single node
batch_ota_update Push firmware to multiple nodes
WASM wasm_list List loaded WASM modules on a node
wasm_upload Upload a .wasm module to a node
wasm_control Start/stop/unload a WASM module
Server start_server Start the sensing HTTP/WS server
stop_server Stop the sensing server
server_status Get current server status
Provision get_provision_config Read provisioning configuration
save_provision_config Save provisioning configuration

Design System (ADR-053)

The UI follows a dark professional theme with the following design tokens:

Token Value Usage
--bg-base #0d1117 Main background
--bg-surface #161b22 Cards, sidebar, panels
--bg-elevated #1c2333 Elevated elements
--accent #7c3aed Primary accent (purple)
--status-online #3fb950 Online/success indicators
--status-error #f85149 Error/offline indicators
--font-mono JetBrains Mono Technical data, code
--font-sans Inter UI text, labels

UI Features

  • Glassmorphism cards with backdrop-filter: blur(12px)
  • Count-up animations on dashboard stat numbers
  • Page transitions with fade-in + scale on navigation
  • Gradient accents on logo, nav indicator, primary buttons
  • Status dot glows with ambient box-shadow per health state
  • Staggered fade-ins for card grids
  • Force-directed graph for mesh topology (pure Canvas 2D)

Download

Pre-built binaries are available on the Releases page.

Platform Download Status
Windows x64 v0.3.0-alpha Debug build
macOS Planned
Linux Planned

Running the pre-built exe (Windows)

The current release is a debug build that loads the frontend from a local Vite dev server. Follow these steps:

# 1. Clone the repo (or download just the ui/ folder)
git clone https://github.com/ruvnet/RuView.git
cd RuView/v2/crates/wifi-densepose-desktop/ui

# 2. Install frontend dependencies
npm install

# 3. Start the Vite dev server
npx vite --host

# 4. Download and run the exe from the release page
#    (or run from the repo if you built it locally)
#    The app window will open and connect to localhost:5173

Requirements: Windows 10 (1803+) or Windows 11. WebView2 runtime is required (pre-installed on Windows 10 1803+ and all Windows 11).

Note: Production builds will bundle the frontend assets directly into the exe, removing the need for a dev server.

Build from Source

Prerequisites

  • Rust 1.85+
  • Node.js 20+
  • Tauri v2 CLI
  • Windows: MSVC build tools + MinGW-w64 (for dlltool)
  • macOS: Xcode Command Line Tools
  • Linux: libwebkit2gtk-4.1-dev, libappindicator3-dev, librsvg2-dev

Development mode

# Install frontend dependencies
cd ui && npm install

# Start in dev mode (hot-reload on both Rust and React)
cargo tauri dev

Production build

# Build optimized release with bundled frontend
cargo tauri build

The installer/bundle will be in target/release/bundle/ (.msi on Windows, .dmg on macOS, .deb/.AppImage on Linux).

Domain Types

Type Fields Description
Node ip, mac, hostname, node_id, firmware_version, chip, mesh_role, health, ... Full node record
HealthStatus online, offline, degraded, unknown Node health state
FlashSession port, firmware, chip, baud, progress Active flash operation
OtaResult node_ip, success, previous_version, new_version, duration_ms OTA outcome
WasmModule module_id, name, size_bytes, state, node_ip Edge module record
ServerStatus running, pid, http_port, ws_port Sensing server state
SensingUpdate timestamp, node_id, subcarrier_count, rssi, activity, confidence Real-time data

License

MIT — see LICENSE for details.