-
Notifications
You must be signed in to change notification settings - Fork 3
DeviceManager
The DeviceManager SysMod is responsible for managing devices and buses. It sets up and monitors the status of devices, handles bus communication, and provides an interface for interacting with devices via REST API endpoints. The DeviceManager interacts with the system manager (SysManager) to register devices and manage data sources. Two distinct kinds of devices are managed:
- Dynamic Devices these are generally attached to a physical, (perhaps wireless, or even notional) bus and detected through some mechanism such that they can dynamically appear and may go offline again.
- Static Devices are generally hardware attached in other ways (SPI, GPIO, etc) and are not detected automatically but require the device code itself to instantiate and support them
- Device Setup and Management: Initializes and manages devices based on configuration.
- Bus Management: Monitors and handles bus operations and element statuses.
- REST API Interface: Provides REST endpoints for interacting with devices.
- Device Data Change Callbacks: Supports registering callbacks for device data changes.
- Status Monitoring: Continuously monitors the status of devices and buses.
-
setup(): Initializes buses from the
Busesconfiguration section and instantiates configured devices from theDeviceslist. -
postSetup(): Registers data sources for publishing (
devjson,devbin), callspostSetup()on each device, and registers device data/status callbacks. -
loop(): Services the bus system and then calls
loop()on each online device.
DeviceManager supports two paths for device creation:
-
Statically configured devices: Devices listed under
Devicesare created using the DeviceFactory, assigned a direct-connection device ID, thensetup()andpostSetup()are called. If a device provides a device type record, it is added to the device type records and assigned a type index. -
Dynamically detected bus devices: As buses report element status changes, newly identified devices are created as
RaftBusDeviceinstances, assigned their bus ID, and brought online. The manager updates online/offline state and registers for device data notifications when a device is first identified.
DeviceManager relies on the DeviceFactory to create devices from the class field in each device configuration entry. Device classes register themselves with the factory at startup. When a configuration entry is processed, DeviceManager looks up the class name in the factory and invokes the registered create function.
If a device provides a type record, DeviceManager registers it with the device type records and assigns a type index. The type information is used by the REST API (/devman/typeinfo) and by published device data.
DeviceManager maintains two per-device maps that are independent of the device type record:
-
Name map — associates a friendly name (e.g.
IMU1,FuelGauge) with aRaftDeviceID. Names can be configured via thenamefield on aDevicesentry, via a top-levelDeviceNamesmap, or assigned at runtime through/devman/setname. -
Role map — associates a role string (default
normal, or e.g.system) with aRaftDeviceID. Roles allow callers to distinguish system-infrastructure devices (fuel gauges, RTCs, chargers) from standard published measurement devices. Roles can be configured via therolefield on aDevicesentry or assigned at runtime through/devman/setrole. The current role is reported by per-device/devman/typeinforequests and by/devman/listdevs.
A Devices entry that omits the class field is treated as a bus-tagging entry — it does not instantiate a device but instead assigns a name and/or role to a bus-discovered device identified by its bus+addr. See DeviceManager Settings for the full schema.
-
Named values:
getNamedValue()andgetNamedString()use the formDeviceName.paramNameto query values on a specific device;setNamedValue()andsetNamedString()route writes the same way. -
JSON command routing:
receiveCmdJSON()expects a JSON body with adevicefield and forwards the command to that device. -
Device events: Device status/event callbacks are registered and forwarded to SysManager as
syseventmessages.
A SysMod can subscribe to a device's decoded data directly (in addition to, or instead of, the published devjson/devbin topics) using DeviceManager::registerForDeviceData(). The callback fires whenever fresh data arrives for the target device, with the device type index (for decoding), the raw poll bytes, and any registered callback info:
using RaftDeviceDataChangeCB = std::function<void(uint32_t deviceTypeIdx,
std::vector<uint8_t> data,
const void* pCallbackInfo)>;The target device can be identified three ways:
-
By device ID / address —
RaftDeviceID, or a device-id string such as"I2CA_0x6a@0"/"1_6a"(bus name or number, hex address, optional@slot). -
By device type index —
DeviceTypeIndexType. -
By device type name — e.g.
"LSM6DS".
Registration is deferred: it is safe to call during setup() before the device has been identified — the request is stored and wired up when a matching device comes online (see the bus element status handling). The const char* overload accepts either a device-id string or a device type name (it first tries to resolve the string as a bus_addr identifier, then falls back to a type-name lookup), so callers targeting a specific bus address and callers targeting a type both work.
// e.g. from a SysMod setup(), register for the accelerometer at I2CA 0x15
getSysManager()->getDeviceManager()->registerForDeviceData("I2CA_0x15@0",
[this](uint32_t devTypeIdx, std::vector<uint8_t> data, const void* /*cbInfo*/) {
// decode `data` using devTypeIdx and use the values
},
50 /* min ms between reports */);DeviceManager automatically publishes device data through the StatePublisher system using two topics:
- devjson: Human-readable JSON format for device data
- devbin: Compact binary format for efficient transmission
For detailed information about the message formats, subscription methods, and integration details, see Device Data Publishing.
Device data publishing uses a state-hash mechanism that combines bus timestamps and per-device state hashes, so publish updates only occur when device data changes.
DeviceManager supports various device types. Some devices have dedicated documentation:
- MotorControl Device - Multi-axis motor control with REST API and JSON commands
When constructed normally (in RaftCoreApp for instance) the DeviceManager is configured using the contents of the SysTypes key DevMan. The settings available to configure DeviceManager are described in Device Manager Settings
RaftI2C scans I2C buses to detect devices, including those connected through bus multiplexers. For configuration of the I2C bus itself (pins, frequency, multiplexers, task parameters, etc.) see I2C Bus.
Scanning uses priority-based address ordering for efficient detection and supports device hot-swapping. For detailed information about the scanning process, priority lists, multiplexer handling, and bus stuck recovery, see I2C Device Scanning.
After devices are detected through scanning, DeviceManager identifies device types, initializes devices, and polls them for data at configured intervals. Device type records define how to identify, initialize, and poll each supported device type.
For detailed information about device type detection, initialization sequences, polling configuration, and data collection, see I2C Device Identification and Polling.
See Device Manager REST API for full endpoint details and examples.
Getting Started
- Quick Start
- Architecture at a Glance
- Writing Your First SysMod
- Adding a Comms Channel
- Adding an I2C Device Type
- PlatformIO / Arduino
Scaffolding & Building
- Raft CLI
- SysTypes
- Top-Level SysType
- Build Process
- WebUI Build Pipeline
- File System
- Partitions & Flash
- Local Dev Libraries
- Library Developer Guide
Architecture
Built-in SysMods
- NetworkManager
- BLEManager
- WebServer
- MQTTManager
- SerialConsole
- CommandSerial
- CommandSocket
- CommandFile
- FileManager
- LogManager
- ESPOTAUpdate
- StatePublisher
- Remote Logging
- Data Source Registration
Comms & Protocols
- Stack Overview
- Comms Channels
- ProtocolExchange
- RICREST Protocol
- Real-Time Streams
- Adding REST Endpoints
- Built-in REST Endpoints
- File Download (OKTO)
- OTA Update Flow
Devices & Buses
- DeviceManager
- Device Manager REST API
- Device Factory & Classes
- Device Type Records
- Adding an I2C Device Type
- Device Data Publishing
- Data Logger
- I2C Bus
- I2C Device Scanning
- I2C ID & Polling
- MotorControl Overview
- MotorControl Config
- MotorControl Commands
Helpers
Reference