Adding New Sensors
Relevant source files
The following files were used as context for generating this wiki page:
Adding new sensors to the OpenAwair project involves implementing a standardized driver interface that allows the system to schedule readings and aggregate telemetry data. The architecture is designed to be modular, supporting various environmental sensors used in Awair Glow C and Awair Element devices, such as Temperature, Humidity, CO2, VOC, and PM2.5 sensors.
The system relies on a SensorScheduler to manage multiple SensorDriver implementations, ensuring that readings are collected at appropriate intervals and merged into a unified DeviceMetrics object for reporting via MQTT or REST APIs.
Sources: host/src/firmware/device.ts, host/src/firmware/sensors/scheduler.ts
Sensor Architecture Overview
The sensor subsystem follows a provider pattern where each physical sensor is represented by a class implementing the SensorDriver interface.
The SensorDriver Interface
Every new sensor must implement the SensorDriver interface, which defines the metadata and the core execution logic for the sensor.
| Property | Type | Description |
|---|---|---|
name | string | Unique identifier for the sensor hardware (e.g., "SGP30"). |
sampleIntervalMs | number | The frequency in milliseconds at which the sensor should be sampled. |
read() | Promise<SensorReading> | Async method that performs the hardware read and returns telemetry data. |
Sources: host/src/firmware/sensors/sensor.ts:3-7
Data Flow and Aggregation
When the AwairDevice requests metrics, it triggers the SensorScheduler to sample all registered drivers. The individual results are then merged into a single state.
This diagram illustrates how the SensorScheduler orchestrates concurrent sensor reads and uses the mergeReadings utility to combine disparate sensor outputs.
Sources: host/src/firmware/sensors/scheduler.ts:12-15, host/src/firmware/sensors/sensor.ts:9-18
Implementing a New Driver
To add a new sensor, create a new class in host/src/firmware/sensors/ that implements the SensorDriver.
1. Define the Driver Class
The class should encapsulate any sensor-specific logic, such as initialization requirements or calibration baselines. For example, the SGP30 sensor includes a method to set a baseline for VOC readings.
Sources: host/src/firmware/sensors/sgp30.ts:4-9
2. Implement the Read Method
The read() method must return a SensorReading object. This object contains optional fields for different environmental metrics.
| Field | Type | Unit |
|---|---|---|
temperatureC | number | Celsius |
humidityPercent | number | % Relative Humidity |
vocPpb | number | Parts per billion |
pm25UgM3 | number | µg/m³ |
co2Ppm | number | Parts per million |
Sources: host/src/shared/telemetry.ts:7-14
Code Example: SHT30 Implementation
export class Sht30Sensor implements SensorDriver {
public readonly name = 'SHT30';
public readonly sampleIntervalMs = 5000;
public async read(): Promise<SensorReading> {
return {
timestamp: new Date(),
temperatureC: 22.9,
humidityPercent: 44.5
};
}
}
Sources: host/src/firmware/sensors/sht30.ts:4-14
Integration with Device Hardware
Once a driver is implemented, it must be passed to the AwairDevice constructor. The AwairDevice manages the lifecycle of these sensors via its internal scheduler.
The class hierarchy shows how specific sensor implementations are composed into the AwairDevice through the SensorScheduler.
Sources: host/src/firmware/device.ts:7-13, host/src/firmware/sensors/scheduler.ts:5-10
Sensor Specific Requirements
Different sensors have specific operational constraints defined in the project:
- SGP30: Requires baseline saves every ~12 hours to flash storage for VOC accuracy.
- HPMA115S0: Requires a fan spin-up period before accurate PM2.5 readings can be taken.
- T6703: CO2 NDIR sensor that typically outputs data every 2 seconds.
Sources: CLAUDE.md:Project Overview/Architecture/Firmware (C/C++)
Summary
Adding a sensor to OpenAwair requires creating a SensorDriver implementation that provides a read() method returning standardized SensorReading types. These drivers are managed by a SensorScheduler which handles the concurrent collection and merging of data, allowing the AwairDevice to provide a consistent telemetry interface regardless of the underlying hardware components.