View charger and device health
Use this runbook when you need a fleet-wide snapshot of every charger and NFC scanner Polaris Express is tracking — for a morning health check, when a customer reports a charger offline, or when you’re triaging a scanner that won’t arm. The /admin/devices page is the single surface that merges OCPP ChargeBoxes and iOS/macOS NFC scanners into one grid.
Prerequisites
Section titled “Prerequisites”- An admin account. Non-admin sessions are rejected with
403 Forbidden. - You’re signed in to the admin console at
/admin. - For owner-scoped scanner queries: the user’s owner ID (visible from
/admin/users).
Procedure
Section titled “Procedure”-
Open the Devices page
From the admin sidebar, click Devices. The page loads at
/admin/devicesand shows a stat strip across the top followed by a responsive card grid mixing chargers and scanners.If you bookmarked the old
/admin/chargersURL, it now302-redirects here with?type=chargerpreselected.Screenshot pending
Admin Devices listing with stat strip and card grid
-
Read the stat strip
The strip at the top of the page reports six aggregates over the currently filtered result set:
- Total — devices matching the active filters.
- Online — chargers whose normalized status is not
Offline, plus scanners that have sent a heartbeat in the last 90 seconds. - Offline — the complement of Online.
- Chargers — entries from the
chargerstable. - Scanners — entries from the
devicestable. - Unmanaged — chargers whose
managementModeisunmanaged(i.e. not connected over OCPP via SteVe).
The totals reflect filters, so if you narrow to scanners only, the Chargers count drops to zero. This is intentional — the strip and grid always agree.
-
Filter by device type
Use the Type control in the filter bar to scope the grid:
- All — chargers and scanners merged.
- Charger — OCPP chargers only. Adds
?type=charger. - Scanner — NFC scanners only. Adds
?type=scanner.
The loader skips the irrelevant database query when you pick a single type, so the page is cheap to refresh.
-
Narrow scanners by kind
When you’re looking at scanners, the Kind filter accepts:
phone_nfc— iPhone running the ExpressCharge app.tablet_nfc— iPad.laptop_nfc— macOS NFC reader.
The kind filter is ignored for chargers.
-
Filter by online state
Set Online to
onlineorofflineto limit the grid. Online state is computed differently per device class:- Chargers — derived from
lastStatusandlastStatusAtvia the sharednormalizeStatushelper. Anything other thanOfflinecounts as online. - Scanners — online if
lastSeenAtis within the last 90 seconds. This matches the freshness window used by scan-stream and scan-arm.
The online filter runs after the merge, so it works uniformly across both types.
- Chargers — derived from
-
Filter chargers by management mode
The Mode filter applies only to chargers:
- All — both modes.
- OCPP — chargers reporting via SteVe over OCPP.
- Unmanaged — chargers added manually that don’t speak OCPP back to us.
Unmanaged entries never go online — they exist so you can record an asset for billing or asset-tracking purposes without a live OCPP session.
-
Filter scanners by owner
To see every scanner registered to a single user, paste their user ID into the Owner field. The match is exact on
devices.owner_user_id. This is the same contract the/api/admin/devicesJSON endpoint uses, so IDs are interchangeable between the two surfaces. -
Open a device card
Click any card to drill into the device detail page. Cards are sorted by last-seen descending across both data sources, so the freshest device — charger or scanner — floats to the top.
Each charger card shows the ChargeBox ID, friendly name, last status, form factor, and capability pills. Each scanner card shows the device label, platform, model, app version, and owner.
Verify
Section titled “Verify”You’ve correctly read the listing when:
- The stat strip’s Total equals the number of cards in the grid.
- Sorting by last-seen puts your most recently active charger or scanner first.
- A device you know is live (you can see it transacting in the audit log or scan stream) shows as Online.
Cross-check against:
/admin/audit— the audit log for boot, status, and registration events.- Scan stream — for scanners, a fresh heartbeat there will be reflected within 90 seconds in the Online count here.
If something goes wrong
Section titled “If something goes wrong”Partial results banner. The loader queries chargers and devices independently and catches errors per source. A failure on one side does not 500 the whole page — you get a banner and half a grid. Check the application logs for AdminDevicesPage entries with messages Failed to load chargers or Failed to load devices to see the underlying error.
Empty grid when you expect data. Re-check your filters first — the most common cause is leaving Mode set to unmanaged or Online set to online from a previous session. The URL carries filter state, so removing query parameters resets the view.
Charger missing entirely. If a charger never appears even with all filters cleared, it hasn’t booted into SteVe yet. The row is created on the first OCPP BootNotification. For a charger that should be there but isn’t, confirm it’s pointed at the right SteVe endpoint.
Scanner missing. Soft-deleted devices (deleted_at IS NOT NULL) are hidden from this listing by design. If a user reports their phone is gone, it may have been removed via the device management flow.
Capability pill missing on a charger. The 'charger' capability is force-added in the loader even if the database row is misconfigured, so this should never happen. If it does, file a bug with the chargeBoxId.
Audit and reversibility
Section titled “Audit and reversibility”This page is read-only — viewing the listing logs nothing and changes nothing. The only mutation reachable from here is Add unmanaged charger in the page header, which routes to /admin/devices/new-unmanaged. See the unmanaged-charger runbook for the audit trail on that flow.