ESPHome 2026.1.4
Loading...
Searching...
No Matches
aqi_calculator.h
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <limits>
6
7// https://document.airnow.gov/technical-assistance-document-for-the-reporting-of-daily-air-quailty.pdf
8
9namespace esphome::aqi {
10
12 public:
13 uint16_t get_aqi(float pm2_5_value, float pm10_0_value) override {
14 float pm2_5_index = calculate_index(pm2_5_value, PM2_5_GRID);
15 float pm10_0_index = calculate_index(pm10_0_value, PM10_0_GRID);
16
17 return static_cast<uint16_t>(std::round((pm2_5_index < pm10_0_index) ? pm10_0_index : pm2_5_index));
18 }
19
20 protected:
21 static constexpr int NUM_LEVELS = 6;
22
23 static constexpr int INDEX_GRID[NUM_LEVELS][2] = {{0, 50}, {51, 100}, {101, 150}, {151, 200}, {201, 300}, {301, 500}};
24
25 static constexpr float PM2_5_GRID[NUM_LEVELS][2] = {{0.0f, 9.0f}, {9.1f, 35.4f},
26 {35.5f, 55.4f}, {55.5f, 125.4f},
27 {125.5f, 225.4f}, {225.5f, std::numeric_limits<float>::max()}};
28
29 static constexpr float PM10_0_GRID[NUM_LEVELS][2] = {{0.0f, 54.0f}, {55.0f, 154.0f},
30 {155.0f, 254.0f}, {255.0f, 354.0f},
31 {355.0f, 424.0f}, {425.0f, std::numeric_limits<float>::max()}};
32
33 static float calculate_index(float value, const float array[NUM_LEVELS][2]) {
34 int grid_index = get_grid_index(value, array);
35 if (grid_index == -1) {
36 return -1.0f;
37 }
38 float aqi_lo = INDEX_GRID[grid_index][0];
39 float aqi_hi = INDEX_GRID[grid_index][1];
40 float conc_lo = array[grid_index][0];
41 float conc_hi = array[grid_index][1];
42
43 return (value - conc_lo) * (aqi_hi - aqi_lo) / (conc_hi - conc_lo) + aqi_lo;
44 }
45
46 static int get_grid_index(float value, const float array[NUM_LEVELS][2]) {
47 for (int i = 0; i < NUM_LEVELS; i++) {
48 if (value >= array[i][0] && value <= array[i][1]) {
49 return i;
50 }
51 }
52 return -1;
53 }
54};
55
56} // namespace esphome::aqi
static constexpr float PM2_5_GRID[NUM_LEVELS][2]
static constexpr int NUM_LEVELS
static int get_grid_index(float value, const float array[NUM_LEVELS][2])
static float calculate_index(float value, const float array[NUM_LEVELS][2])
static constexpr float PM10_0_GRID[NUM_LEVELS][2]
static constexpr int INDEX_GRID[NUM_LEVELS][2]
uint16_t get_aqi(float pm2_5_value, float pm10_0_value) override