Device Management - Kush-Kelaiya22/imPress GitHub Wiki

Device Management

How to watch and look after classroom devices: presence, health states, diagnostics, device keys, the student module inventory, and enabling or disabling a device. The page is Modules in the admin menu. Reference: docs/api/device-api.md.

Contents


The Modules page

The top of the page has four counters:

Counter Counts
Total devices every registered gateway and hub
Connected devices currently online
OTA pending devices with an update pending
Need attention devices in the ERROR or DEGRADED health state

Below it, the All devices table:

Column Shows
Device name and MAC address
Type c6 (gateway), s3 (hub)
Health the health state badge, with its reasons underneath; disabled if switched off
Firmware the running version; ✓ verified if an admin stamped it
OTA the pending version and its state, or up to date
Assigned class the class this gateway serves
Students (C6) students currently online on this gateway's mesh
RAM free / Flash total the gateway's latest report
Actions Diagnostics, Push OTA, Verify

Then the Student modules seen by gateways card: the inventory.

Presence

Device Online when Offline / "seen" after
Gateway, hub any contact: registration, heartbeat (every 15 s), status ping (every 2 min), WebSocket message 30 s of silence
Student module a join, a heartbeat (every 30 s), or a relayed message 90 s of silence (three missed heartbeats), or an explicit leave

The presence sweep runs every 15 s and makes these changes. Each change to online or offline is written to the activity log once (esp_device.online, esp_device.offline), not on every heartbeat. Teachers' class pages get a fresh snapshot on every change, and poll every 5 s as a fallback.

Health states

A gateway's health is computed from its latest values every time it is shown. The first rule that matches wins:

State When Badge
UNKNOWN never seen outline
OFFLINE silent for more than 30 s grey
UPDATING an OTA update is in progress for it blue
ERROR the last OTA update failed (failed, rolled_back, timed_out, unreachable), or it reset because of a panic, int_wdt, task_wdt, wdt or brownout in the last 10 minutes red
DEGRADED its hub link is down, or Wi-Fi signal is below −80 dBm, or its lowest free memory since boot is below 20 KB amber
ONLINE none of the above green

The reasons are listed under the badge in plain words, for example reset by task_wdt 2 min ago, S3 link down, weak Wi-Fi (-83 dBm) or last OTA update rolled back.

Order matters: an offline device shows OFFLINE even if its last report was a crash, because you can't know more until it comes back. A device that is updating shows UPDATING, not DEGRADED.

When an ERROR clears:

  • Caused by a crash: after 10 minutes of uptime.
  • Caused by a failed update: only after a later update succeeds.

Rules source: backend/app/services/health.py, tested rule by rule in backend/tests/test_health.py.

Diagnostics

Diagnostics on a device opens a read-only panel, with Refresh and Reset key:

