Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

csi-webclient

csi-webclient is the operator’s end of the pair. It is a native desktop application — egui/eframe — that connects to a running csi-webserver over HTTP and WebSocket, discovers whatever boards that server has found, and gives you a place to configure them, start and stop collection, watch frames arrive, and record captures locally.

Together the two are the shortest path from a board to something you can drive and look at: the webserver moves frames off the host’s serial ports, and the webclient is where a person actually works.

The published crate is at 0.2.1 at the time of writing, with the repository ahead at 0.3.0. It targets csi-webserver 0.1.5 or newer — the multi-device API.

Naming. As with the webserver, the repository is csi-webclient-rs while the published crate is csi-webclient. The esp-csi-webclient-rs spelling used in earlier drafts does not exist on crates.io.

Running It

cargo build --release
cargo run --release

On start, set the host and port in the top bar to match your webserver — the default is 127.0.0.1:3000 — and click Connect. From there the client polls for attached devices roughly every two seconds, so boards appear and disappear as they are plugged in and out.

The Five Tabs

TabWhat it is for
DevicesFleet overview, per-device start/stop, refresh, and the event log
DashboardPer-device status, firmware identification, and stream counters
ConfigEvery per-device configuration endpoint, as a form
ControlStart and stop collection; connect and disconnect the WebSocket
StreamFrame counters, hex previews, and local Parquet recording

Selecting several devices — from the Devices tab or the top-bar combo box — drives the detail tabs side by side, which is how you compare two nodes of a pairing without switching back and forth.

What It Adds Over curl

Anything the client does can be done by hand against the server’s HTTP API. Four things are enough easier here that they are worth calling out.

Fleet operations. Start All and Stop All act across every discovered device, and multi-select gives synchronized collection across a set of boards. For a multi-receiver measurement, starting nodes one curl at a time introduces exactly the skew you were trying to measure.

Pairing presets. The Devices tab applies two-device presets — a softAP lab pair, or an HT20/HT40 emitter plus a sniffer — in one action. These are the arrangements from Crates & Libraries, pre-wired so the channel and mode on both ends agree without you checking twice.

Local Parquet export. The Stream tab records to csi_export_{id}_YYYYMMDD_HHmmss.parquet, with a schema matching the server-side dumps described in the webserver section. The difference is where the file lands: server dumps are written next to the server, these are written next to you.

Configuration snapshots. Device configuration saves and loads as JSON (csi_config_{id}_YYYYMMDD_HHmmss.json), and the Config tab can copy a configuration from one device to another — the quickest way to bring a second board into line with a first.

Those snapshots contain Wi-Fi passwords in plain text. They are convenient to check into a lab notebook and a poor thing to check into a repository.

Configuration Surface

The client exposes the server’s full per-device surface: the emitter and collector Wi-Fi modes (station, sniffer, wifi-ap, ht20-emitter, ht40-emitter) with their softAP options, traffic frequency, CSI acquisition flags, the CSI-output gate, delivery mode, PHY rate and protocol, the I/O task toggles, and the stream / dump / both output-mode switch.

There is no log-mode control, and its absence is deliberate: the server always runs devices in the serialized format, because that is the format it decodes. The hex previews in the Stream tab are the raw COBS + postcard frames described in CSI Data Formats, shown before decoding precisely so that a malformed stream is visible as bytes rather than as a silent absence of rows.

Architecture

The codebase keeps three domains deliberately separate, which is worth knowing before contributing:

  • src/state — the source of truth for application data and UI-visible state.
  • src/ui — rendering only; no network calls and no orchestration.
  • src/core — side effects: HTTP requests, the WebSocket loop, the async runtime, and the channels between them.
  • src/export — the host-side serialized CSI decoder and the Parquet writer.

Intent orchestration and event application happen in src/app.rs, and nowhere else.