Please enable JavaScript to view this website.

Skip to main content

Architecture

In a nutshell

The reference implementation is a CompuLab iMX8 running the AWS IoT Greengrass nucleus plus a variety of components. cert-manager establishes the device identity and gates everything else on a cert/ready signal; the other components then scan BLE, collect location, publish asset scans, write shadows, and serve an on-device dashboard. Components talk to each other only over local Greengrass IPC (without leaving the box), and the device reaches AWS over cellular or WiFi.

Read this if: you want the conceptual map of what runs on the gateway and how the parts fit together.

Before this: skim the Overview.

This page is the conceptual map of the gateway's software; the exact recipes, deploy commands, and setup procedure live in the iot-edge repository README.

The device

One CompuLab IOT-GATE-iMX8 (aarch64, Debian) is the core: a single, self-contained gateway. It runs the AWS IoT Greengrass V2 nucleus (the runtime that manages component lifecycle and the cloud connection) and reaches AWS IoT Core over cellular via a SIM7600G modem or WiFi via an Intel WiFi 6 AX210 module.

Everything the platform does on real hardware happens on this one device. The Edge Mesh experiment later adds Raspberry Pi nodes around it, but the reference implementation itself is just the core.

The device's identity is its MPBID: a 10-character uppercase hex string assigned at manufacturing (e.g. 028800011A), used directly as the AWS IoT thing name with no transformation.

Custom Greengrass Components

Each component is an independently deployable unit with its own recipe and code. They coordinate over local IPC pub/sub (see below). In steady state, asset-publisher, device-reporter, and location-collector are the components that push data to the cloud (asset scans and shadows). cert-manager (provisioning and rotation), and health-portal (on-demand shadow reads) reach the cloud only in specific situations, as the table shows.

ComponentRoleTalks to cloud?
cert-managerCertificate lifecycle: manufacturing bootstrap, MQTT fleet provisioning for the operational cert, and rotation. Publishes edge/internal/cert/ready once the operational cert is on disk. This is the signal location-collector, asset-publisher, and device-reporter wait for before writing to the cloud.Yes (provisioning/rotation)
location-collectorReads GNSS and LTE cell-tower data from the SIM7600G modem; publishes location/fix over IPC and updates the location shadow.Yes (shadow)
ble-scannerScans nearby Milwaukee Tool BLE advertisements (subprocess-per-scan, a BlueZ 5.50 workaround), snapshots the latest location/fix into each scan, and writes session files to disk. Reads its scan settings (enabled, ble_scan.duration_sec, ble_scan.rssi_threshold, ble_scan.service_uuids, ble_scan.schedule) from the config shadow.No
asset-publisherReads BLE session files, builds RP2 asset-scan payloads, and publishes them to IoT Core. Reads its upload cadence (reporting.asset_scan_upload) from the config shadow.Yes
device-reporterOne-shot at boot: writes the identity and status named shadows once, then exits. Hard-depends on cert-manager.Yes (shadow)
health-portalOn-device web dashboard: health checks, cert/shadow/WiFi panels, and (with the mesh) a live topology map.On demand (dashboard shadow reads/writes)

Local IPC: the on-device bus

Components communicate through Greengrass IPC, a local publish/subscribe bus built into the runtime. IPC messages never leave the device: no IPC traffic crosses the network. Internal topics use the edge/internal/* prefix, e.g. edge/internal/cert/ready and edge/internal/location/fix.

Two message paths are worth remembering:

  • cert/ready: cert-manager publishes it once the operational cert exists; location-collector, asset-publisher, and device-reporter subscribe and gate their cloud writes on it. (ble-scanner depends on cert-manager only for deployment ordering, a Greengrass component dependency, not this IPC signal; ble-scanner has no cloud path at all.)
  • location/fix: location-collector publishes the latest fix; ble-scanner snapshots it into each session file so a scan carries the location where it was captured.

ble-scanner hands sessions to asset-publisher not over IPC but through session files on disk (/var/lib/edge/ble/sessions/). This is a deliberate decoupling, so a scan survives even if the publisher is momentarily down.

Startup ordering

The cert/ready gate is the backbone of boot order:

  1. cert-manager first. On a provisioned device the operational cert already exists, so it publishes cert/ready promptly; on a fresh device it runs provisioning first.
  2. The cloud-writing components (location-collector, asset-publisher, device-reporter) wait for cert/ready before writing. There is no valid identity to connect with until then.
  3. device-reporter is one-shot: it writes identity + status once after cert/ready, then exits (it is not a long-running service).
  4. location-collectorble-scanner: scans want a location snapshot, so the location feed comes up alongside scanning.

Identity & certificates

The device carries two certificates, both with on-device private keys that never leave the box:

  • Bootstrap cert: long-lived, obtained during manufacturing, used only for provisioning and rotation.
  • Operational cert: used for all runtime MQTT, replaced periodically via rotation.

cert-manager tracks progress in state.json (unprovisioned → bootstrap_complete → operational). The two-phase model is the same device-agnostic contract described in Device Provisioning; the reference implementation is a concrete implementation of it, run by cert-manager.

Deployment model

Components ship two ways, and this distinction matters when you're iterating:

  • Cloud deployment: the CI pipeline publishes versioned artifacts to S3, and create-deployment ships them to every device in the thing group.
  • Local deployment: make deploy-all-local runs components straight from the checked-out source on the device, taking effect in seconds — the fast, no-build-cycle iteration this device exists to enable.

When both target the same component, local takes precedence; a cloud deployment will not evict a local pin until you clear it. Exact commands live in the repo README's Day-to-day Development section.

Where the code lives

  • iot-edge repo README: the authoritative runtime, IPC flow, provisioning, setup, and deployment reference.
  • components/: one README per component (cert-manager, location-collector, ble-scanner, asset-publisher, device-reporter, health-portal).
  • shared/README.md: the edge_shared library shared by every component (payload, shadow / shadow_mqtt, ipc, provision, csr, ble, location, sessions).
  • Data Path: trace the actual messages, from BLE scans to the cloud through the shadow writes.