# RuView — WiFi CSI spatial-intelligence nodes (Phase 2) Real upstream project: **[github.com/ruvnet/ruview](https://github.com/ruvnet/ruview)** — a WiFi Channel-State-Information (CSI) platform that detects presence, tracks movement/pose, and infers semantic room states (see §2 below) through walls, without a camera. **This repo does not reimplement any of RuView's CSI firmware or signal processing** — that's genuine DSP research code (Rust + ESP-IDF, running on-device), and fabricating it from scratch rather than integrating the real thing would be exactly the kind of guess this project's own conventions exist to avoid. What lives in this directory is a thin, honest wrapper around RuView's own tooling, matching how this repo already treats Frigate/ Zigbee2MQTT/Grocy — integrated, not forked. This is a different device from `firmware/esphome-ble-proxy/` — separate hardware, separate job, per `docs/project-plan.md` §1.5's "separate hardware from RuView nodes" note. BLE proxies resolve *who* (via Bermuda/Private BLE Device); RuView nodes sense *room activity/vitals*, camera-free. ## 1. Hardware Per RuView's own README (confirmed via the link above, not guessed): | Board | Price | Role | |---|---|---| | **ESP32-S3** | ~€9 | Primary target — CSI capture + edge processing | | ESP32-C6 | €6–10 | Research variant, WiFi 6 + dual-band | | Intel 5300 / Atheros AR9580 (research NICs) | €50–100 | Higher-fidelity research hardware, not a household pick | | Cognitum Seed (optional) | ~€140 | Persistent storage / vector search / witness-chain, not required for basic presence | **ESP32-C3 and the original ESP32 are explicitly NOT supported** (RuView's own README: "single-core, insufficient for CSI DSP") — this updates `docs/project-plan.md` §1.6's original "ESP32-S3 dev board" pick from a general recommendation to a confirmed hard requirement. ## 2. What it publishes — and why that's more sensitive than plain presence RuView ships **21 MQTT entities per node** via its own `HA-DISCO` MQTT auto-discovery publisher: 11 raw signals plus 10 inferred semantic states — `someone-sleeping`, `possible-distress`, `room-active`, `elderly-inactivity- anomaly`, `meeting-in-progress`, `bathroom-occupied`, `fall-risk-elevated`, `bed-exit`, `no-movement`, `multi-room-transition`. It can also estimate breathing/heart rate. **This is a meaningfully bigger privacy surface than the plain occupancy sensor `docs/project-plan.md`'s original Phase 2 sketch assumed.** Bathroom-occupancy, sleep state, and vitals-adjacent inference are the kind of data this project has otherwise been careful about (see `identity/README.md`'s "Anti-spoofing" and "People without a device" sections for the same care applied to identity/consent). **Nothing in this repo currently gives household members a way to opt out of a specific room's RuView sensing, or restricts who these MQTT topics are visible to beyond the same trust boundary as every other entity on this network.** Treat this as an explicit open decision (`docs/project-plan.md` §4) before wiring automations against the more sensitive semantic states, not something silently safe by default just because the network is local. ## 3. Build + flash — RuView's own tooling, not this repo's This repo does not vendor RuView's source. Clone and build it yourself per its own README: ```sh git clone https://github.com/ruvnet/ruview ~/ruview cd ~/ruview # Rust 1.85+ and the ESP-IDF toolchain are prerequisites — see RuView's own docs idf.py set-target esp32s3 # or esp32c6 for that variant idf.py build python -m esptool --chip esp32s3 --port /dev/ttyUSB0 --baud 460800 write_flash ... ``` **VERIFY the exact build/flash command against whatever version you actually clone** — the commands above are transcribed from RuView's own README as fetched during this session, not independently run against real hardware from within this project; upstream commands/flags can and do change between releases. ## 4. Provisioning per room — `provision-room.sh` Once a node is flashed, it needs Wi-Fi + this stack's MQTT broker credentials. RuView ships its own `firmware/esp32-csi-node/provision.py` for this; `provision-room.sh` in this directory is a **thin wrapper** that fills in this project's own settings (same Mosquitto broker every other service already uses, Phase 1) so you don't retype them per node: ```sh cp rooms.env.example rooms.env # fill in RUVIEW_REPO_DIR, Wi-Fi, MQTT_BROKER_HOST chmod 600 rooms.env ./provision-room.sh living-room /dev/ttyUSB0 ``` Only `--port`/`--ssid`/`--password`/`--mqtt` are passed by the wrapper — those four flags are the ones confirmed against RuView's own README during this session. **Anything else `provision.py` might need in your specific installed version (MQTT auth flags, a node-naming flag, etc.) is NOT guessed here** — pass it as an extra argument to `provision-room.sh` after checking `python3 ~/ruview/firmware/esp32-csi-node/provision.py --help` against your real checkout first. ## 5. Automations built on RuView's semantic states You've confirmed you want these wired up despite §2's privacy note — the concrete rules requested, all in `automations.yaml.example` (paste whichever ones you want into your own HA config, same "nothing under this repo merges into your HA config for you" convention as identity's own worked `rest_command` example): 1. **Someone asleep → dim that room's lights.** Straightforward state trigger → `light.turn_on` at low brightness/warm color temp. 2. **Possible distress → alert everyone home.** Mapped to RuView's own `possible-distress` semantic state — **this is RuView's closest documented inference to "a heart attack," there is no literal heart-attack-detection entity, and this repo does not build its own medical-anomaly detection on top of RuView's raw signals.** The automation bridges that state to an urgent `ntfy` push (via a `rest_command:`, same pattern as every other ntfy-posting service in this stack) plus a whole-house TTS announcement across every `media_player` you list, plus flashing every light red as a visual backup. Whatever RuView's real accuracy turns out to be is entirely upstream's, not something this bridge changes — **do not treat this as a substitute for an actual medical alert device/service.** 3. **Two people's heart rate elevated concurrently in the same room → red/ magenta/violet lighting.** Approximated as "both above an elevated threshold at the same time" rather than a true rate-of-change trigger (deliberately — derivative triggers on noisy CSI-derived vitals are far more false-trigger- prone than a plain threshold). **This is the single most uncertain rule in this file**: RuView's fetched README doesn't confirm whether one node can actually distinguish and report two distinct people's heart rates concurrently at all — multi-target vital-sign separation from WiFi CSI is a genuinely hard, actively-researched problem. Confirm you have two real per-person heart-rate entities for a room before trusting this can fire as described; if there's only one aggregate entity per node, this rule needs a different design once you know that, not a guess made now. 4. **Bathroom occupied → an external indicator outside the door.** You mentioned you'll likely add a dedicated light/actor for this — the automation targets a placeholder `switch.bathroom_door_indicator`; swap it for whatever you end up choosing (worth adding to `components.md`'s Zigbee list once picked, same as every other Zigbee actuator in this project). **Every `entity_id` in `automations.yaml.example` is a placeholder** — RuView's README documents semantic-state *names*, not their exact post-MQTT-discovery HA `entity_id`s (domain, underscore-vs-hyphen, per-node naming). Confirm every one against Developer Tools → States on a real HA instance after provisioning a real node before relying on any of this. ## 6. Home Assistant integration — likely nothing to build, but unverified RuView's `HA-DISCO` publisher uses MQTT auto-discovery against the **same Mosquitto broker** every other service in this stack already connects to (Phase 1) — if that's accurate, entities should appear in HA automatically once a node is provisioned and online, no manual entity/automation setup required to just *see* the data. RuView's own docs reportedly include `docs/integrations/home-assistant.md` and three starter HA Blueprints (per its README) for turning the semantic states into actual automations — **none of that has been read in detail or verified from within this project**, only the top-level README summary this section is built from. Confirm the real doc before wiring anything beyond "the entities show up." Same "nothing under this repo builds the HA side" convention as every entry in `docs/project-plan.md`'s HA-integrations catalog (§2) — automations against RuView's semantic states are a decision for you to make deliberately, especially given §2's privacy note above, not something this repo pre-wires. ## Manual verification still outstanding 1. Nothing here has been run against real hardware, a real RuView checkout, or a real MQTT broker from within this project — §3's build commands and §4's `provision.py` flags are transcribed from RuView's own README, not independently confirmed. 2. `docs/integrations/home-assistant.md` / RuView's HA Blueprints (§6) — described secondhand from the top-level README, not read directly. 3. The privacy/consent gap in §2 — the household-level decision has been made (you want this data and the automations built on it), but there is still no technical opt-out for a specific person/room, and no access restriction on these MQTT topics beyond this network's normal trust boundary. Worth revisiting if anyone who isn't fully on board with being sensed this way ever stays over. 4. `docs/project-plan.md` §1.6/§2's RuView entries — updated this session to match §1 above (ESP32-C3/original-ESP32 unsupported, real hardware tiers), but the phased implementation plan (Phase 2) itself still describes RuView only at the "deploy nodes per room" level of detail from before this integration pass. 5. **`automations.yaml.example`'s entity_ids are ALL placeholders** — none of §5's four automations have been run against real RuView entities; in particular rule 3 (concurrent two-person heart rate) rests on an unconfirmed assumption that a single node can even report two people's heart rates at once, see that automation's own prominent warning comment.