WiFi Sensing Bench

RuView CSI test bench for your own network

NO SOURCE Disconnected

Presence

—
motion: —

People

—
confidence: —

Breathing

—bpm
not medical-grade

Heart rate

—bpm
proxy, unvalidated

Mean RSSI

—dBm
nodes: —

Frames

—/s
total: 0

Signal history

RSSI motion band breathing band

Signal field

—

Subcarrier waterfall

—

Nodes

NodeRSSISubcarriersCSI fpsSync
No frames yet

Event log

    Last raw frame
    —

    How the pieces connect

    ESP32-S3 nodecaptures CSI from your router
    UDP 5005
    sensing-serverDocker on your PC, port 3000
    token + ticket
    ruview-bridge127.0.0.1:3100, adds CORS
    browser
    This pagetracker.ciprari.ai

    All sensing data stays on your network. This page is static; it only connects to 127.0.0.1 on the computer you open it on. Nothing is sent to Cloudflare.

    0 · Try it with no hardware

    Choose Demo data on the Live tab. Or run the real server in simulated mode (step 2 without an ESP32) to test the full chain.

    1 · Flash and provision an ESP32-S3

    An ESP32-S3 (~$9) is the supported CSI source. ESP32-C3 and the original ESP32 are not supported. A plain laptop gives RSSI-only, coarse presence. Flash the firmware from the RuView repo, then point it at your PC's LAN IP:

    python firmware/esp32-csi-node/provision.py --port COM5 \
      --ssid "YourWiFi" --password "YourWiFiPassword" \
      --target-ip 192.168.1.20

    Replace COM5, the network name, and 192.168.1.20 (your PC's IP, from ipconfig).

    2 · Run the sensing-server (Docker)

    PowerShell:

    $env:RUVIEW_API_TOKEN = -join ((1..32) | % { '{0:x2}' -f (Get-Random -Max 256) })
    docker run --rm -e RUVIEW_API_TOKEN -e CSI_SOURCE=esp32 `
      -e RUVIEW_UDP_ALLOW=192.168.1.0/24 `
      -p 127.0.0.1:3000:3000 -p 5005:5005/udp `
      ruvnet/wifi-densepose:latest

    Drop -e CSI_SOURCE=esp32, the UDP allow-list and -p 5005:5005/udp to run on simulated data. Adjust the subnet to your LAN. Allow UDP 5005 through Windows Firewall when prompted. If the node never appears, Docker Desktop may be rewriting the source address to its own gateway; as a test-only fallback, replace the allow-list with -e RUVIEW_UDP_INSECURE_LAN=true.

    3 · Start the bridge (same PowerShell window)

    Needs Node 18+. It reads the token from the environment, so the token never touches the browser.

    node bridge/ruview-bridge.mjs

    The file is in the coledtouch/tracker repo under bridge/. Or download it here.

    4 · Connect

    On the Live tab choose Local bridge and press Connect. Chrome may ask to allow access to devices on your local network; allow it for this site.

    Phones and other devices

    An https page can reach 127.0.0.1 but browsers block it from reaching plain http://192.168.x.x. To watch from a phone, open RuView's own UI on your LAN (set SENSING_ALLOWED_HOSTS and publish port 3000 on 0.0.0.0) or put the bridge behind a Cloudflare Tunnel with Cloudflare Access in front of it.

    Direct mode

    For an older server, or one started with RUVIEW_WS_LEGACY_UNAUTHENTICATED=1, choose Direct WebSocket and use ws://localhost:3000/ws/sensing. That flag turns off WebSocket auth, so only use it on a server bound to 127.0.0.1.

    What this bench is testing

    WiFi signals bend and reflect off bodies. A receiver that reads the fine-grained channel data can infer presence, motion and breathing without a camera.

    RuView (what you run)

    Open-source sensing from WiFi Channel State Information (CSI) captured by ESP32-S3 nodes. It reports presence, occupancy, motion, breathing and a heart-rate proxy, and runs locally with no cloud.

    Per its README: the live single-node pose model is first-cut, named-person identification is not shipped, and vitals are not medical-grade.

    github.com/ruvnet/ruview ↗

    BFId (the privacy warning)

    KIT researchers showed at ACM CCS 2025 that people can be identified from beamforming feedback, which devices send to routers unencrypted. In a 197-person test they reported near-100% accuracy, even for people carrying no phone.

    They frame it as a risk and call for safeguards in the upcoming IEEE 802.11bf standard.

    ScienceDaily article ↗

    Use it responsibly

    • Sense only spaces you control, and tell the people in them.
    • Keep the server bound to 127.0.0.1 and the API token set.
    • Recordings of breathing and movement are sensitive personal data. Delete what you don't need.