initial commit
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
**RMon** is a real-time data monitor and plotter for distributed control systems accessed over SSH. The UI runs locally; data is acquired by a remote agent. See `usecase.md` for requirements and `docs/` for full specs.
|
||||
|
||||
## Language and Tech Stack
|
||||
|
||||
**Rust throughout** — single language for agent, UI, and shared types.
|
||||
|
||||
| Crate | Role | Key deps |
|
||||
|-------|------|----------|
|
||||
| `rmon-common` | Shared types, protocol message enums | `serde`, `bincode` |
|
||||
| `rmon-agent` | Remote data acquisition server | `tokio`, `tracing`, `anyhow`, `toml`, `serde` |
|
||||
| `rmon-ui` | Operator desktop application | `egui`, `eframe`, `egui_plot`, `tokio`, `tracing` |
|
||||
|
||||
## Build Commands
|
||||
|
||||
```sh
|
||||
# Build everything (debug)
|
||||
cargo build
|
||||
|
||||
# Build the agent as a fully static binary (primary deployment target)
|
||||
cargo build --release --target x86_64-unknown-linux-musl -p rmon-agent
|
||||
|
||||
# Build agent for ARM (e.g. remote Raspberry Pi)
|
||||
cargo build --release --target aarch64-unknown-linux-musl -p rmon-agent
|
||||
|
||||
# Build the UI for the current platform
|
||||
cargo build --release -p rmon-ui
|
||||
|
||||
# Run tests
|
||||
cargo test
|
||||
|
||||
# Run tests for a single crate
|
||||
cargo test -p rmon-common
|
||||
cargo test -p rmon-agent
|
||||
|
||||
# Run a single test
|
||||
cargo test -p rmon-agent sources::csv::tests::parse_timestamp
|
||||
|
||||
# Lint
|
||||
cargo clippy --all-targets --all-features
|
||||
|
||||
# Format
|
||||
cargo fmt
|
||||
```
|
||||
|
||||
## Architecture (short version)
|
||||
|
||||
Two executables communicate via a binary TCP protocol over an SSH tunnel:
|
||||
|
||||
- **`rmon-agent`**: runs on the remote machine, acquires data from heterogeneous sources (CSV, UDP, EPICS…), stores it, streams it to connected clients. Built as a fully static musl binary — single file, zero runtime deps, `scp` + run.
|
||||
|
||||
- **`rmon-ui`**: runs on the operator's local desktop. Manages the SSH tunnel automatically (uses the system `ssh` binary + user's `~/.ssh/config`). Renders real-time plots with `egui`/`egui_plot`.
|
||||
|
||||
- **`rmon-common`**: library crate shared by both. Contains all types (`SignalId`, `SignalInfo`, `Sample`, `StorageMode`) and the `ClientMessage`/`AgentMessage` protocol enums serialized with `bincode`.
|
||||
|
||||
Full architecture: `docs/architecture.md`
|
||||
Wire protocol: `docs/protocol.md`
|
||||
Data model: `docs/data-model.md`
|
||||
Agent config and source trait: `docs/agent-spec.md`
|
||||
UI layout and state machine: `docs/ui-spec.md`
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
- **Protocol framing**: `[u32 LE length][bincode payload]` — no gRPC/HTTP overhead. Both sides are Rust so `bincode` + shared enum types is simplest.
|
||||
- **Agent portability**: `x86_64-unknown-linux-musl` gives a fully static binary requiring only Linux kernel ≥ 3.2. The agent never has a GUI, so no X11/GL needed.
|
||||
- **Remote access UX**: The UI deploys the agent binary via SSH itself (like VSCode Remote). Users only need to enter their SSH host alias; existing `~/.ssh/config` (including `ProxyJump`) handles multi-hop routing.
|
||||
- **UI rendering**: `egui` immediate-mode with `glow` (OpenGL 2.1) backend. For signals with more points than screen pixels, min-max downsampling runs on the CPU before drawing.
|
||||
- **Timestamps**: all source timestamps are normalized to `i64` nanoseconds since Unix epoch inside the source adapter. The rest of the codebase only sees `i64`.
|
||||
- **Concurrency (agent)**: one tokio task per data source → `broadcast` channel → dispatcher fans out to storage writers and per-client session tasks.
|
||||
- **UI/async boundary**: tokio runtime in a background thread; egui on main thread. `std::sync::mpsc` channels carry `UiEvent` (agent→UI) and `Command` (UI→agent).
|
||||
|
||||
## Adding a New Data Source
|
||||
|
||||
1. Create `rmon-agent/src/sources/{name}.rs`
|
||||
2. Implement the `DataSource` trait (`name()`, `signals()`, `async fn run(self, tx)`)
|
||||
3. Add a new variant to `SourceConfig` in `config.rs` and construct it in `sources/mod.rs`
|
||||
4. Add config example to `docs/agent-spec.md`
|
||||
|
||||
## Protocol Changes
|
||||
|
||||
All protocol types live in `rmon-common/src/protocol.rs`. Since `bincode` is not self-describing, any change to `ClientMessage` or `AgentMessage` requires a protocol version bump in the `Handshake` message and both sides must be rebuilt together.
|
||||
Reference in New Issue
Block a user