ESPHome
2026.8.0-dev
Loading...
Searching...
No Matches
esphome
components
aqi
aqi_calculator.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <algorithm>
4
#include <cmath>
5
#include <limits>
6
#include "
abstract_aqi_calculator.h
"
7
8
// https://document.airnow.gov/technical-assistance-document-for-the-reporting-of-daily-air-quailty.pdf
9
10
namespace
esphome::aqi
{
11
12
class
AQICalculator
:
public
AbstractAQICalculator
{
13
public
:
14
uint16_t
get_aqi
(
float
pm2_5_value,
float
pm10_0_value,
bool
extended_range)
override
{
15
float
pm2_5_index =
calculate_index
(pm2_5_value,
PM2_5_GRID
, extended_range);
16
float
pm10_0_index =
calculate_index
(pm10_0_value,
PM10_0_GRID
, extended_range);
17
float
aqi = std::max({pm2_5_index, pm10_0_index, 0.0f});
18
// extended_range lets the index run past the standard maximum, so clamp to the sensor's range.
19
aqi = std::min(aqi,
static_cast<
float
>
(std::numeric_limits<uint16_t>::max()));
20
return
static_cast<
uint16_t
>
(std::lround(aqi));
21
}
22
23
protected
:
24
static
constexpr
int
NUM_LEVELS
= 6;
25
26
static
constexpr
int
INDEX_GRID
[
NUM_LEVELS
][2] = {{0, 50}, {51, 100}, {101, 150}, {151, 200}, {201, 300}, {301, 500}};
27
28
static
constexpr
float
PM2_5_GRID
[
NUM_LEVELS
][2] = {
29
// clang-format off
30
{0.0f, 9.1f},
31
{9.1f, 35.5f},
32
{35.5f, 55.5f},
33
{55.5f, 125.5f},
34
{125.5f, 225.5f},
35
{225.5f, 500.4f}
// EPA 2024: AQI 301-500 maps to PM2.5 225.5-500.4 ug/m3
36
// clang-format on
37
};
38
39
static
constexpr
float
PM10_0_GRID
[
NUM_LEVELS
][2] = {
40
// clang-format off
41
{0.0f, 55.0f},
42
{55.0f, 155.0f},
43
{155.0f, 255.0f},
44
{255.0f, 355.0f},
45
{355.0f, 425.0f},
46
{425.0f, 604.0f}
// EPA: AQI 301-500 maps to PM10 425-604 ug/m3 (top of the 401-500 band)
47
// clang-format on
48
};
49
50
static
float
calculate_index
(
float
value,
const
float
array[
NUM_LEVELS
][2],
bool
extended_range) {
51
int
grid_index =
get_grid_index
(value, array);
52
if
(grid_index == -1) {
53
return
-1.0f;
54
}
55
float
aqi_lo =
INDEX_GRID
[grid_index][0];
56
float
aqi_hi =
INDEX_GRID
[grid_index][1];
57
float
conc_lo = array[grid_index][0];
58
float
conc_hi = array[grid_index][1];
59
60
float
index = (value - conc_lo) * (aqi_hi - aqi_lo) / (conc_hi - conc_lo) + aqi_lo;
61
62
// Concentrations above the highest breakpoint run the linear fit past aqi_hi. By default we
63
// clamp to the standard maximum; with extended_range we keep the extrapolated "over-range"
64
// value so heavy pollution reports numbers beyond what the standard defines.
65
if
(grid_index ==
NUM_LEVELS
- 1 && !extended_range && index > aqi_hi) {
66
return
aqi_hi;
67
}
68
return
index;
69
}
70
71
static
int
get_grid_index
(
float
value,
const
float
array[
NUM_LEVELS
][2]) {
72
for
(
int
i = 0; i <
NUM_LEVELS
; i++) {
73
// The top band is open-ended: any value at or above its lower breakpoint falls into it,
74
// and calculate_index() decides whether to clamp or extrapolate.
75
const
bool
in_range = (value >= array[i][0]) && (i ==
NUM_LEVELS
- 1 || value < array[i][1]);
76
if
(in_range) {
77
return
i;
78
}
79
}
80
return
-1;
81
}
82
};
83
84
}
// namespace esphome::aqi
abstract_aqi_calculator.h
esphome::aqi::AQICalculator
Definition
aqi_calculator.h:12
esphome::aqi::AQICalculator::PM2_5_GRID
static constexpr float PM2_5_GRID[NUM_LEVELS][2]
Definition
aqi_calculator.h:28
esphome::aqi::AQICalculator::NUM_LEVELS
static constexpr int NUM_LEVELS
Definition
aqi_calculator.h:24
esphome::aqi::AQICalculator::get_grid_index
static int get_grid_index(float value, const float array[NUM_LEVELS][2])
Definition
aqi_calculator.h:71
esphome::aqi::AQICalculator::calculate_index
static float calculate_index(float value, const float array[NUM_LEVELS][2], bool extended_range)
Definition
aqi_calculator.h:50
esphome::aqi::AQICalculator::get_aqi
uint16_t get_aqi(float pm2_5_value, float pm10_0_value, bool extended_range) override
Definition
aqi_calculator.h:14
esphome::aqi::AQICalculator::PM10_0_GRID
static constexpr float PM10_0_GRID[NUM_LEVELS][2]
Definition
aqi_calculator.h:39
esphome::aqi::AQICalculator::INDEX_GRID
static constexpr int INDEX_GRID[NUM_LEVELS][2]
Definition
aqi_calculator.h:26
esphome::aqi::AbstractAQICalculator
Definition
abstract_aqi_calculator.h:7
esphome::aqi
Definition
abstract_aqi_calculator.h:5
Generated by
1.12.0