Skip to main content

Crate pamoja_dashboard

Crate pamoja_dashboard 

Source
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:

  • State is the language-neutral fleet snapshot served at GET /state: Orgs of Groups of Sensors, each group on its own Link.
  • StateSource is the one seam between the dashboard and its data; a real gateway and the Mock both implement it.
  • Mock serves a deterministic Scenario so the whole dashboard runs and is debugged with no hardware.
  • Server serves 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, and tier-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 (the locale-* features, English always included); the page learns the embedded set from GET /locales and 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 to GET /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.
ElementSpec
A custom sensor or node stat a profile contributes to the dashboard.
EventRecord
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.
FleetBuilder
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.
AuthError
Why a control request was refused. The code is a stable, language-neutral string the page localizes.
Command
A control action a client asks the node to take.
CommandError
Why a command could not be carried out. The code is a stable, language-neutral string the page localizes.
EventLevel
The severity of a telemetry event, mirrored onto the wire as a stable string.
LinkKind
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§

StateSource
Produces the current State snapshot whenever the dashboard asks for one.