Merge pull request #263 from airgradienthq/fix/correction

Fix EPA compensated on top of SLR correction
This commit is contained in:
Samuel Siburian
2024-11-19 02:20:51 +07:00
committed by GitHub
4 changed files with 42 additions and 42 deletions

View File

@ -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}` | | `tvocLearningOffset` | Set VOC learning gain offset. | Number | 0-720 (default 12) | `{"tvocLearningOffset": 12}` |
| `offlineMode` | Set monitor to run without WiFi. | Boolean | `false`: Disabled (default) <br> `true`: Enabled | `{"offlineMode": true}` | | `offlineMode` | Set monitor to run without WiFi. | Boolean | `false`: Disabled (default) <br> `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) <br> `true`: with compensate | `{"monitorDisplayCompensatedValues": false }` | | `monitorDisplayCompensatedValues` | Set the display show the PM value with/without compensate value (only on [3.1.9]()) | Boolean | `false`: Without compensate (default) <br> `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 - PMS5003_20231218
```bash ```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 - PMS5003_20240104

View File

@ -354,16 +354,16 @@ bool Configuration::begin(void) {
* @return false Failure * @return false Failure
*/ */
bool Configuration::parse(String data, bool isLocal) { bool Configuration::parse(String data, bool isLocal) {
logInfo("Parse configure: " + data); logInfo("Parsing configuration: " + data);
JSONVar root = JSON.parse(data); JSONVar root = JSON.parse(data);
failedMessage = ""; failedMessage = "";
if (root == undefined) { if (root == undefined || JSONVar::typeof_(root) != "object") {
logError("Parse configuration failed, JSON invalid (" + JSONVar::typeof_(root) + ")");
failedMessage = "JSON invalid"; failedMessage = "JSON invalid";
logError(failedMessage);
return false; return false;
} }
logInfo("Parse configure success"); logInfo("Parse configuration success");
/** Is configuration changed */ /** Is configuration changed */
bool changed = false; bool changed = false;

View File

@ -87,37 +87,37 @@ bool StateMachine::sensorhandleLeds(void) {
int StateMachine::co2handleLeds(void) { int StateMachine::co2handleLeds(void) {
int totalUsed = ag->ledBar.getNumberOfLeds(); int totalUsed = ag->ledBar.getNumberOfLeds();
int co2Value = round(value.getAverage(Measurements::CO2)); int co2Value = round(value.getAverage(Measurements::CO2));
if (co2Value <= 700) { if (co2Value <= 600) {
/** G; 1 */ /** G; 1 */
ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 1);
totalUsed = 1; totalUsed = 1;
} else if (co2Value <= 1000) { } else if (co2Value <= 800) {
/** GG; 2 */ /** GG; 2 */
ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 1);
ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 2); ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 2);
totalUsed = 2; totalUsed = 2;
} else if (co2Value <= 1333) { } else if (co2Value <= 1000) {
/** YYY; 3 */ /** YYY; 3 */
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 1); 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() - 2);
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 3); ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 3);
totalUsed = 3; totalUsed = 3;
} else if (co2Value <= 1666) { } else if (co2Value <= 1250) {
/** OOOO; 4 */ /** OOOO; 4 */
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 1);
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 2); ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 2);
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 3); ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 3);
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 4); ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 4);
totalUsed = 4; totalUsed = 4;
} else if (co2Value <= 2000) { } else if (co2Value <= 1500) {
/** OOOOO; 5 */ /** OOOOO; 5 */
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 1);
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 2); ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 2);
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 3); ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 3);
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 4); ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 4);
ag->ledBar.setColor(RGB_COLOR_Y, ag->ledBar.getNumberOfLeds() - 5); ag->ledBar.setColor(RGB_COLOR_O, ag->ledBar.getNumberOfLeds() - 5);
totalUsed = 5; totalUsed = 5;
} else if (co2Value <= 2666) { } else if (co2Value <= 1750) {
/** RRRRRR; 6 */ /** RRRRRR; 6 */
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 1); 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() - 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() - 5);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 6); ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 6);
totalUsed = 6; totalUsed = 6;
} else if (co2Value <= 3333) { } else if (co2Value <= 2000) {
/** RRRRRRR; 7 */ /** RRRRRRR; 7 */
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 1); 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() - 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() - 6);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 7); ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 7);
totalUsed = 7; totalUsed = 7;
} else if (co2Value <= 4000) { } else if (co2Value <= 3000) {
/** RRRRRRRR; 8 */ /** PPPPPPPP; 8 */
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 1);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 2); ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 2);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 3); ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 3);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 4); ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 4);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 5); ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 5);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 6); ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 6);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 7); ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 7);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 8); ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 8);
totalUsed = 8; totalUsed = 8;
} else { /** > 4000 */ } else { /** > 3000 */
/* PRPRPRPRP; 9 */ /* PRPRPRPRP; 9 */
ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 1); ag->ledBar.setColor(RGB_COLOR_P, ag->ledBar.getNumberOfLeds() - 1);
ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 2); ag->ledBar.setColor(RGB_COLOR_R, ag->ledBar.getNumberOfLeds() - 2);

View File

@ -562,7 +562,7 @@ float Measurements::getCorrectedPM25(AirGradient &ag, Configuration &config, boo
pmCorrection.intercept); pmCorrection.intercept);
if (pmCorrection.useEPA) { if (pmCorrection.useEPA) {
// Add EPA compensation on top of SLR // Add EPA compensation on top of SLR
corrected = ag.pms5003.compensate(pm25, humidity); corrected = ag.pms5003.compensate(corrected, humidity);
} }
} }
} }
@ -896,10 +896,10 @@ JSONVar Measurements::buildPMS(AirGradient &ag, int ch, bool allCh, bool withTem
pms[json_prop_pm03Count] = ag.round2(avg); pms[json_prop_pm03Count] = ag.round2(avg);
pms["channels"]["1"][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);
pms["channels"]["2"][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);
} 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[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); 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[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); 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[json_prop_pm05Count] = ag.round2(avg);
pms["channels"]["1"][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);
pms["channels"]["2"][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);
} 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[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); 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[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); 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[json_prop_pm1Count] = ag.round2(avg);
pms["channels"]["1"][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);
pms["channels"]["2"][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);
} 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[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); 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[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); 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[json_prop_pm25Count] = ag.round2(avg);
pms["channels"]["1"][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);
pms["channels"]["2"][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);
} 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[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); 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[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); pms["channels"]["2"][json_prop_pm25Count] = ag.round2(_pm_25_pc[1].update.avg);
} }