Aether is a small Rust application that simulates sensor readings and displays them in a real-time Raylib dashboard.
- Load any number of sensors from a YAML config, each with an arbitrary
list of named metrics carrying units (
temperature (C),pressure (hPa), ...) - Adaptive card grid: each metric renders as a chip with its value, sparkline, and up/down change indicator
- Card detail view with large trend lines and min/avg/max stats per metric
- Tabbed navigation: a tab holds as many cards as fit the window;
overflow goes to numbered tabs (
1 2 ... N), clickable and bound toAlt/Cmd + 1..9 - Settings modal to toggle trend lines, value animation, and change indicators at runtime
- Fixed-slot task scheduler decoupled from data handling
- Bounded per-sensor reading history (ring buffers)
- Unit tests for configuration, history, scheduler, sensor, and dashboard layout modules
- Rust toolchain (rustup)
Raylib and serde-yaml are pulled in automatically by Cargo. On Linux the raylib build additionally needs the X11/OpenGL development headers, e.g.:
sudo apt-get install cmake libx11-dev libxrandr-dev libxi-dev \
libxcursor-dev libxinerama-dev libgl1-mesa-dev libglu1-mesa-dev \
libasound2-devmacOS needs nothing beyond the Xcode command-line tools.
Build the application:
cargo build --releaseRun it:
cargo runBuild and run all unit tests:
cargo testThe test suite covers:
- sensor initialization and simulated updates;
- reading history ordering, oldest-entry eviction, and metric statistics;
- task scheduling;
- YAML configuration loading, including malformed input, unknown keys, missing ids, and growing registries;
- dashboard layout math: tab capacity, pagination limits, and range mapping.
Sensor data is loaded from:
config/sensors.yaml
Example:
sensors:
- id: 1
name: temperature_sensor
metrics:
- name: temperature
unit: C
value: 22.5
- name: humidity
unit: "%"
value: 45Each sensor requires:
| Field | Description |
|---|---|
id |
Unique numeric sensor identifier |
name |
Readable sensor name |
metrics |
List of metrics, each with name, unit and value |
Note: a % unit must be quoted ("%") because YAML reserves the percent sign.
| Input | Action |
|---|---|
| Click the cogwheel (top right) | Open/close the settings modal |
| Click a card | Open that sensor's detail view |
| Click a numbered tab (bottom) | Jump to that tab |
Alt/Cmd + 1..9 |
Jump directly to tab N |
← / → |
Previous / next tab |
Esc |
Close the detail view or settings modal |
.
├── assets/fonts/ Bundled font (JetBrains Mono, SIL OFL)
├── config/ Sensor configuration YAML
├── docs/ Screenshots and demo media
├── src/config.rs YAML config parsing (sensor registry and settings)
├── src/sensor.rs Sensor data types and simulation
├── src/history.rs Bounded per-sensor reading history (ring buffer)
├── src/scheduler.rs Periodic task scheduling
├── src/layout.rs Raylib-free layout and formatting math
├── src/theme.rs Theme tokens and presets
├── src/dashboard.rs Dashboard rendering (Raylib)
├── src/main.rs Application entry point
└── Cargo.toml Build and dependency manifest
sensors.yaml
│
▼
configuration parser
│
▼
sensor registry ◄── scheduled sensor tasks (update in place)
│ │
▼ ▼
Raylib dashboard per-sensor reading history (ring buffers)
This project is licensed under the MIT License.


