Skip to content

RaftArchitecture

Rob Dobson edited this page May 3, 2026 · 1 revision

Raft Architecture at a Glance

One-page overview of how a Raft application is structured at runtime: the boot sequence, the major subsystems, and how they reach each other. Use this page to orient yourself before drilling into individual subsystems.

                              ┌──────────────────────────────────┐
                              │   Application (your main.cpp)    │
                              │   ─ creates RaftCoreApp          │
                              │   ─ registers SysMods            │
                              │   ─ calls setup() / loop()       │
                              └──────────────────────────────────┘
                                              │
                                              ▼
                              ┌──────────────────────────────────┐
                              │   RaftCoreApp                    │
                              │   ─ owns SysManager, FileSystem, │
                              │     ConfigBase, RestAPIEndpoints │
                              └──────────────────────────────────┘
                                              │
                                              ▼
                              ┌──────────────────────────────────┐
                              │   SysManager                     │
                              │   ─ orchestrates SysMod lifecycle│
                              │   ─ setup → addEndpoints →       │
                              │     addCommsChannels → loop      │
                              └──────────────────────────────────┘
                              │       │       │        │       │
            ┌─────────────────┘       │       │        │       └────────────────┐
            ▼                         ▼       ▼        ▼                        ▼
   ┌───────────────┐       ┌──────────────┐  ...   ┌──────────────┐    ┌────────────────┐
   │  Network /    │       │ WebServer    │        │ DeviceManager│    │ Your SysMods   │
   │  BLE / MQTT   │       │              │        │ + I2C bus    │    │                │
   │  / Serial     │       │              │        │              │    │                │
   │  transports   │       │              │        │              │    │                │
   └───────┬───────┘       └──────┬───────┘        └──────┬───────┘    └───────┬────────┘
           │                      │                       │                    │
           ▼                      ▼                       ▼                    ▼
   ┌───────────────────────────────────────────────────────────────────────────────────┐
   │   CommsChannelManager  (channels + protocol codecs)                               │
   └───────────────────────────────────────────────────────────────────────────────────┘
                                              │
                                              ▼
                              ┌──────────────────────────────────┐
                              │   ProtocolExchange               │
                              │   ─ decodes RICREST, dispatches  │
                              │     URL/cmd to RestAPIEndpoints  │
                              └──────────────────────────────────┘
                                              │
                                              ▼
                              ┌──────────────────────────────────┐
                              │   RestAPIEndpointManager         │
                              │   ─ registry of REST endpoints   │
                              │   ─ HTTP handlers also call here │
                              └──────────────────────────────────┘

The boot sequence (in order)

RaftCoreApp::setup() drives this. Each step happens for every registered SysMod before moving to the next:

Step What happens
1. Construct Each SysMod's create() factory is invoked. The constructor stores the system config reference.
2. setup() Read JSON config, initialise hardware drivers, allocate buffers.
3. addRestAPIEndpoints() Register REST endpoints with the global RestAPIEndpointManager.
4. addCommsChannels() Register protocol codecs and channels with CommsCoreIF.
5. postSetup() Run anything that needs other SysMods to be fully wired (e.g. WebServer creates websocket channels here, since CommsCore is now ready).
6. loop() repeatedly Cooperative multitasking — each SysMod gets a slice on every iteration.

Two consequences worth remembering:

  • A SysMod's setup() cannot rely on another SysMod's REST endpoints — they aren't registered yet. Use postSetup() instead.
  • A SysMod's setup() cannot register comms channels reliably — the codecs may not be added yet. Use addCommsChannels().

The four big subsystems

1. Configuration

Everything is driven by a single JSON document — the SysType — composed from:

  1. The compiled-in default SysType.
  2. Variant overrides (systypes/<Variant>/SysType.json).
  3. Non-volatile saved values (NVS).
  4. Runtime patches via the sysconfig REST endpoint.

Each layer is layered on top of the previous via RaftJsonNVS / RaftJsonPrefixed. SysMods read their own subtree via configGet*().

See Configuration, SysTypes, Top-Level SysType.

2. SysMods

A SysMod is a self-contained module with:

  • A name and a JSON config slot inside the SysType.
  • Lifecycle hooks (setup, loop, addRestAPIEndpoints, addCommsChannels, postSetup).
  • Optional debug JSON (getDebugJSON()) and busy-state (isBusy()).

Every Raft capability — networking, BLE, MQTT, file system, OTA, devices, your own code — is a SysMod. Built-in SysMods live in RaftSysMods.

See SysMods, SysManager, Writing Your First SysMod.

3. Communications stack

A layered model that lets a single REST endpoint serve any transport. Bottom to top:

  • Transports (BLE, UART, sockets, websocket, MQTT) — each owned by its transport SysMod.
  • Channels (CommsChannelManager) — register a transport, give it a name and a codec.
  • Protocol codecs — RICSerial (HDLC), RICFrame (length-prefixed), RICJSON (JSON-only).
  • ProtocolExchange — decodes RICREST inner messages and dispatches.
  • RestAPIEndpointManager — every endpoint registered by any SysMod, keyed on the first path segment.

See Communications Stack Overview.

4. Devices and buses

DeviceManager is the SysMod that owns hardware buses (currently I2C; SPI and GPIO follow the same pattern). It scans, identifies, polls and publishes device data based on JSON device-type records. Other parts of the system can register as data sources or subscribe via the standard subscription endpoint.

See DeviceManager, I2C Bus, Device Type Record Format.

Where the code lives

Subsystem Repo Top-level folder
RaftCoreApp, SysManager, base RaftSysMod, RaftJson, comms core, helpers RaftCore components/core/, components/comms/
Built-in SysMods (BLE, Network, MQTT, FileManager, LogManager, OTA, command channels) RaftSysMods components/
HTTP server, websocket and SSE handlers RaftWebServer components/RaftWebServer/, components/WebServer/
I2C bus and device infrastructure RaftI2C components/RaftI2C/

Reading order

If you've just landed:

  1. Quick Start — run something.
  2. This page.
  3. SysMods — the abstraction every part of Raft is built on.
  4. Communications Stack Overview — how requests reach your code.
  5. Writing Your First SysMod — apply it.

Clone this wiki locally