PSI IoT — Machine RMM Initiative
Repo: ProgressiveSurface/psi-iot-poc (GHE) · Status: Tenant Zero pilot LIVE (cloud spine e2e) · Updated: 2026-08-11
Live surfaces: iot.progressivesurface.com (IoT Console — registry + fleet health, app-layer MSAL) · iot-grafana.progressivesurface.com (dashboards, EasyAuth). Cloud: rg-psi-iot (Event Grid MQTT egns-psi-iot, PG16+timescaledb psql-psi-iot), bridge + console + Grafana on the shared App Service plan, PEs .26/.27/.29/.30. Edge: per-device X.509; DEVTEST simulator (L5X-modeled) streaming; wave 1 = 4 ControlLogix thermal sprays. Scope rule: no PLC changes ever — read-only enforced in collector code. PRIMS process data already lands in Azure Files (psproductiondata) — process hygiene is a cloud-side ingest.
An RMM (remote monitoring & management) platform for a machine builder. Target scope: machine hygiene, process hygiene, and OEE telemetry from every PSI machine in the installed fleet — internal and customer-sited — plus remote management where customer security allows. Truly multi-tenant, integrated with the D365 customer-support system.
Full reference architecture lives in the repo:
ARCHITECTURE.md.
Architecture in one paragraph
Five layers. Edge: one collector per machine on a dedicated device straddling
OT/IT, read-only against the PLC (EtherNet/IP), durable store-and-forward.
Ingestion/tenancy: per-device X.509 identity; every message stamped
tenant/site/asset where asset = machine serial — joining fleet telemetry to
the serial-first engineering knowledge base (BOM, PLC history, drawings).
Historian/apps: one long-format multi-tenant readings hypertable
(Timescale now, ADX at fleet scale); OEE is a computed view, not a new pipeline.
Action: Connected Field Service pattern — telemetry alerts create D365 Cases
against the Customer Asset (= serial). Fleet management plane: Balena-class
device lifecycle (provision/update/access) + a PSI-built registry + device-management console (device ↔ serial ↔ tenant ↔ tier, fleet health) as part of the IoT app itself — the platform is its own bounded product, not a psi-portal module.
Trust tiers (product-defining)
| Tier | Posture |
|---|---|
| 0 | Airgapped — local historian, signed diagnostics export |
| 1 | Monitor-only outbound (data-diode semantics) — default ship config |
| 2 | + customer-initiated, recorded remote support sessions |
| 3 | Full RMM — managed updates, PRIMS image management, config-drift detection |
Telemetry and management are separate channels with separate identities; the write path is a different binary a customer can decline to install.
Tenant Zero PoC (current state)
Docker Compose spine: collector (Node/TS; simulator or st-ethernet-ip
read-only PLC source) → Mosquitto → bridge → TimescaleDB → Grafana dashboard.
Store-and-forward proven by killing the broker mid-run. Deliberate PoC
shortcuts (anonymous MQTT/Grafana, plaintext .env password) are documented in
the README. Next steps: real PLC reads on an internal machine via a Dell
OptiPlex Micro edge box, then a manual telemetry → D365 Case walkthrough in the
Sandbox.
Provisioning a new machine (console-owned, 2026-08-11)
The console owns the entire edge-onboarding path — the earlier bench scripts
(issue-device-cert.sh, bootstrap-edge.sh) are retired:
- OS install — download the Edge installer ISO from the console toolbar
(
/edge/psi-edge-installer.iso, ~63 MB, generic, no secrets — remastered Debian 12 netboot with initrd preseed). Write to USB with Rufus in dd/image mode and boot the box; the only install prompt is setting the localpsiedgeadmin password, and first boot lands on a tty prompt waiting for the enrollment command from step 3. (A box installed any other way just needs to be a fresh Debian 12.) - Register + Provision in the console — register the device against its
serial (the machine’s invariant identity; project numbers are lifecycle
entries under the serial — original build + retrofits, same asset model as
PSI Explorer), then Provision from the fleet
table: the console issues the device X.509 from the pilot CA (Key Vault
PsiIot--CaCert/CaKey), registers the Event Grid namespace client via its managed identity, and mints a single-use 24 h enrollment token (bundle encrypted with a token-derived key; only the token hash is stored). - Enroll — paste the generated one-liner at the box’s first-boot prompt
(or any root shell):
curl -fsSL https://iot.progressivesurface.com/enroll/<token> | sudo bashapplies network posture (OT leg static/no-gateway, forwarding off), installs Docker, pulls the collector bundle from the console (no git on the device), writes certs/tag map/.env, and starts the systemd-managed collector.
The device then appears live in the fleet table as soon as telemetry flows.
Related
- Process Services Fleet — the internal machines Tenant Zero targets
- PC Fleet / PRIMS Pro — the existing customer HMI-PC fleet practice that converges into tiers 2–3