Buying the sensors is the easy part. This page is the part that actually matters: the tools you need, how to flash a sensor on your Mac or PC, get it on WiFi, have it talk to your Cognitum One Seed, and then bring in RuView to make sense of the data. Honest, step-by-step, no hand-waving.
Every WiFi sensor follows the same five-step path. Get this mental model first and nothing below is confusing.
This guide assumes you're working in VS Code with Claude Code. The simplest path: open your project, add RuView as a git submodule (next section), install the RuView plugin, and then mostly just tell Claude Code in plain English what you want — it flashes the nodes, sets their WiFi, and helps wire up the dashboard for you. (Having Ruflo installed adds extra orchestration, but it's not required.)
The exact commands below are "under the hood" — handy if you want to understand them or do it by hand, but you usually won't need to type them yourself.
Missing one of these is the #1 reason a beginner stalls for an evening.
| Tool | What it's for | Don't get this wrong |
|---|---|---|
| USB-C data cable | Connecting an ESP32 to your Mac/PC to flash it | Many cables are charge-only — they power the board but carry no data, so flashing silently fails. Buy one labelled "data". |
| A Mac or PC | Running the flashing tool | You flash once per node, then it runs on its own. |
| Your Cognitum One Seed (the host) | Receives the sensor streams — this is the brain | Give it the power supply specified for your model. Underpowering causes random dropouts that look like sensor failures. |
| Your WiFi name + password | The sensor needs to join your network | 2.4 GHz for ESP32-S3 & the MR60; 5 GHz for the ESP32-C5. They are not interchangeable. |
| The Seed's IP address | So the sensor knows where to send data | If the Seed's IP changes (DHCP), sensors "disappear" — reserve the Seed's address in your router. |
"Flashing" just means copying the sensor's program onto its chip over USB. Each of the three sensors is different — and one needs no flashing at all.
The USB kit is the simplest device here. There is nothing to flash. Plug its USB adapter into the Cognitum One Seed (or your Mac to test). The Seed reads its position data over a serial port at 256000 baud. Done. This is why it's the recommended first sensor.
It comes pre-loaded with ESPHome firmware, so you don't flash it — it just needs your WiFi credentials. The simplest way: ask Claude Code to provision its WiFi (ESPHome is what's running under the hood). Then the Seed connects out to it and pulls heart rate & breathing over TCP 6053.
The trap: the XIAO has two USB-C ports. The one on the case edge is power only. To configure it, open the case and use the XIAO's own inner USB-C port. ESPHome docs ↗
Easiest: with the RuView plugin loaded in Claude Code, just plug a node into your Mac/PC and ask. Type something like:
"Flash this ESP32-S3 as CSI node #1, join WiFi 'MyNetwork' / 'mypassword', and stream to my Seed at 10.0.0.50 on UDP 5005."
Claude Code (driving RuView) handles the toolchain, the config and the flash. Repeat for each node, bumping the number to 2, 3 … 7. Prefer to do it by hand? Here's exactly what's happening under the hood (Espressif's free ESP-IDF / esptool):
Install ESP-IDF 5.5.2 by following Espressif's official get-started guide. It brings the build tool idf.py and the flasher esptool. ESP-IDF Get Started ↗
Use a real USB-C data cable. It appears as a serial port (e.g. /dev/cu.usbmodem… on a Mac).
Open menuconfig and set: a node ID (1, 2, 3… one per board), your WiFi SSID + password, the Seed's IP, and the UDP port (5005). Then:
# for an ESP32-C5 node (5 GHz); use esp32s3 for S3 (2.4 GHz) cd firmware/esp32c5-csi-node idf.py set-target esp32c5 idf.py menuconfig # node ID, WiFi SSID/password, Seed IP, port 5005 idf.py build idf.py -p /dev/cu.usbmodemXXXX flash monitor
On the Seed, watch for its packets:
tcpdump -ni any udp port 5005 # expect ~10 packets/sec from the node
Flash each node with a different node ID. Repeat for 3+ nodes — a single CSI node can't locate anything.
If you added the M5StickS3, it's an ESP32-S3 board, so you flash it the same way (ESP-IDF / esptool) — or use M5's own no-code tool, UIFlow. Set your WiFi + the Seed's address, and it streams its IMU (motion/vibration) to the Seed over WiFi. It's the in-stock successor to the discontinued M5StickC PLUS2.
A point that confuses everyone: there are different ports for different jobs. Don't mix them up.
| Sensor | How it reaches the Seed | Port |
|---|---|---|
| ESP32 CSI nodes | Stream UDP over WiFi to the Seed | UDP 5005 |
| MR60BHA2 vitals | The Seed connects out and pulls from it | TCP 6053 |
| LD2450 radar | USB cable straight into the Seed (serial) | USB · 256000 baud |
Don't confuse the ports. Sensors send their data to the Seed — CSI on UDP 5005, vitals on TCP 6053. What the Seed sends back out to a dashboard is a separate connection — don't mix up the inbound sensor ports with the outbound one. Bands matter too: 2.4 GHz for the S3 & MR60, 5 GHz for the C5.
RuView (Ruv's open-source project) is the software that turns raw WiFi-CSI into presence, breathing, and the anonymous identity "fingerprint." Here's how to pull it in and build it. github.com/ruvnet/RuView ↗


So what is it? RuView is Ruv's open-source "ambient intelligence" software. It takes the raw WiFi-CSI your ESP32 nodes stream in and turns it into a live read of the room — presence, breathing, heart rate, a rough body pose, and an anonymous identity "fingerprint" — all on-device, no cloud. It's the brain-software that makes your sensor array actually mean something.
Clone it (simplest), or — if you're building your own project around it — add it as a git submodule so it's pinned inside your repo. Then build the Rust core:
# simplest — just clone it: git clone https://github.com/ruvnet/RuView # …or pin it inside your own project as a submodule: git submodule add https://github.com/ruvnet/RuView vendor/RuView git submodule update --init --recursive # then build it: cd RuView/v2 && cargo build --release
For the Python path, follow the repo's README rather than guessing a package name.
Optional: spin up the demo in Docker to see the interface on simulated data before you wire anything up.
docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 ruvnet/wifi-densepose:latest # open http://localhost:3000"The RuView plugin" is a Claude Code plugin — it gives an AI agent the skills and commands to drive RuView. Install it:
/plugin marketplace add ruvnet/RuView /plugin install ruview@ruview
(There's also a separate MCP server, @ruvnet/rvagent, and on-device "cogs" — those are different things; the plugin is the Claude Code one above.)
RuView's aggregator listens for the same CSI stream your nodes send (UDP 5005). It turns the WiFi into presence, breathing/heart rate, and a 128-number fingerprint of who/what is in the room.
Start here: README.md, then docs/user-guide.md and install.sh in the repo. Live demo: ruvnet.github.io/RuView ↗