From 7b0381dea315e9bdbfce45b203e6e3cbf37d92bf Mon Sep 17 00:00:00 2001 From: samuelbles07 Date: Sat, 2 Nov 2024 14:44:32 +0700 Subject: [PATCH] Apply pm correction to display and led bar --- src/AgOledDisplay.cpp | 10 ++++------ src/AgStateMachine.cpp | 4 ++-- src/AgValue.cpp | 33 +++++++++++++++++++++++++++++++++ src/AgValue.h | 12 ++++++++++++ 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/AgOledDisplay.cpp b/src/AgOledDisplay.cpp index 5661f21..7f11bb5 100644 --- a/src/AgOledDisplay.cpp +++ b/src/AgOledDisplay.cpp @@ -314,13 +314,11 @@ void OledDisplay::showDashboard(const char *status) { /** Draw PM2.5 value */ int pm25 = value.get(Measurements::PM25); - if (utils::isValidPm(pm25)) { - /** Compensate PM2.5 value. */ - if (config.hasSensorSHT && config.isMonitorDisplayCompensatedValues()) { - pm25 = ag->pms5003.compensate(pm25, value.getFloat(Measurements::Humidity)); - logInfo("PM2.5 compensate: " + String(pm25)); - } + if (config.hasSensorSHT && config.isPMCorrectionEnabled()) { + pm25 = (int)value.getCorrectedPM25(*ag, config); + } + if (utils::isValidPm(pm25)) { if (config.isPmStandardInUSAQI()) { sprintf(strBuf, "%d", ag->pms5003.convertPm25ToUsAqi(pm25)); } else { diff --git a/src/AgStateMachine.cpp b/src/AgStateMachine.cpp index 9cbe068..8e0be6a 100644 --- a/src/AgStateMachine.cpp +++ b/src/AgStateMachine.cpp @@ -142,8 +142,8 @@ void StateMachine::co2handleLeds(void) { */ void StateMachine::pm25handleLeds(void) { int pm25Value = value.get(Measurements::PM25); - if (config.isMonitorDisplayCompensatedValues() && config.hasSensorSHT) { - pm25Value = ag->pms5003.compensate(pm25Value, value.getFloat(Measurements::Humidity)); + if (config.hasSensorSHT && config.isPMCorrectionEnabled()) { + pm25Value = (int)value.getCorrectedPM25(*ag, config); } if (pm25Value < 5) { diff --git a/src/AgValue.cpp b/src/AgValue.cpp index fb7135a..bcf617b 100644 --- a/src/AgValue.cpp +++ b/src/AgValue.cpp @@ -1,6 +1,7 @@ #include "AgValue.h" #include "AgConfigure.h" #include "AirGradient.h" +#include "App/AppDef.h" #define json_prop_pmFirmware "firmware" #define json_prop_pm01Ae "pm01" @@ -482,6 +483,38 @@ void Measurements::validateChannel(int ch) { } } +float Measurements::getCorrectedPM25(AirGradient &ag, Configuration &config, bool useAvg, int ch) { + float pm25; + float humidity; + float pm003Count; + int channel = ch - 1; // Array index + if (useAvg) { + // Directly call from the index + pm25 = _pm_25[channel].update.avg; + humidity = _humidity[channel].update.avg; + pm003Count = _pm_03_pc[channel].update.avg; + } else { + pm25 = get(PM25, ch); + humidity = getFloat(Humidity, ch); + pm003Count = get(PM03_PC, ch); + } + + Configuration::PMCorrection pmCorrection = config.getPMCorrection(); + if (pmCorrection.algorithm == PMCorrectionAlgorithm::EPA_2021) { + // EPA correction directly applied + pm25 = ag.pms5003.compensate(pm25, humidity); + } else { + // SLR correction, this is assumes before calling this function, correction algorithm is not None + pm25 = ag.pms5003.slrCorrection(pm25, pm003Count, pmCorrection.scalingFactor, pmCorrection.intercept); + if (pmCorrection.useEPA) { + // Add EPA compensation on top of SLR + pm25 = ag.pms5003.compensate(pm25, humidity); + } + } + + return pm25; +} + String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, AirGradient &ag, Configuration &config) { JSONVar root; diff --git a/src/AgValue.h b/src/AgValue.h index 5efea18..3b129b3 100644 --- a/src/AgValue.h +++ b/src/AgValue.h @@ -114,6 +114,18 @@ public: */ float getFloat(MeasurementType type, int ch = 1); + + /** + * @brief Get the Corrected PM25 object based on the correction algorithm from configuration + * + * @param ag AirGradient instance + * @param config Configuration instance + * @param useAvg Use moving average value if true, otherwise use latest value + * @param ch MeasurementType channel + * @return float Corrected PM2.5 value + */ + float getCorrectedPM25(AirGradient &ag, Configuration &config, bool useAvg = false, int ch = 1); + /** * build json payload for every measurements */