Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Status & diagnostics

This page explains how to see what each service of a device is doing and how that differs from configuring it, using rohi. Nothing here is specific to a module: the device describes its services, sections and actions, and the tool shows them. How a firmware reports status is in Status.

Commands

rohi status                       # device health and one row per service: one compact request
rohi status network                  # one service: values with units, active issues
rohi status --watch               # reprint when something observable changed (Ctrl-C to stop)
rohi status network --watch --interval 5
rohi -o json status network

Services are discovered from the device, so rohi status <name> works for any service the summary lists. Without a service the output is the summary table; with -o json it is { "device": .., "uptime_ms": .., "health": .., "services": [..] }. The sections below explain state, health, readiness, issues and revisions.

Four questions, four places

Capability    what can this firmware do?          (kept for runtime operations, e.g. firmware update)
Config        what is it set up to do?            persistent, desired state      rohi config ...
Status        what is it actually doing now?      live, observed state, read-only rohi status ...
Actions       what can I ask it to do?            explicit operations            rohi action ...
Diagnostics   what happened before?               logs, history                  (separate concern)

The same service appears in several places, never mixed:

$ rohi config connectivity          # desired: what it is set up to do (defaults + your overrides)
enabled     true
node_id     42
interval_s  60 s
host        ingress.example.org
port        443

$ rohi status connectivity          # observed: what is happening now
Service:  connectivity
State:    running
Health:   degraded
Ready:    yes
Since:    34s

frames_created           212
frames_delivered         209
send_retries             7
frames_rejected          0
queue_depth              3
frames_without_location  212

Issues:
  WARNING  no_location  (34s)

The device summary

rohi status is one compact request: the device health and one row per service. It stays small however many fields a service has.

$ rohi status
Device:  altruist-urban-0.4.0 (urban-esp32c3)
Uptime:  2h 14m
Health:  degraded

SERVICE       STATE     HEALTH    READY  SINCE
network        running   ok        yes    2h 14m
connectivity  running   degraded  yes    34s
time          running   ok        yes    2h 13m
sensors       running   ok        yes    2h 14m
identity      running   ok        yes    2h 14m
location      disabled  -         no     -

State, health and readiness are three separate things, not one big status:

AnswersValues
Statewhere is it in its lifecycle?disabled, stopped, starting, running, stopping, failed
Healthhow well does it work?ok, degraded, error, or - (unknown)
Readycan it do its job right now?yes / no

So the same word means different things in different columns, and combinations carry information:

StateHealthReadyMeaning
runningokyesworking
runningdegradedyesworks, but something is wrong (telemetry without a location)
runningdegradednothe task runs, the backend does not answer
starting-noWi-Fi is still connecting
disabled-noturned off by configuration or never set: not an error
failederrornocrashed and not recovering

SINCE is how long the service has been in its current state.

Device health

Health: in the header is decided by the firmware, not computed by the tool. The firmware knows which services are mandatory, optional or redundant: a cellular modem may be degraded while Ethernet is fine. With the default policy a failed essential service makes the device error, a degraded service or a running service that is not ready makes it degraded, and disabled services do not count.

One service in detail

rohi status <service> adds the service-specific values the device describes (with their units) and the active issues:

$ rohi status network
Service:  network
State:    running
Health:   ok
Ready:    yes
Since:    2h 14m

ssid     office
rssi     -61 dBm
ip       192.168.1.42
gateway  192.168.1.1
dns      192.168.1.1

An issue has a stable machine-readable code (connection_timeout, no_location), a severity, a message and an age. Scripts react to the code, people read the message. Only issues that are active now are listed; history is diagnostics. With -o json the values are keyed by field name and carry their units:

$ rohi -o json status network
{
  "schema_version": 1,
  "service": { "service": "network", "state": "running", "health": "ok", "ready": true, ... },
  "values": { "ssid": "office", "rssi": -61, "ip": "192.168.1.42" },
  "units": { "rssi": "dBm" },
  "issues": []
}

Watching

$ rohi status --watch                 # reprint when something observable changed
$ rohi status connectivity --watch --interval 5

Every service has a status revision that changes when its state, health, readiness or active issues change. A summary watch polls the compact summary and prints again only when a revision (or the device health) moved, so it stays cheap. Values that vary all the time (counters, signal strength) do not change the revision; rohi status <service> --watch re-reads the detail on every poll and prints when what is shown changed. Stop with Ctrl-C.

Doing things: actions

Status never changes anything. Operations are actions, listed and described by the device:

$ rohi action
SERVICE   ACTION      PRIVILEGED
network   scan        no
network   reconnect   yes
network   disconnect  yes
identity  provision   yes
identity  erase       yes

$ rohi action network                  # the actions of one service, with their arguments
$ rohi action network scan --help      # arguments and results, from the device schema
$ rohi action network scan
SSID    RSSI     CHANNEL  SECURITY
office  -50 dBm  6        wpa2
guest   -70 dBm  11       open

Privileged actions need a link that satisfies the device’s authorization policy. Arguments are NAME=VALUE pairs; use NAME=- to read a value from stdin so it stays out of the shell history. Secret arguments, like the one of identity provisioning, are always read from stdin or a hidden prompt: rohi action identity provision secret=-.

Configuration

rohi config lists the sections of the device, shows the effective configuration of a section (the firmware defaults with your explicit overrides applied) and changes overrides with patches that are applied atomically per section. Secrets are write-only. It is covered on Configuration; the rules are in Service pipeline.

What the services are

ServiceWhat it reportsTypical issue codes
wificonnection state, network, signal, channel, radio heapauthentication_failed, network_not_found, association_failed
networkIPv4 address, gateway, DNS, address mode, socket usagedhcp_failed
bleperipheral state, advertised name, link securitydriver_error
connectivitytelemetry queue and countersconnection_timeout, unauthorized, no_identity, no_utc_time, no_location
timewall-clock time, source, age, failuresnetwork_unavailable, timeout, implausible
sensors<sensor>.<measurement> values in canonical unitsbmx280_error, sds011_degraded, …
identityprovisioned or not, public keynot_provisioned
locationwhere the device is and where that comes from (Location)not_set

A firmware may offer more or fewer; rohi status shows what the connected device really has. Adding a service needs no change to the tool: Add a service.