diff --git a/docs/local-server.md b/docs/local-server.md
index 1daede0..25cab52 100644
--- a/docs/local-server.md
+++ b/docs/local-server.md
@@ -41,33 +41,35 @@ You get the following response:
"bootCount": 6,
"ledMode": "pm",
"firmware": "3.1.3",
- "model": "I-9PSL"
+ "model": "I-9PSL",
+ "monitorDisplayCompensatedValues": true
}
```
-| Properties | Type | Explanation |
-|------------------|--------|--------------------------------------------------------------------|
-| `serialno` | String | Serial Number of the monitor |
-| `wifi` | Number | WiFi signal strength |
-| `pm01` | Number | PM1 in ug/m3 |
-| `pm02` | Number | PM2.5 in ug/m3 |
-| `pm10` | Number | PM10 in ug/m3 |
-| `pm02Compensated` | Number | PM2.5 in ug/m3 with correction applied (from fw version 3.1.4 onwards) |
-| `rco2` | Number | CO2 in ppm |
-| `pm003Count` | Number | Particle count per dL |
-| `atmp` | Number | Temperature in Degrees Celsius |
-| `atmpCompensated` | Number | Temperature in Degrees Celsius with correction applied |
-| `rhum` | Number | Relative Humidity |
-| `rhumCompensated` | Number | Relative Humidity with correction applied |
-| `tvocIndex` | Number | Senisiron VOC Index |
-| `tvocRaw` | Number | VOC raw value |
-| `noxIndex` | Number | Senisirion NOx Index |
-| `noxRaw` | Number | NOx raw value |
-| `boot` | Number | Counts every measurement cycle. Low boot counts indicate restarts. |
-| `bootCount` | Number | Same as boot property. Required for Home Assistant compatability. Will be depreciated. |
-| `ledMode` | String | Current configuration of the LED mode |
-| `firmware` | String | Current firmware version |
-| `model` | String | Current model name |
+| Properties | Type | Explanation |
+|-----------------------------------|---------|----------------------------------------------------------------------------------------|
+| `serialno` | String | Serial Number of the monitor |
+| `wifi` | Number | WiFi signal strength |
+| `pm01` | Number | PM1 in ug/m3 |
+| `pm02` | Number | PM2.5 in ug/m3 |
+| `pm10` | Number | PM10 in ug/m3 |
+| `pm02Compensated` | Number | PM2.5 in ug/m3 with correction applied (from fw version 3.1.4 onwards) |
+| `rco2` | Number | CO2 in ppm |
+| `pm003Count` | Number | Particle count per dL |
+| `atmp` | Number | Temperature in Degrees Celsius |
+| `atmpCompensated` | Number | Temperature in Degrees Celsius with correction applied |
+| `rhum` | Number | Relative Humidity |
+| `rhumCompensated` | Number | Relative Humidity with correction applied |
+| `tvocIndex` | Number | Senisiron VOC Index |
+| `tvocRaw` | Number | VOC raw value |
+| `noxIndex` | Number | Senisirion NOx Index |
+| `noxRaw` | Number | NOx raw value |
+| `boot` | Number | Counts every measurement cycle. Low boot counts indicate restarts. |
+| `bootCount` | Number | Same as boot property. Required for Home Assistant compatability. Will be depreciated. |
+| `ledMode` | String | Current configuration of the LED mode |
+| `firmware` | String | Current firmware version |
+| `model` | String | Current model name |
+| `monitorDisplayCompensatedValues` | Boolean | Switching Display of AirGradient ONE to Compensated / Non Compensated Values |
Compensated values apply correction algorithms to make the sensor values more accurate. Temperature and relative humidity correction is only applied on the outdoor monitor Open Air but the properties _compensated will still be send also for the indoor monitor AirGradient ONE.
@@ -110,21 +112,22 @@ If the monitor is set up on the AirGradient dashboard, it will also receive conf
#### Configuration Parameters (GET/PUT)
-| Properties | Description | Type | Accepted Values | Example |
-|-------------------------|:-------------------------------------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
-| `country` | Country where the device is. | String | Country code as [ALPHA-2 notation](https://www.iban.com/country-codes) | {"country": "TH"} |
-| `model` | Hardware identifier (only GET). | String | I-9PSL-DE | {"model": "I-9PSL-DE"} |
-| `pmStandard` | Particle matter standard used on the display. | String | `ugm3`: ug/m3
`us-aqi`: USAQI | {"pmStandard": "ugm3"} |
-| `ledBarMode` | Mode in which the led bar can be set. | String | `co2`: LED bar displays CO2
`pm`: LED bar displays PM
`off`: Turn off LED bar | {"ledBarMode": "off"} |
-| `displayBrightness` | Brightness of the Display. | Number | 0-100 | {"displayBrightness": 50} |
-| `ledBarBrightness` | Brightness of the LEDBar. | Number | 0-100 | {"ledBarBrightness": 40} |
-| `abcDays` | Number of days for CO2 automatic baseline calibration. | Number | Maximum 200 days. Default 8 days. | {"abcDays": 8} |
-| `mqttBrokerUrl` | MQTT broker URL. | String | | {"mqttBrokerUrl": "mqtt://192.168.0.18:1883"} |
-| `temperatureUnit` | Temperature unit shown on the display. | String | `c` or `C`: Degree Celsius °C
`f` or `F`: Degree Fahrenheit °F | {"temperatureUnit": "c"} |
-| `configurationControl` | The configuration source of the device. | String | `both`: Accept local and cloud configuration
`local`: Accept only local configuration
`cloud`: Accept only cloud configuration | {"configurationControl": "both"} |
-| `postDataToAirGradient` | Send data to AirGradient cloud. | Boolean | `true`: Enabled
`false`: Disabled | {"postDataToAirGradient": true} |
-| `co2CalibrationRequested` | Can be set to trigger a calibration. | Boolean | `true`: CO2 calibration (400ppm) will be triggered | {"co2CalibrationRequested": true} |
-| `ledBarTestRequested` | Can be set to trigger a test. | Boolean | `true` : LEDs will run test sequence | {"ledBarTestRequested": true} |
-| `noxLearningOffset` | Set NOx learning gain offset. | Number | 0-720 (default 12) | {"noxLearningOffset": 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)
`true`: Enabled | {"offlineMode": true} |
+| Properties | Description | Type | Accepted Values | Example |
+|-----------------------------------|:-----------------------------------------------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|
+| `country` | Country where the device is. | String | Country code as [ALPHA-2 notation](https://www.iban.com/country-codes) | `{"country": "TH"}` |
+| `model` | Hardware identifier (only GET). | String | I-9PSL-DE | `{"model": "I-9PSL-DE"}` |
+| `pmStandard` | Particle matter standard used on the display. | String | `ugm3`: ug/m3
`us-aqi`: USAQI | `{"pmStandard": "ugm3"}` |
+| `ledBarMode` | Mode in which the led bar can be set. | String | `co2`: LED bar displays CO2
`pm`: LED bar displays PM
`off`: Turn off LED bar | `{"ledBarMode": "off"}` |
+| `displayBrightness` | Brightness of the Display. | Number | 0-100 | `{"displayBrightness": 50}` |
+| `ledBarBrightness` | Brightness of the LEDBar. | Number | 0-100 | `{"ledBarBrightness": 40}` |
+| `abcDays` | Number of days for CO2 automatic baseline calibration. | Number | Maximum 200 days. Default 8 days. | `{"abcDays": 8}` |
+| `mqttBrokerUrl` | MQTT broker URL. | String | | `{"mqttBrokerUrl": "mqtt://192.168.0.18:1883"}` |
+| `temperatureUnit` | Temperature unit shown on the display. | String | `c` or `C`: Degree Celsius °C
`f` or `F`: Degree Fahrenheit °F | `{"temperatureUnit": "c"}` |
+| `configurationControl` | The configuration source of the device. | String | `both`: Accept local and cloud configuration
`local`: Accept only local configuration
`cloud`: Accept only cloud configuration | `{"configurationControl": "both"}` |
+| `postDataToAirGradient` | Send data to AirGradient cloud. | Boolean | `true`: Enabled
`false`: Disabled | `{"postDataToAirGradient": true}` |
+| `co2CalibrationRequested` | Can be set to trigger a calibration. | Boolean | `true`: CO2 calibration (400ppm) will be triggered | `{"co2CalibrationRequested": true}` |
+| `ledBarTestRequested` | Can be set to trigger a test. | Boolean | `true` : LEDs will run test sequence | `{"ledBarTestRequested": true}` |
+| `noxLearningOffset` | Set NOx learning gain offset. | Number | 0-720 (default 12) | `{"noxLearningOffset": 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)
`true`: Enabled | `{"offlineMode": true}` |
+| `monitorDisplayCompensatedValues` | Set the display show the PM value with/without compensate value (From [3.1.8]()) | Boolean | `false`: Without compensate (default)
`true`: with compensate | `{"monitorDisplayCompensatedValues": false }` |
diff --git a/src/AgConfigure.cpp b/src/AgConfigure.cpp
index 99e00c1..f3abd7c 100644
--- a/src/AgConfigure.cpp
+++ b/src/AgConfigure.cpp
@@ -41,21 +41,23 @@ JSON_PROP_DEF(displayBrightness);
JSON_PROP_DEF(co2CalibrationRequested);
JSON_PROP_DEF(ledBarTestRequested);
JSON_PROP_DEF(offlineMode);
+JSON_PROP_DEF(monitorDisplayCompensatedValues);
-#define jprop_model_default ""
-#define jprop_country_default "TH"
-#define jprop_pmStandard_default getPMStandardString(false)
-#define jprop_ledBarMode_default getLedBarModeName(LedBarMode::LedBarModeCO2)
-#define jprop_abcDays_default 8
-#define jprop_tvocLearningOffset_default 12
-#define jprop_noxLearningOffset_default 12
-#define jprop_mqttBrokerUrl_default ""
-#define jprop_temperatureUnit_default "c"
-#define jprop_configurationControl_default String(CONFIGURATION_CONTROL_NAME[ConfigurationControl::ConfigurationControlBoth])
-#define jprop_postDataToAirGradient_default true
-#define jprop_ledBarBrightness_default 100
-#define jprop_displayBrightness_default 100
-#define jprop_offlineMode_default false
+#define jprop_model_default ""
+#define jprop_country_default "TH"
+#define jprop_pmStandard_default getPMStandardString(false)
+#define jprop_ledBarMode_default getLedBarModeName(LedBarMode::LedBarModeCO2)
+#define jprop_abcDays_default 8
+#define jprop_tvocLearningOffset_default 12
+#define jprop_noxLearningOffset_default 12
+#define jprop_mqttBrokerUrl_default ""
+#define jprop_temperatureUnit_default "c"
+#define jprop_configurationControl_default String(CONFIGURATION_CONTROL_NAME[ConfigurationControl::ConfigurationControlBoth])
+#define jprop_postDataToAirGradient_default true
+#define jprop_ledBarBrightness_default 100
+#define jprop_displayBrightness_default 100
+#define jprop_offlineMode_default false
+#define jprop_monitorDisplayCompensatedValues_default false
JSONVar jconfig;
@@ -167,6 +169,7 @@ void Configuration::defaultConfig(void) {
jconfig[jprop_abcDays] = jprop_abcDays_default;
jconfig[jprop_model] = jprop_model_default;
jconfig[jprop_offlineMode] = jprop_offlineMode_default;
+ jconfig[jprop_monitorDisplayCompensatedValues] = jprop_monitorDisplayCompensatedValues_default;
saveConfig();
}
@@ -628,6 +631,27 @@ bool Configuration::parse(String data, bool isLocal) {
}
}
+ if (JSON.typeof_(root[jprop_monitorDisplayCompensatedValues]) == "boolean") {
+ bool value = root[jprop_monitorDisplayCompensatedValues];
+ bool oldValue = jconfig[jprop_monitorDisplayCompensatedValues];
+ if (value != oldValue) {
+ changed = true;
+ jconfig[jprop_monitorDisplayCompensatedValues] = value;
+
+ configLogInfo(String(jprop_monitorDisplayCompensatedValues),
+ String(oldValue ? "true" : "false"),
+ String(value ? "true" : "false"));
+ }
+ } else {
+ if (jsonTypeInvalid(root[jprop_monitorDisplayCompensatedValues],
+ "boolean")) {
+ failedMessage = jsonTypeInvalidMessage(
+ String(jprop_monitorDisplayCompensatedValues), "boolean");
+ jsonInvalid();
+ return false;
+ }
+ }
+
if (ag->getBoardType() == ONE_INDOOR ||
ag->getBoardType() == OPEN_AIR_OUTDOOR) {
if (JSON.typeof_(root["targetFirmware"]) == "string") {
@@ -1082,12 +1106,14 @@ void Configuration::toConfig(const char *buf) {
}
if (JSON.typeof_(jconfig[jprop_offlineMode]) != "boolean") {
- isInvalid = true;
- } else {
- isInvalid = false;
+ jconfig[jprop_offlineMode] = jprop_offlineMode_default;
}
- if (isInvalid) {
- jconfig[jprop_offlineMode] = false;
+
+ /** Validate monitorDisplayCompensatedValues */
+ if (JSON.typeof_(jconfig[jprop_monitorDisplayCompensatedValues]) !=
+ "boolean") {
+ jconfig[jprop_monitorDisplayCompensatedValues] =
+ jprop_monitorDisplayCompensatedValues_default;
}
if (changed) {
@@ -1173,6 +1199,10 @@ bool Configuration::isLedBarModeChanged(void) {
return changed;
}
+bool Configuration::isMonitorDisplayCompensatedValues(void) {
+ return jconfig[jprop_monitorDisplayCompensatedValues];
+}
+
bool Configuration::isDisplayBrightnessChanged(void) {
bool changed = displayBrightnessChanged;
displayBrightnessChanged = false;
diff --git a/src/AgConfigure.h b/src/AgConfigure.h
index 24473ec..a899b64 100644
--- a/src/AgConfigure.h
+++ b/src/AgConfigure.h
@@ -82,6 +82,7 @@ public:
void setOfflineMode(bool offline);
void setOfflineModeWithoutSave(bool offline);
bool isLedBarModeChanged(void);
+ bool isMonitorDisplayCompensatedValues(void);
};
#endif /** _AG_CONFIG_H_ */
diff --git a/src/AgOledDisplay.cpp b/src/AgOledDisplay.cpp
index 8250407..2a18d59 100644
--- a/src/AgOledDisplay.cpp
+++ b/src/AgOledDisplay.cpp
@@ -10,37 +10,49 @@
*
* @param hasStatus
*/
-void OledDisplay::showTempHum(bool hasStatus) {
- char buf[16];
+void OledDisplay::showTempHum(bool hasStatus, char* buf, int buf_size) {
if (utils::isValidTemperature(value.Temperature)) {
+ float t = 0.0f;
+ if(ag->isOpenAir() && config.isMonitorDisplayCompensatedValues()) {
+ if(config.isTemperatureUnitInF()) {
+ /** Compensate temperature */
+ t = ag->pms5003t_1.compensateTemp(value.Temperature);
+ /** Convert C to F */
+ t = (t * 9)/5.0f + 32.0f;
+ }
+ } else {
+
+ }
+
+
if (config.isTemperatureUnitInF()) {
float tempF = (value.Temperature * 9) / 5 + 32;
if (hasStatus) {
- snprintf(buf, sizeof(buf), "%0.1f", tempF);
+ snprintf(buf, buf_size, "%0.1f", tempF);
} else {
- snprintf(buf, sizeof(buf), "%0.1f°F", tempF);
+ snprintf(buf, buf_size, "%0.1f°F", tempF);
}
} else {
if (hasStatus) {
- snprintf(buf, sizeof(buf), "%.1f", value.Temperature);
+ snprintf(buf, buf_size, "%.1f", value.Temperature);
} else {
- snprintf(buf, sizeof(buf), "%.1f°C", value.Temperature);
+ snprintf(buf, buf_size, "%.1f°C", value.Temperature);
}
}
} else {
if (config.isTemperatureUnitInF()) {
- snprintf(buf, sizeof(buf), "-°F");
+ snprintf(buf, buf_size, "-°F");
} else {
- snprintf(buf, sizeof(buf), "-°C");
+ snprintf(buf, buf_size, "-°C");
}
}
DISP()->drawUTF8(1, 10, buf);
/** Show humidty */
if (utils::isValidHumidity(value.Humidity)) {
- snprintf(buf, sizeof(buf), "%d%%", value.Humidity);
+ snprintf(buf, buf_size, "%d%%", value.Humidity);
} else {
- snprintf(buf, sizeof(buf), "-%%");
+ snprintf(buf, buf_size, "-%%");
}
if (value.Humidity > 99) {
@@ -261,7 +273,7 @@ void OledDisplay::showDashboard(const char *status) {
do {
DISP()->setFont(u8g2_font_t0_16_tf);
if ((status == NULL) || (strlen(status) == 0)) {
- showTempHum(false);
+ showTempHum(false, strBuf, sizeof(strBuf));
} else {
String strStatus = "Show status: " + String(status);
logInfo(strStatus);
@@ -272,7 +284,7 @@ void OledDisplay::showDashboard(const char *status) {
/** Show WiFi NA*/
if (strcmp(status, "WiFi N/A") == 0) {
DISP()->setFont(u8g2_font_t0_12_tf);
- showTempHum(true);
+ showTempHum(true, strBuf, sizeof(strBuf));
}
}
@@ -304,29 +316,27 @@ void OledDisplay::showDashboard(const char *status) {
DISP()->drawStr(55, 27, "PM2.5");
/** Draw PM2.5 value */
- int pm25 = value.pm25_1;
- if (config.hasSensorSHT) {
- pm25 = ag->pms5003.compensate(pm25, value.Humidity);
- logInfo("PM2.5:" + String(value.pm25_1) + String("Compensated:") + String(pm25));
- }
- DISP()->setFont(u8g2_font_t0_22b_tf);
- if (config.isPmStandardInUSAQI()) {
- if (utils::isValidPm(pm25)) {
+ if (utils::isValidPm(value.pm25_1)) {
+ int pm25 = value.pm25_1;
+ if (config.isPmStandardInUSAQI() &&
+ config.isMonitorDisplayCompensatedValues()) {
+ if (config.hasSensorSHT) {
+ pm25 = ag->pms5003.compensate(pm25, value.Humidity);
+ }
sprintf(strBuf, "%d", ag->pms5003.convertPm25ToUsAqi(pm25));
} else {
- sprintf(strBuf, "%s", "-");
+ sprintf(strBuf, "%d", pm25);
}
- DISP()->drawStr(55, 48, strBuf);
- DISP()->setFont(u8g2_font_t0_12_tf);
+ } else {
+ sprintf(strBuf, "%s", "-");
+ }
+ DISP()->setFont(u8g2_font_t0_22b_tf);
+ DISP()->drawStr(55, 48, strBuf);
+
+ DISP()->setFont(u8g2_font_t0_12_tf);
+ if (config.isPmStandardInUSAQI()) {
DISP()->drawUTF8(55, 61, "AQI");
} else {
- if (utils::isValidPm(pm25)) {
- sprintf(strBuf, "%d", pm25);
- } else {
- sprintf(strBuf, "%s", "-");
- }
- DISP()->drawStr(55, 48, strBuf);
- DISP()->setFont(u8g2_font_t0_12_tf);
DISP()->drawUTF8(55, 61, "ug/m³");
}
@@ -355,18 +365,18 @@ void OledDisplay::showDashboard(const char *status) {
ag->display.clear();
/** Set CO2 */
- if(utils::isValidCO2(value.CO2)) {
+ if (utils::isValidCO2(value.CO2)) {
snprintf(strBuf, sizeof(strBuf), "CO2:%d", value.CO2);
} else {
snprintf(strBuf, sizeof(strBuf), "CO2:-");
}
-
+
ag->display.setCursor(0, 0);
ag->display.setText(strBuf);
/** Set PM */
int pm25 = value.pm25_1;
- if(config.hasSensorSHT) {
+ if (config.hasSensorSHT && config.isMonitorDisplayCompensatedValues()) {
pm25 = (int)ag->pms5003.compensate(pm25, value.Humidity);
}
ag->display.setCursor(0, 12);
diff --git a/src/AgOledDisplay.h b/src/AgOledDisplay.h
index 28a0cba..435ff4c 100644
--- a/src/AgOledDisplay.h
+++ b/src/AgOledDisplay.h
@@ -16,7 +16,7 @@ private:
Measurements &value;
bool isDisplayOff = false;
- void showTempHum(bool hasStatus);
+ void showTempHum(bool hasStatus, char* buf, int buf_size);
void setCentralText(int y, String text);
void setCentralText(int y, const char *text);
diff --git a/src/Main/utils.cpp b/src/Main/utils.cpp
index 42b06a5..33f8618 100644
--- a/src/Main/utils.cpp
+++ b/src/Main/utils.cpp
@@ -87,3 +87,8 @@ int utils::getInvalidPmValue(void) { return INVALID_PMS; }
int utils::getInvalidNOx(void) { return INVALID_NOX; }
int utils::getInvalidVOC(void) { return INVALID_VOC; }
+
+float utils::degreeC_To_F(float t) {
+ /** (t * 9)/5 + 32 */
+ return t * 1.8f + 32.0f;
+}
diff --git a/src/Main/utils.h b/src/Main/utils.h
index b51ac98..6b8452b 100644
--- a/src/Main/utils.h
+++ b/src/Main/utils.h
@@ -24,6 +24,7 @@ public:
static int getInvalidPmValue(void);
static int getInvalidNOx(void);
static int getInvalidVOC(void);
+ static float degreeC_To_F(float t);
};