Sensor Task Scheduling
Relevant source files
The following files were used as context for generating this wiki page:
Sensor Task Scheduling in the OpenAwair project provides a structured mechanism for managing periodic data collection from various environmental sensors across different hardware revisions (Glow C and Element). The system abstracts hardware-specific sensor logic behind a unified interface, allowing a centralized scheduler to trigger asynchronous measurement cycles.
The scheduling logic is primarily defined in the host-side TypeScript abstractions, which serve as a blueprint for the eventual C/C++ implementation on the STM32F412 MCU. This architecture ensures that telemetry data, including temperature, humidity, CO₂, and particulate matter, is collected at appropriate intervals relative to each sensor's physical constraints.
Sources: CLAUDE.md:32-55, host/src/firmware/sensors/scheduler.ts:1-15
Core Architecture
The scheduling system is built on a provider-consumer pattern where individual SensorDriver implementations provide data to a central SensorScheduler. The AwairDevice controller utilizes this scheduler to aggregate metrics for export via MQTT or REST API.
Component Relationship
The following class diagram illustrates the relationship between the device controller, the scheduler, and the individual sensor drivers.
This diagram shows how AwairDevice delegates sampling logic to the SensorScheduler, which iterates through a collection of objects adhering to the SensorDriver interface.
Sources: host/src/firmware/device.ts:4-16, host/src/firmware/sensors/scheduler.ts:4-15, host/src/firmware/sensors/sensor.ts:3-7
Data Collection Flow
The collection process is asynchronous. When a measurement cycle is triggered, the scheduler executes the read() method for all registered drivers concurrently using Promise.all. The individual results are then merged into a single SensorReading object.
Sampling Sequence
The sequence diagram below details the flow of data from a request for metrics down to the individual sensor hardware abstractions.
This flow ensures that the slowest sensor does not block the initialization of other sensor reads, though the total sampling time is determined by the most latent sensor.
Sources: host/src/firmware/sensors/scheduler.ts:11-14, host/src/firmware/sensors/sensor.ts:9-19
Sensor Configurations and Intervals
Each sensor implementation defines its own sampleIntervalMs, reflecting its hardware requirements. For example, some sensors require warm-up periods (HPMA115S0) or baseline calibrations (SGP30).
| Sensor Model | Purpose | Default Interval | Data Field |
|---|---|---|---|
| SGP30 | TVOC / eCO₂ | 10,000ms | vocPpb |
| SHTC3 | Temp / Humidity | 5,000ms | temperatureC, humidityPercent |
| SHT30 | Temp / Humidity | 5,000ms | temperatureC, humidityPercent |
| HPMA115S0 | PM2.5 | 30,000ms | pm25UgM3 |
| T6703 | CO₂ (NDIR) | 30,000ms | co2Ppm |
Sources: host/src/firmware/sensors/sgp30.ts:5-6, host/src/firmware/sensors/shtc3.ts:5-6, host/src/firmware/sensors/sht30.ts:5-6, host/src/firmware/sensors/hpma115s0.ts:5-6, host/src/firmware/sensors/t6703.ts:5-6
Data Structures
SensorReading Interface
The SensorReading interface serves as the unified data bucket for all scheduled tasks. It uses optional fields because not every device revision contains every sensor.
export interface SensorReading {
readonly timestamp: Date;
readonly temperatureC?: TemperatureCelsius;
readonly humidityPercent?: RelativeHumidity;
readonly vocPpb?: VolatileOrganicCompounds;
readonly pm25UgM3?: ParticulateMatter;
readonly co2Ppm?: CarbonDioxide;
}
Sources: host/src/shared/telemetry.ts:7-14
Implementation Example: SGP30
The SGP30 driver demonstrates how specific sensor logic, such as baseline management, is encapsulated within the driver while the scheduler remains agnostic.
export class Sgp30Sensor implements SensorDriver {
public readonly name = 'SGP30';
public readonly sampleIntervalMs = 10000;
private baseline: number | null = null;
public setBaseline(baseline: number): void {
this.baseline = baseline;
}
public async read(): Promise<SensorReading> {
const voc = this.baseline ?? 150;
return {
timestamp: new Date(),
vocPpb: voc
};
}
}
Sources: host/src/firmware/sensors/sgp30.ts:4-21
Summary
The Sensor Task Scheduling system provides a modular and extensible framework for air quality monitoring. By decoupling the timing and data acquisition logic from the primary device controller, the architecture supports diverse sensor arrays across the Awair Glow C and Element product lines while maintaining a consistent telemetry output format.