Row Meaning
Health the state and reasons
Last seen when it last contacted the backend
Firmware the running version
Uptime time since its last boot
Last reset why it last restarted (table below)
Boots boots since its first flash. A rising count with short uptimes means a reset loop
Wi-Fi signal RSSI in dBm (−50 excellent, −70 fine, below −80 weak)
Free heap (now / lowest) current free memory, and the lowest since boot
S3 link up (with the hub's uptime) or down. Up means the hub's own heartbeat arrived over SPI in the last 15 s
Reported when these values arrived
Device key own key (active, since when) · issued (not used yet) · shared key

Reset reasons:

Value Meaning Usual cause
poweron power applied normal start, or power cut
external reset pin someone pressed reset
software the firmware restarted itself after an OTA update; a configuration change
panic a crash a firmware bug: capture the serial log
int_wdt, task_wdt, wdt a watchdog fired a task stuck or starving the CPU
brownout the supply voltage dipped a weak power supply or cable
deepsleep woke from deep sleep not used by imPress
other anything else

Firmware older than v2.1 doesn't send diagnostics; its fields show not reported, and the rules that need them don't apply. The panel only reads: diagnostics add no remote control over devices.

The hub doesn't send its own reset reason or memory yet. Only the gateway does, along with the hub link state and the hub's uptime.

Device keys

Every device starts with the site's shared key. When it registers, the backend issues it its own key, and from then on the device uses that key. The Diagnostics panel shows the state:

stateDiagram-v2
    [*] --> shared: no key of its own
    shared --> issued: registers with the shared key → the response carries its key
    issued --> issued: registers again before using it (a lost response) → a new key replaces it
    issued --> active: first request made with its own key
    active --> shared: an admin clicks Reset key
State What it means for security
shared key the device still uses the shared key; anyone with that key can act for it
issued a key was issued but never used; the shared key still works for this device
active only this device's key can act for it, and that key works for no other device

Reset key (after a confirmation):

  1. The device's current key stops working at once.
  2. On its next request the device gets 401, drops its key, registers again with the shared key, and is issued a new one.

Use it when a device was reflashed (its flash, and so its key, was erased) or when a key may have leaked.

When every device shows own key, set IMPRESS_DEVICE_KEYS_REQUIRED=true. The shared key then only works for registration (Security).

Disabling a device

Switching a device's access off (admin) refuses every request for that device, whichever key it presents, and excludes it from deployments. Other devices are unaffected. Switching it back on restores it; its key is kept.

Student module inventory

The Student modules seen by gateways card lists every student module any gateway has heard:

Column Meaning
Device ID the module's 32-bit ID in hex (from its MAC). Older firmware that sends no ID shows — and is keyed by enrollment number
Enrollment the student identity the module last announced
State connected, or seen N ago (after a leave or 90 s of silence)
Class the class of the gateway that heard it, and its section
Gateway which gateway relayed it
Last seen how long ago
Battery as reported (currently always 100 % on student modules)

You can filter by state and class, and search by device ID or enrollment number (partial matches, any case).

Properties:

  • One row per module. A module that reconnects, or moves to another room, keeps its row; its gateway and class update.
  • No history: the inventory records presence, not location over time, by design.
  • Deletes: erasing a student keeps the module's row but removes the enrollment number. Deleting a class keeps the rows but unlinks them.
  • Teachers see their own class's modules in the Live Devices panel; the full inventory is admin-only.

Linking a gateway to a class

Method How
Room code (recommended) set the class's Room Label (classroom_code, e.g. RM-201) and have the gateway register with it. The smoke test does exactly this
Automatic a gateway that registers without a code links itself to the first active class without a gateway (lowest id). Good for a single room; unpredictable with many
By an admin the link and unlink actions in the API (/api/admin/modules/{id}/link-device, /unlink)

A hub is linked to its gateway (gateway_id) so that OTA prompts for the hub can be delivered through that gateway.

Reading the signs: worked examples

What you see Likely cause Action
ERROR · reset by brownout 3 min ago; Boots rising the power supply sags under Wi-Fi bursts a better 5 V supply and a shorter, thicker cable
DEGRADED · S3 link down; students not reaching the backend the hub is off, unplugged or crashed, or the SPI wiring is loose check the hub's power and the 6 signal wires plus ground
DEGRADED · weak Wi-Fi (-84 dBm) the gateway is far from the access point move the gateway, or add an access point
DEGRADED · low memory a memory leak or overload capture the serial log; note the firmware version; report it
ERROR · last OTA update rolled back the new image couldn't reach the backend within 120 s and the old one booted see Recovery Procedures
OFFLINE, last seen hours ago power off, or the Wi-Fi credentials changed check power; check the NVS Wi-Fi settings
Gateway online, inventory empty during class modules unprovisioned (NO ID), wrong mesh channel, or hub down check a module's screen; the hub link state
shared key on a device running v2.1 firmware it hasn't registered since the backend upgrade it will at its next boot or reconnect; or restart it