From 1b4d89e1a1f2879c1d481b065e8db381b10e9784 Mon Sep 17 00:00:00 2001 From: samuelbles07 Date: Mon, 18 Nov 2024 19:53:28 +0700 Subject: [PATCH 1/6] fix correction on top of compensation --- src/AgValue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AgValue.cpp b/src/AgValue.cpp index b0b281d..6772147 100644 --- a/src/AgValue.cpp +++ b/src/AgValue.cpp @@ -562,7 +562,7 @@ float Measurements::getCorrectedPM25(AirGradient &ag, Configuration &config, boo pmCorrection.intercept); if (pmCorrection.useEPA) { // Add EPA compensation on top of SLR - corrected = ag.pms5003.compensate(pm25, humidity); + corrected = ag.pms5003.compensate(corrected, humidity); } } } From a6b48acb41bc9951d30a5f309c5f08302b270f22 Mon Sep 17 00:00:00 2001 From: samuelbles07 Date: Mon, 18 Nov 2024 21:24:47 +0700 Subject: [PATCH 2/6] CO2 led bar indicator sync fix --- src/AgStateMachine.cpp | 54 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/AgStateMachine.cpp b/src/AgStateMachine.cpp index 63d8d63..3656bde 100644 --- a/src/AgStateMachine.cpp +++ b/src/AgStateMachine.cpp @@ -87,37 +87,37 @@ bool StateMachine::sensorhandleLeds(void) { int StateMachine::co2handleLeds(void) { int totalUsed = ag->ledBar.getNumberOfLeds(); int co2Value = round(value.getAverage(Measurements::CO2)); - if (co2Value <= 700) { + if (co2Value <= 600) { /** G; 1 */ ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 1); totalUsed = 1; - } else if (co2Value <= 1000) { + } else if (co2Value <= 800) { /** GG; 2 */ ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 2); totalUsed = 2; - } else if (co2Value <= 1333) { + } else if (co2Value <= 1000) { /** YYY; 3 */ ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 2); ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 3); totalUsed = 3; - } else if (co2Value <= 1666) { + } else if (co2Value <= 1250) { /** OOOO; 4 */ - ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 1); - ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 2); - ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 3); - ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 4); + ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 1); + ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 2); + ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 3); + ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 4); totalUsed = 4; - } else if (co2Value <= 2000) { + } else if (co2Value <= 1500) { /** OOOOO; 5 */ - ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 1); - ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 2); - ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 3); - ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 4); - ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 5); + ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 1); + ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 2); + ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 3); + ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 4); + ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 5); totalUsed = 5; - } else if (co2Value <= 2666) { + } else if (co2Value <= 1750) { /** RRRRRR; 6 */ ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 2); @@ -126,7 +126,7 @@ int StateMachine::co2handleLeds(void) { ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 5); ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 6); totalUsed = 6; - } else if (co2Value <= 3333) { + } else if (co2Value <= 2000) { /** RRRRRRR; 7 */ ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 2); @@ -136,18 +136,18 @@ int StateMachine::co2handleLeds(void) { ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 6); ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 7); totalUsed = 7; - } else if (co2Value <= 4000) { - /** RRRRRRRR; 8 */ - ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 1); - ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 2); - ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 3); - ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 4); - ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 5); - ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 6); - ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 7); - ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 8); + } else if (co2Value <= 3000) { + /** PPPPPPPP; 8 */ + ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 1); + ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 2); + ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 3); + ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 4); + ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 5); + ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 6); + ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 7); + ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 8); totalUsed = 8; - } else { /** > 4000 */ + } else { /** > 3000 */ /* PRPRPRPRP; 9 */ ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 2); From 46f6309b77df0a642d542117e1a54095e606fdab Mon Sep 17 00:00:00 2001 From: samuelbles07 Date: Mon, 18 Nov 2024 22:42:43 +0700 Subject: [PATCH 3/6] Fix use the right function --- src/AgValue.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/AgValue.cpp b/src/AgValue.cpp index 6772147..0df5db8 100644 --- a/src/AgValue.cpp +++ b/src/AgValue.cpp @@ -896,10 +896,10 @@ JSONVar Measurements::buildPMS(AirGradient &ag, int ch, bool allCh, bool withTem pms[json_prop_pm03Count] = ag.round2(avg); pms["channels"]["1"][json_prop_pm03Count] = ag.round2(_pm_03_pc[0].update.avg); pms["channels"]["2"][json_prop_pm03Count] = ag.round2(_pm_03_pc[1].update.avg); - } else if (utils::isValidPm(_pm_03_pc[0].update.avg)) { + } else if (utils::isValidPm03Count(_pm_03_pc[0].update.avg)) { pms[json_prop_pm03Count] = ag.round2(_pm_03_pc[0].update.avg); pms["channels"]["1"][json_prop_pm03Count] = ag.round2(_pm_03_pc[0].update.avg); - } else if (utils::isValidPm(_pm_03_pc[1].update.avg)) { + } else if (utils::isValidPm03Count(_pm_03_pc[1].update.avg)) { pms[json_prop_pm03Count] = ag.round2(_pm_03_pc[1].update.avg); pms["channels"]["2"][json_prop_pm03Count] = ag.round2(_pm_03_pc[1].update.avg); } @@ -911,10 +911,10 @@ JSONVar Measurements::buildPMS(AirGradient &ag, int ch, bool allCh, bool withTem pms[json_prop_pm05Count] = ag.round2(avg); pms["channels"]["1"][json_prop_pm05Count] = ag.round2(_pm_05_pc[0].update.avg); pms["channels"]["2"][json_prop_pm05Count] = ag.round2(_pm_05_pc[1].update.avg); - } else if (utils::isValidPm(_pm_05_pc[0].update.avg)) { + } else if (utils::isValidPm03Count(_pm_05_pc[0].update.avg)) { pms[json_prop_pm05Count] = ag.round2(_pm_05_pc[0].update.avg); pms["channels"]["1"][json_prop_pm05Count] = ag.round2(_pm_05_pc[0].update.avg); - } else if (utils::isValidPm(_pm_05_pc[1].update.avg)) { + } else if (utils::isValidPm03Count(_pm_05_pc[1].update.avg)) { pms[json_prop_pm05Count] = ag.round2(_pm_05_pc[1].update.avg); pms["channels"]["2"][json_prop_pm05Count] = ag.round2(_pm_05_pc[1].update.avg); } @@ -925,10 +925,10 @@ JSONVar Measurements::buildPMS(AirGradient &ag, int ch, bool allCh, bool withTem pms[json_prop_pm1Count] = ag.round2(avg); pms["channels"]["1"][json_prop_pm1Count] = ag.round2(_pm_01_pc[0].update.avg); pms["channels"]["2"][json_prop_pm1Count] = ag.round2(_pm_01_pc[1].update.avg); - } else if (utils::isValidPm(_pm_01_pc[0].update.avg)) { + } else if (utils::isValidPm03Count(_pm_01_pc[0].update.avg)) { pms[json_prop_pm1Count] = ag.round2(_pm_01_pc[0].update.avg); pms["channels"]["1"][json_prop_pm1Count] = ag.round2(_pm_01_pc[0].update.avg); - } else if (utils::isValidPm(_pm_01_pc[1].update.avg)) { + } else if (utils::isValidPm03Count(_pm_01_pc[1].update.avg)) { pms[json_prop_pm1Count] = ag.round2(_pm_01_pc[1].update.avg); pms["channels"]["2"][json_prop_pm1Count] = ag.round2(_pm_01_pc[1].update.avg); } @@ -940,10 +940,10 @@ JSONVar Measurements::buildPMS(AirGradient &ag, int ch, bool allCh, bool withTem pms[json_prop_pm25Count] = ag.round2(avg); pms["channels"]["1"][json_prop_pm25Count] = ag.round2(_pm_25_pc[0].update.avg); pms["channels"]["2"][json_prop_pm25Count] = ag.round2(_pm_25_pc[1].update.avg); - } else if (utils::isValidPm(_pm_25_pc[0].update.avg)) { + } else if (utils::isValidPm03Count(_pm_25_pc[0].update.avg)) { pms[json_prop_pm25Count] = ag.round2(_pm_25_pc[0].update.avg); pms["channels"]["1"][json_prop_pm25Count] = ag.round2(_pm_25_pc[0].update.avg); - } else if (utils::isValidPm(_pm_25_pc[1].update.avg)) { + } else if (utils::isValidPm03Count(_pm_25_pc[1].update.avg)) { pms[json_prop_pm25Count] = ag.round2(_pm_25_pc[1].update.avg); pms["channels"]["2"][json_prop_pm25Count] = ag.round2(_pm_25_pc[1].update.avg); } From 1de9344f43c69958ed8004ff6da756a26e055aa5 Mon Sep 17 00:00:00 2001 From: samuelbles07 Date: Mon, 18 Nov 2024 22:50:36 +0700 Subject: [PATCH 4/6] Fix typo on docs --- docs/local-server.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/local-server.md b/docs/local-server.md index 3a54c98..4cbd851 100644 --- a/docs/local-server.md +++ b/docs/local-server.md @@ -156,7 +156,7 @@ If the monitor is set up on the AirGradient dashboard, it will also receive the | `tvocLearningOffset` | Set VOC learning gain offset. | Number | 0-720 (default 12) | `{"tvocLearningOffset": 12}` | | `offlineMode` | Set monitor to run without WiFi. | Boolean | `false`: Disabled (default)
`true`: Enabled | `{"offlineMode": true}` | | `monitorDisplayCompensatedValues` | Set the display show the PM value with/without compensate value (only on [3.1.9]()) | Boolean | `false`: Without compensate (default)
`true`: with compensate | `{"monitorDisplayCompensatedValues": false }` | -| `corrections` | Sets correction options to display and measurement values on local server response. | Object | _see corrections section_ | _see corrections section_ | +| `corrections` | Sets correction options to display and measurement values on local server response. (version >= [3.1.11]()) | Object | _see corrections section_ | _see corrections section_ | @@ -206,7 +206,7 @@ curl --location -X PUT 'http://airgradient_84fce612eff4.local/config' --header ' - PMS5003_20231218 ```bash -curl --location -X PUT 'http://airgradient_84fce612eff4.local/config' --header 'Content-Type: application/json' --data '{"corrections":{"pm02":{"correctionAlgorithm":"slr_PMS5003_20231218","slr":{"intercept":0,"scalingFactor":0,03525,"useEpa2021":true}}}}' +curl --location -X PUT 'http://airgradient_84fce612eff4.local/config' --header 'Content-Type: application/json' --data '{"corrections":{"pm02":{"correctionAlgorithm":"slr_PMS5003_20231218","slr":{"intercept":0,"scalingFactor":0.03525,"useEpa2021":true}}}}' ``` - PMS5003_20240104 From 902a768f28b142c0c7b525de41dc2ba9e06f2a62 Mon Sep 17 00:00:00 2001 From: samuelbles07 Date: Tue, 19 Nov 2024 01:45:50 +0700 Subject: [PATCH 5/6] Handle parsing invalid json string --- src/AgConfigure.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AgConfigure.cpp b/src/AgConfigure.cpp index f090d3d..57e864b 100644 --- a/src/AgConfigure.cpp +++ b/src/AgConfigure.cpp @@ -354,16 +354,16 @@ bool Configuration::begin(void) { * @return false Failure */ bool Configuration::parse(String data, bool isLocal) { - logInfo("Parse configure: " + data); + logInfo("Parsing configuration: " + data); JSONVar root = JSON.parse(data); failedMessage = ""; - if (root == undefined) { + if (root == undefined || JSONVar::typeof_(root) != "object") { + logError("Parse configuration failed, JSON invalid (" + JSONVar::typeof_(root) + ")"); failedMessage = "JSON invalid"; - logError(failedMessage); return false; } - logInfo("Parse configure success"); + logInfo("Parse configuration success"); /** Is configuration changed */ bool changed = false; From 3644dc43fe8bb66a6b889ea0032a025d80b6138b Mon Sep 17 00:00:00 2001 From: samuelbles07 Date: Tue, 19 Nov 2024 18:44:23 +0700 Subject: [PATCH 6/6] Prepared to release 3.1.12 --- library.properties | 2 +- src/AirGradient.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.properties b/library.properties index afa6008..4b1742a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AirGradient Air Quality Sensor -version=3.1.11 +version=3.1.12 author=AirGradient maintainer=AirGradient sentence=ESP32-C3 / ESP8266 library for air quality monitor measuring PM, CO2, Temperature, TVOC and Humidity with OLED display. diff --git a/src/AirGradient.h b/src/AirGradient.h index a6986e8..754db60 100644 --- a/src/AirGradient.h +++ b/src/AirGradient.h @@ -15,7 +15,7 @@ #include "Main/utils.h" #ifndef GIT_VERSION -#define GIT_VERSION "3.1.11-snap" +#define GIT_VERSION "3.1.12-snap" #endif /**