Expand description
Local-first dashboard for a pamoja node.
A node serves its own dashboard over its own WiFi hotspot, so a clinic worker, a farmer, or a water committee sees their own data with no internet at all, in their own language, on whatever cheap phone they have. This crate is the host side of that: it turns the state a node already holds into a small, language-neutral snapshot and serves a hand-built, localized page that renders it.
The design rests on one split. The device emits only a State - stable keys,
stable codes, raw values, and canonical units, identical in every locale - and the
page does all rendering, formatting, and translation at the surface. That keeps the
device’s job tiny enough for constrained hardware and the page’s job rich enough to
be beautiful, and it means localization is a property of the page, not a fork of
the data.
The pieces:
Stateis the language-neutral fleet snapshot served atGET /state:Orgs ofGroups ofSensors, each group on its ownLink.StateSourceis the one seam between the dashboard and its data; a real gateway and theMockboth implement it.Mockserves a deterministicScenarioso the whole dashboard runs and is debugged with no hardware.Serverserves the page, the snapshot, and a live event stream over plain TCP.
§Capability tiers
One design serves hardware from a Raspberry Pi to a microcontroller, chosen with a
compile-time tier feature. The /state contract is identical across all of them, so a
page written for one tier reads another tier’s data:
- Tiers A and B (
tier-a, the default, andtier-b) embed the full localized app: the hand-built visuals, history, authenticated control, and the seed locales. A Tier B build trims flash by embedding only the locales it needs (thelocale-*features, English always included); the page learns the embedded set fromGET /localesand offers only those languages. - Tier C (
tier-c) embeds only a single self-contained floor page for the smallest hardware. It renders the status table with the smallest possible script, and when scripting is off entirely it falls back toGET /lite, a server-rendered, meta-refreshing table with no script at all. It is plain, but it is legible and it works on any browser.
Build a non-default tier with --no-default-features, for example
--no-default-features --features "serve,tier-c". Each tier’s gzipped page-load budget
is enforced by cargo xtask dashboard footprint.
§Examples
A device turns the state it holds into the language-neutral snapshot the page fetches:
use pamoja_dashboard::{State, Status};
let state = State {
orgs: Vec::new(),
status: Status::Alarm,
uptime_secs: Some(3600),
demo: false,
};
let json = state.to_json().expect("serialize");
assert!(json.contains("\"status\":\"alarm\""));The hardware-free Mock fleet (the mock feature) implements StateSource the same
way a real node does, so the whole dashboard runs and is debugged with no hardware.
Structs§
- Auth
- Gatekeeper for control actions: it issues pairing challenges and verifies commands.
- Catalog
- The presentation catalog served at
GET /catalog. - Challenge
- A pairing challenge handed to a client in the clear.
- Element
Spec - A custom sensor or node stat a profile contributes to the dashboard.
- Event
Record - One recent telemetry event, carried as a stable code the page localizes.
- Fleet
- A real fleet a project fills and the dashboard renders. Clone to share one between the serving layer and the sampling loop.
- Fleet
Builder - Builds a fleet’s initial structure: organizations, their groups, and each group’s sensors. Parents are referenced by id, so add an org before its groups and a group before its sensors.
- Group
- A group of sensors sharing one node and one link, such as a clinic’s fridges.
- Link
- A group’s connectivity: what it talks over, how strong it is, and whether it is up.
- Mock
- A deterministic, hardware-free fleet that serves a
Scenario. - Org
- An organization, such as a health authority or a farming co-op.
- Presentation
- How a profile presents itself on the dashboard: its custom elements and theme.
- Reading
- A single measured value, named by a stable key and a canonical unit.
- Sensor
- A single sensor: its current reading, recent history, power, and recent events.
- Server
- The dashboard HTTP server, generic over whatever produces its state.
- State
- The complete language-neutral fleet snapshot served at
GET /state. - Theme
- A small set of theme tokens a profile can set on the dashboard.
Enums§
- Assets
- Where the page assets come from.
- Auth
Error - Why a control request was refused. The
codeis a stable, language-neutral string the page localizes. - Command
- A control action a client asks the node to take.
- Command
Error - Why a command could not be carried out. The
codeis a stable, language-neutral string the page localizes. - Event
Level - The severity of a telemetry event, mirrored onto the wire as a stable string.
- Link
Kind - The kind of link a group reports over, shown as a labelled service before the bars.
- Mode
- The work cadence a node is running at, mirrored from
PowerMode. - Scenario
- A reproducible condition injected into the fleet for the dashboard to render.
- Scope
- Which groups a declared element is offered on when a user adds a sensor.
- Status
- The health of a sensor, group, or the whole fleet, the basis of the glance-first UI.
- Trend
- The direction a reading is moving, drawn as a trend arrow.
- Viz
- The graphic a reading is drawn with on the dashboard.
Traits§
- State
Source - Produces the current
Statesnapshot whenever the dashboard asks for one.