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-rswhile the published crate iscsi-webclient. Theesp-csi-webclient-rsspelling 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
| Tab | What it is for |
|---|---|
| Devices | Fleet overview, per-device start/stop, refresh, and the event log |
| Dashboard | Per-device status, firmware identification, and stream counters |
| Config | Every per-device configuration endpoint, as a form |
| Control | Start and stop collection; connect and disconnect the WebSocket |
| Stream | Frame 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.
Relevant Links & Resources
- Crate:
csi-webclienton crates.io - Source: csi-rs/csi-webclient-rs
- The client’s own view of the API is
docs/HTTP_API.mdin the repository.