Customizing Device Workflows
Relevant source files
The following files were used as context for generating this wiki page:
Customizing device workflows in the OpenAwair project involves configuring how Awair Glow C and Awair Element devices handle sensor data collection, state management (such as relay control), and communication via MQTT and REST interfaces. The architecture is designed to support local-first operation, allowing users to define how telemetry is reported and how device components respond to external commands or internal state changes.
Sources: CLAUDE.md:5-10, host/src/firmware/device.ts:1-15
Device State and Sensor Management
The core of a device workflow is the AwairDevice class, which orchestrates sensor sampling and manages hardware states like the power relay found in the Glow C model.
Sensor Data Collection
Workflows are driven by the SensorScheduler, which executes periodic reads from registered SensorDriver instances. The device collects metrics including temperature, humidity, VOC, CO2, and PM2.5, depending on the hardware model.
The diagram above shows the relationship between the device controller, the scheduler, and the individual drivers that populate telemetry data.
Sources: host/src/firmware/device.ts:7-21, host/src/shared/telemetry.ts:10-24
Relay Control Logic
For the Awair Glow C, the workflow includes a relay for smart plug functionality. The state can be toggled manually or via API endpoints, with a default safety constraint to remain OFF on boot.
| Method | Description | Return Type |
|---|---|---|
toggleRelay() | Flips the current boolean state of the relay | void |
getRelayState() | Returns the current state (enabled/disabled) | boolean |
Sources: host/src/firmware/device.ts:24-30, CLAUDE.md:77-78
Networking and Discovery Workflows
Customizing how the device interacts with the network involves configuring MQTT publishers and REST routers to match specific integration needs, such as Home Assistant auto-discovery.
MQTT Telemetry Flow
Devices utilize an MqttPublisher to format sensor readings into standardized JSON payloads and manage availability status.
This sequence illustrates the transformation of internal metrics into network-ready MQTT messages.
Sources: host/src/firmware/networking/mqtt.ts:8-21
Home Assistant Discovery
To automate setup, the workflow includes a discovery mechanism that generates configuration messages for Home Assistant. This requires defining DiscoverySensor objects that map internal telemetry fields to Home Assistant entity classes.
Sources: host/src/firmware/networking/mqttDiscovery.ts:15-38
Bootloader and Update Workflows
The boot sequence determines whether the device starts the main application or enters a Device Firmware Update (DFU) session based on flags stored in persistent flash memory.
Boot Decision Logic
The Bootloader class reads a dfuFlagKey from the FlashStore to decide the execution path.
Firmware Commit Workflow
When a new firmware image is received via DFU, the workflow must validate the CRC32 checksum before updating the metadata in flash and resetting the DFU flag to '0' (boot application).
| Configuration Key | Description |
|---|---|
dfuFlagKey | Trigger for DFU mode ('1' for DFU, '0' for App) |
firmwareCrcKey | Expected CRC32 of the firmware image |
firmwareSizeKey | Total size of the firmware binary |
Sources: host/src/firmware/bootloader/bootloader.ts:7-12, host/src/firmware/bootloader/bootloader.ts:38-42
REST API Customization
The project allows for custom endpoints through a RestRouter. Standard workflows include a metrics endpoint for polling data and a relay endpoint for control.
// Example: Registering a custom metrics workflow
export const createMetricsEndpoint = (metrics: DeviceMetrics): RestEndpoint => {
return {
path: '/api/v1/metrics',
method: 'GET',
async handle() {
return JSON.stringify(metrics);
}
};
};
Sources: host/src/firmware/networking/rest.ts:8-18
Summary: Customizing device workflows in OpenAwair involves configuring the AwairDevice for hardware control, defining DiscoverySensor mappings for Home Assistant, and managing the Bootloader state to handle firmware lifecycle and local API access.