mirror of
https://github.com/esphome/esphome.git
synced 2026-05-27 03:36:19 +08:00
[aqi] Fix AQI calculation for specific pm2.5 or pm10 readings (#13770)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include "abstract_aqi_calculator.h"
|
#include "abstract_aqi_calculator.h"
|
||||||
@@ -14,7 +15,11 @@ class AQICalculator : public AbstractAQICalculator {
|
|||||||
float pm2_5_index = calculate_index(pm2_5_value, PM2_5_GRID);
|
float pm2_5_index = calculate_index(pm2_5_value, PM2_5_GRID);
|
||||||
float pm10_0_index = calculate_index(pm10_0_value, PM10_0_GRID);
|
float pm10_0_index = calculate_index(pm10_0_value, PM10_0_GRID);
|
||||||
|
|
||||||
return static_cast<uint16_t>(std::round((pm2_5_index < pm10_0_index) ? pm10_0_index : pm2_5_index));
|
float aqi = std::max(pm2_5_index, pm10_0_index);
|
||||||
|
if (aqi < 0.0f) {
|
||||||
|
aqi = 0.0f;
|
||||||
|
}
|
||||||
|
return static_cast<uint16_t>(std::lround(aqi));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -22,13 +27,27 @@ class AQICalculator : public AbstractAQICalculator {
|
|||||||
|
|
||||||
static constexpr int INDEX_GRID[NUM_LEVELS][2] = {{0, 50}, {51, 100}, {101, 150}, {151, 200}, {201, 300}, {301, 500}};
|
static constexpr int INDEX_GRID[NUM_LEVELS][2] = {{0, 50}, {51, 100}, {101, 150}, {151, 200}, {201, 300}, {301, 500}};
|
||||||
|
|
||||||
static constexpr float PM2_5_GRID[NUM_LEVELS][2] = {{0.0f, 9.0f}, {9.1f, 35.4f},
|
static constexpr float PM2_5_GRID[NUM_LEVELS][2] = {
|
||||||
{35.5f, 55.4f}, {55.5f, 125.4f},
|
// clang-format off
|
||||||
{125.5f, 225.4f}, {225.5f, std::numeric_limits<float>::max()}};
|
{0.0f, 9.1f},
|
||||||
|
{9.1f, 35.5f},
|
||||||
|
{35.5f, 55.5f},
|
||||||
|
{55.5f, 125.5f},
|
||||||
|
{125.5f, 225.5f},
|
||||||
|
{225.5f, std::numeric_limits<float>::max()}
|
||||||
|
// clang-format on
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr float PM10_0_GRID[NUM_LEVELS][2] = {{0.0f, 54.0f}, {55.0f, 154.0f},
|
static constexpr float PM10_0_GRID[NUM_LEVELS][2] = {
|
||||||
{155.0f, 254.0f}, {255.0f, 354.0f},
|
// clang-format off
|
||||||
{355.0f, 424.0f}, {425.0f, std::numeric_limits<float>::max()}};
|
{0.0f, 55.0f},
|
||||||
|
{55.0f, 155.0f},
|
||||||
|
{155.0f, 255.0f},
|
||||||
|
{255.0f, 355.0f},
|
||||||
|
{355.0f, 425.0f},
|
||||||
|
{425.0f, std::numeric_limits<float>::max()}
|
||||||
|
// clang-format on
|
||||||
|
};
|
||||||
|
|
||||||
static float calculate_index(float value, const float array[NUM_LEVELS][2]) {
|
static float calculate_index(float value, const float array[NUM_LEVELS][2]) {
|
||||||
int grid_index = get_grid_index(value, array);
|
int grid_index = get_grid_index(value, array);
|
||||||
@@ -45,7 +64,10 @@ class AQICalculator : public AbstractAQICalculator {
|
|||||||
|
|
||||||
static int get_grid_index(float value, const float array[NUM_LEVELS][2]) {
|
static int get_grid_index(float value, const float array[NUM_LEVELS][2]) {
|
||||||
for (int i = 0; i < NUM_LEVELS; i++) {
|
for (int i = 0; i < NUM_LEVELS; i++) {
|
||||||
if (value >= array[i][0] && value <= array[i][1]) {
|
const bool in_range =
|
||||||
|
(value >= array[i][0]) && ((i == NUM_LEVELS - 1) ? (value <= array[i][1]) // last bucket inclusive
|
||||||
|
: (value < array[i][1])); // others exclusive on hi
|
||||||
|
if (in_range) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include "abstract_aqi_calculator.h"
|
#include "abstract_aqi_calculator.h"
|
||||||
@@ -12,7 +13,11 @@ class CAQICalculator : public AbstractAQICalculator {
|
|||||||
float pm2_5_index = calculate_index(pm2_5_value, PM2_5_GRID);
|
float pm2_5_index = calculate_index(pm2_5_value, PM2_5_GRID);
|
||||||
float pm10_0_index = calculate_index(pm10_0_value, PM10_0_GRID);
|
float pm10_0_index = calculate_index(pm10_0_value, PM10_0_GRID);
|
||||||
|
|
||||||
return static_cast<uint16_t>(std::round((pm2_5_index < pm10_0_index) ? pm10_0_index : pm2_5_index));
|
float aqi = std::max(pm2_5_index, pm10_0_index);
|
||||||
|
if (aqi < 0.0f) {
|
||||||
|
aqi = 0.0f;
|
||||||
|
}
|
||||||
|
return static_cast<uint16_t>(std::lround(aqi));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -21,10 +26,24 @@ class CAQICalculator : public AbstractAQICalculator {
|
|||||||
static constexpr int INDEX_GRID[NUM_LEVELS][2] = {{0, 25}, {26, 50}, {51, 75}, {76, 100}, {101, 400}};
|
static constexpr int INDEX_GRID[NUM_LEVELS][2] = {{0, 25}, {26, 50}, {51, 75}, {76, 100}, {101, 400}};
|
||||||
|
|
||||||
static constexpr float PM2_5_GRID[NUM_LEVELS][2] = {
|
static constexpr float PM2_5_GRID[NUM_LEVELS][2] = {
|
||||||
{0.0f, 15.0f}, {15.1f, 30.0f}, {30.1f, 55.0f}, {55.1f, 110.0f}, {110.1f, std::numeric_limits<float>::max()}};
|
// clang-format off
|
||||||
|
{0.0f, 15.1f},
|
||||||
|
{15.1f, 30.1f},
|
||||||
|
{30.1f, 55.1f},
|
||||||
|
{55.1f, 110.1f},
|
||||||
|
{110.1f, std::numeric_limits<float>::max()}
|
||||||
|
// clang-format on
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr float PM10_0_GRID[NUM_LEVELS][2] = {
|
static constexpr float PM10_0_GRID[NUM_LEVELS][2] = {
|
||||||
{0.0f, 25.0f}, {25.1f, 50.0f}, {50.1f, 90.0f}, {90.1f, 180.0f}, {180.1f, std::numeric_limits<float>::max()}};
|
// clang-format off
|
||||||
|
{0.0f, 25.1f},
|
||||||
|
{25.1f, 50.1f},
|
||||||
|
{50.1f, 90.1f},
|
||||||
|
{90.1f, 180.1f},
|
||||||
|
{180.1f, std::numeric_limits<float>::max()}
|
||||||
|
// clang-format on
|
||||||
|
};
|
||||||
|
|
||||||
static float calculate_index(float value, const float array[NUM_LEVELS][2]) {
|
static float calculate_index(float value, const float array[NUM_LEVELS][2]) {
|
||||||
int grid_index = get_grid_index(value, array);
|
int grid_index = get_grid_index(value, array);
|
||||||
@@ -42,7 +61,10 @@ class CAQICalculator : public AbstractAQICalculator {
|
|||||||
|
|
||||||
static int get_grid_index(float value, const float array[NUM_LEVELS][2]) {
|
static int get_grid_index(float value, const float array[NUM_LEVELS][2]) {
|
||||||
for (int i = 0; i < NUM_LEVELS; i++) {
|
for (int i = 0; i < NUM_LEVELS; i++) {
|
||||||
if (value >= array[i][0] && value <= array[i][1]) {
|
const bool in_range =
|
||||||
|
(value >= array[i][0]) && ((i == NUM_LEVELS - 1) ? (value <= array[i][1]) // last bucket inclusive
|
||||||
|
: (value < array[i][1])); // others exclusive on hi
|
||||||
|
if (in_range) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user