Blueprint 06 · Edge & control
Edge-to-Cloud IoT: Closed-Loop Telemetry & Control
Field devices sense and act; the cloud decides and verifies. Telemetry flows through a single message bridge to a deterministic engine that closes the loop — decided, commanded, observed, verified — while a hardware safety override owes nothing to the network it can't always reach.
The network is not your safety system
An IoT system that controls something physical — a valve, a motor, a heater — lives with a hard truth: connectivity is intermittent, latency is variable, and the cloud will sometimes be unreachable at exactly the wrong moment. A design that assumes the link is always up is a design that eventually does harm. This blueprint puts the boundaries where physics demands them.
Three layers, each with a clear job. The edge senses, acts, and protects itself with a local override that no remote command can defeat. A single bridge is the only place the messaging protocol terminates, keeping the rest of the platform transport-agnostic. The cloud ingests, decides with deterministic rules, and — crucially — verifies that what it commanded actually happened.
Sending a command and assuming it worked is open-loop control — it fails silently. This blueprint tracks every command through four states: decided (the engine chose to act), commanded (the message was published), observed (the device acknowledged), and verified (the physical effect was measured and matched expectation). A stuck valve or a dropped command surfaces as an unverified action, not a wrong assumption.
Sense at the edge, decide in the middle, verify the result
Self-protecting edge node
The device samples sensors on a non-blocking schedule, derives calibrated units locally, and runs a hardware override (a physical input) as the highest-priority interlock — it can always force the actuator safe, regardless of network or cloud state.
Single message bridge
One component subscribes to the broker, validates payloads, maps device → location, and hands data to the platform. Because it is the only place MQTT terminates, the broker is swappable and everything upstream is transport-agnostic.
Deterministic decision engine
Control decisions are pure functions with built-in cooldowns and guards, layered so each adds one concern (react → defer on forecast → defer on demand model → narrate). Any optional AI sits at the very edge and only explains — it never gates an actuation.
Closed-loop verification
Commands carry a correlation id echoed in the acknowledgement; the platform advances the loop from commanded to observed to verified by comparing the measured effect against what was expected.
Zero-touch provisioning
A factory mint issues a device id and a one-time token (printable as a QR code); the operator scans to claim and bind the device to a location; first boot exchanges the token for per-device credentials exactly once.
Per-consumer BFFs & graceful degradation
Each dashboard is served by a thin backend-for-frontend that fans out to only the modules it needs; offline devices show a last-known value with a freshness indicator instead of an error.
Software device mocks that speak the identical message contract — including a flag distinguishing synthetic from live data, and the ability to inject faults like a stuck actuator — let the exact production code path be tested without hardware. A development-board stand-in can mirror a constrained production radio's publishing topology so the cloud code never changes when the real device is swapped in.
Three layers, one loop
flowchart TB
subgraph edge["Edge layer"]
SENS["Sensors → calibrated units"]
MCU["Device firmware
non-blocking scheduler"]
OVR["Hardware override
(highest priority, local)"]
ACT["Actuator"]
SENS --> MCU
OVR --> ACT
MCU --> ACT
end
BROKER(["Message broker (MQTT)"])
MCU -->|telemetry| BROKER
BROKER -->|commands| MCU
subgraph cloud["Cloud layer"]
BRIDGE["Single MQTT bridge
validate · map device→site"]
LIVE["Live snapshot
(in-memory)"]
TS[("Time-series store")]
ENG["Deterministic decision engine
(+ advisory AI at the edge)"]
BFF["Per-consumer BFFs"]
BRIDGE --> LIVE
BRIDGE --> TS
LIVE --> ENG
TS --> ENG
ENG -->|command| BRIDGE
LIVE --> BFF
TS --> BFF
end
BROKER --- BRIDGE
BFF --> UI["Role-specific dashboards"]
What lives at each layer
| Layer | Responsibilities | Key property |
|---|---|---|
| Edge / device | Sample sensors, derive units with calibration, drive the actuator, enforce the local override, publish telemetry & acks | Acts safely even with no connectivity |
| Transport | Carry compact, timestamped JSON telemetry up and commands down over a pub/sub broker | Lightweight; quality-of-service tuned per message type |
| Ingestion bridge | The single place the protocol terminates: validate, map device to location, fan out to live + durable stores, trigger the engine | Broker-agnostic seam (see Blueprint 03) |
| Decision engine | Deterministic control with cooldowns/guards, layered by concern; advisory AI only narrates | Reliability never depends on the model (see Blueprint 02) |
| Presentation | Per-consumer BFFs serve role-specific dashboards with freshness indicators | Degrades to last-known value, never errors |
Decided → commanded → observed → verified
sequenceDiagram
participant S as Sensor / device
participant B as Broker
participant G as Ingestion bridge
participant E as Decision engine
participant A as Actuator
S->>B: Telemetry (timestamped)
B->>G: Deliver
G->>G: Validate · map device→site
G->>E: Update live + durable state
E->>E: Evaluate rules (cooldown, guards) → DECIDED
E->>B: Command (correlation id) → COMMANDED
B->>A: Deliver command
A->>A: Apply (subject to local override)
A->>B: Ack (echo correlation id) → OBSERVED
B->>G: Ack + follow-on telemetry
G->>E: Compare measured effect vs expected → VERIFIED
The hardware override is evaluated locally, every loop, and outranks any remote command. If the cloud says "open" but the local safety input says "closed," the device stays closed. This single rule means a compromised, confused, or unreachable cloud can never force an unsafe physical action.
Five alternate use cases
Smart HVAC & energy control
Zone sensors drive deterministic setpoint logic with comfort guards; an advisory model explains "why" to facilities staff, and a local override protects occupants if the cloud drops.
Water / wastewater monitoring
Distributed pump and flow nodes report through one bridge; closed-loop verification catches a pump that was commanded on but never started, before a tank overflows.
Condition monitoring & safe shutdown
Vibration and temperature telemetry feed deterministic thresholds; the actuator is an interlock that trips locally, with the cloud providing trends and fleet health.
Refrigeration & logistics tracking
Compressor control with deterministic guards and a local safety cut-out; time-series history plus freshness indicators show exactly when and where an excursion occurred.
Distributed solar / battery sites
Per-site BFFs serve owner, installer and operator views over shared telemetry; zero-touch provisioning lets a non-specialist commission a new site by scanning a code.
Where edge systems bite
| Risk | Why it happens | Mitigation |
|---|---|---|
| Assuming the command worked | Open-loop control with no verification | Correlation ids and the four-state loop; verify the physical effect; alert on unverified actions |
| Cloud dependency for safety | Critical interlocks implemented only in the cloud | Local hardware override evaluated every loop, outranking remote commands |
| Synthetic data mistaken for real | Simulated/seed readings indistinguishable from live | A source discriminator on every reading; never let synthetic data drive real decisions or reports |
| Broker lock-in / single point | Protocol handling spread across the codebase | Terminate the protocol in one bridge; make the broker a swappable seam; cluster/secure the broker |
| Fleet blindness | No view of which devices are healthy, stale, or offline | Track last-seen per device; surface online/stale/offline status; freshness indicators on every live tile |
| Clock & ordering issues | Devices disagree on time; messages arrive out of order | Timestamp at the edge; tolerate reordering in ingestion; treat telemetry as events, not state |
Trust the device just enough
Devices have no human to log in. Provision them with a one-time token that is exchanged at first boot for per-device credentials — issued exactly once and not recoverable from storage afterwards. Revocation retires a device and frees its identity for reissue after a re-flash. Factory endpoints are gated by a factory key.
- Use mutual-TLS for device-to-broker transport in production; anonymous access is acceptable only on a trusted, isolated bench network.
- Enforce data-minimisation and any anonymisation centrally (in a platform service), not in each dashboard, so a surface can't bypass it.
- Keep an append-only, tamper-evident provenance trail of commands and actuations (see Blueprint 04) — for physical systems, "who turned this on" is a safety question, not just an audit one.
- Keep device secrets out of source control (templated example files, secret scanning in CI) and derive device identity from immutable hardware identifiers.
When to reach for it — and when not to
Use it when
- Devices physically actuate something and an unsafe state has real consequences.
- Connectivity is intermittent and the system must behave safely offline.
- You need to prove a command had its intended physical effect, not just that it was sent.
- A fleet must be provisioned and operated by non-specialists at sites you don't control.
Simplify when
- Devices only sense and never actuate — you may not need the command loop or override.
- Connectivity is reliable and cheap, and pure cloud control is acceptable.
- The fleet is tiny and hand-provisioning is fine — skip the zero-touch machinery.
- Real-time control isn't required and periodic batch upload would do.
Want this pattern applied to your build?
These are the structures we reach for. Tell us the system you're trying to build.