Compare commits

...

43 Commits
3.1.5 ... 3.1.7

Author SHA1 Message Date
28096e9faf Update version to 3.1.7 2024-09-02 19:55:16 +07:00
682378a47c Merge pull request #231 from airgradienthq/develop
Add WiFi feature
2024-09-02 19:53:33 +07:00
a1861be7b7 Merge pull request #230 from airgradienthq/feature/wifi-connect-to-default
Add default WiFi connect
2024-09-02 19:50:47 +07:00
99ddd24432 Merge branch 'develop' into feature/wifi-connect-to-default 2024-09-02 19:44:53 +07:00
29491e4cbe Merge pull request #229 from airgradienthq/develop
Merge to Master to Release 3.1.6
2024-09-02 12:19:46 +07:00
87cc3fc45f Update library.properties to v 3.1.6 2024-09-02 12:18:04 +07:00
7471d8079a Update AirGradient.h to v 3.1.6 2024-09-02 12:17:08 +07:00
8b0fe967f1 Merge pull request #223 from airgradienthq/hotfix/print-log-wrong-format
Fix print log message number format
2024-09-02 12:11:43 +07:00
6f1cef4e67 Merge pull request #224 from airgradienthq/hotfix/pms25-compensated-show-on-display
[Fix] PM2.5 compensated show on display
2024-09-02 12:09:51 +07:00
02b63ff816 Merge pull request #226 from airgradienthq/fix/pm2.5-compensated-formula
Fix pm2.5 compensation formula
2024-09-02 12:06:39 +07:00
228bf83e92 Merge pull request #228 from airgradienthq/feature/support-led-test-on-openair
`OpenAir` handle `ledBarTestRequested`
2024-09-02 12:05:20 +07:00
d3534cda52 handle ledBarTestRequested on OpenAir 2024-09-01 20:19:18 +07:00
aafaa42a68 Update formula link 2024-09-01 19:56:11 +07:00
2e9ff0d7dd add link to formula document 2024-08-30 19:21:54 +07:00
244b7814a6 add link to formula documents 2024-08-30 19:20:08 +07:00
28d27ee8fd Rename temperatureCompensated to compensateTemp and humidityCompensated to compensateHum 2024-08-30 19:17:58 +07:00
753f22923c rename isValidPMS to isValidPm 2024-08-30 19:07:31 +07:00
c45901706f Merge branch 'develop' into hotfix/pms25-compensated-show-on-display 2024-08-30 19:02:50 +07:00
663836e277 Merge pull request #205 from airgradienthq/feature/send-pms-sensor-fw-version-to-ag-cloud
Send PMS5003T firmware version to Ag Cloud
2024-08-30 10:54:36 +07:00
d39e10908d Merge branch 'develop' into hotfix/print-log-wrong-format 2024-08-28 09:57:45 +07:00
c52962d628 Update float constant 2024-08-26 20:47:48 +07:00
6b65efd3d6 fix pm2.5 compensated formula, #225 2024-08-26 20:43:48 +07:00
8bb87a75ef Merge pull request #222 from airgradienthq/hotfix/pms-fail-count-restart
Hotfix/pms fail count restart
2024-08-26 20:17:20 +07:00
1afcca25a1 Fix compile failed. 2024-08-26 15:54:41 +07:00
17238cff86 fix compile failed. 2024-08-26 15:52:31 +07:00
03e2afbf54 WiFi Connect to default airgradient if WiFi connected is empty 2024-08-26 15:47:49 +07:00
104d58a8c0 resolve review #222 2024-08-26 14:14:42 +07:00
7a988ea6c1 rename compensated to compensate 2024-08-26 11:56:01 +07:00
54ed83cb89 Revert las misstake commit changed. 2024-08-25 20:56:30 +07:00
e461b92c9f Fix build failed 2024-08-25 20:51:07 +07:00
db21648e91 Merge branch 'develop' into feature/send-pms-sensor-fw-version-to-ag-cloud 2024-08-25 20:46:28 +07:00
a9654506f5 Update log format, #218 2024-08-25 20:40:45 +07:00
63f653d5cd fix PM2.5 compensated on display, #221 2024-08-25 20:37:38 +07:00
b049a23657 Restart device after PMS sensor read failed 10 times 2024-08-25 20:21:26 +07:00
d6766ef68b Correct print log number format, fix #218 2024-08-25 08:37:25 +07:00
6c3259b94b Merge branch 'master' into develop 2024-08-23 09:16:10 +07:00
2df78e9066 Merge branch 'master' into develop 2024-08-23 08:59:49 +07:00
81b13134d2 update PM2.5 firmware prefix to PMS5003x 2024-08-16 06:42:43 +07:00
6d01366887 change pmsFirmare to firmware 2024-08-15 08:04:30 +07:00
040bd28038 Add report PMS5003 and PMS5003T firmware version 2024-08-07 08:50:43 +07:00
01943f594d Send PMS5003T firmware version to cloud 2024-07-29 13:20:07 +07:00
01a69668cc Merge branch 'develop' into feature/send-pms-sensor-fw-version-to-ag-cloud 2024-07-29 12:56:45 +07:00
812c2ab803 add PMS5003T get module firmware version code 2024-07-20 08:53:19 +07:00
27 changed files with 548 additions and 217 deletions

View File

@ -68,7 +68,6 @@ static LocalServer localServer(Serial, openMetrics, measurements, configuration,
wifiConnector);
static MqttClient mqttClient(Serial);
static int pmFailCount = 0;
static int getCO2FailCount = 0;
static AgFirmwareMode fwMode = FW_MODE_I_BASIC_40PS;
@ -514,15 +513,20 @@ static void updatePm(void) {
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
pmFailCount = 0;
ag.pms5003.resetFailCount();
} else {
pmFailCount++;
Serial.printf("PMS read failed: %d\r\n", pmFailCount);
if (pmFailCount >= 3) {
measurements.pm01_1 = utils::getInvalidPMS();
measurements.pm25_1 = utils::getInvalidPMS();
measurements.pm10_1 = utils::getInvalidPMS();
measurements.pm03PCount_1 = utils::getInvalidPMS();
ag.pms5003.updateFailCount();
Serial.printf("PMS read failed %d times\r\n", ag.pms5003.getFailCount());
if (ag.pms5003.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
measurements.pm01_1 = utils::getInvalidPmValue();
measurements.pm25_1 = utils::getInvalidPmValue();
measurements.pm10_1 = utils::getInvalidPmValue();
measurements.pm03PCount_1 = utils::getInvalidPmValue();
}
if(ag.pms5003.getFailCount() >= ag.pms5003.getFailCountMax()) {
Serial.printf("PMS failure count reach to max set %d, restarting...", ag.pms5003.getFailCountMax());
ESP.restart();
}
}
}

View File

@ -67,10 +67,10 @@ String OpenMetrics::getPayload(void) {
float _temp = utils::getInvalidTemperature();
float _hum = utils::getInvalidHumidity();
int pm01 = utils::getInvalidPMS();
int pm25 = utils::getInvalidPMS();
int pm10 = utils::getInvalidPMS();
int pm03PCount = utils::getInvalidPMS();
int pm01 = utils::getInvalidPmValue();
int pm25 = utils::getInvalidPmValue();
int pm10 = utils::getInvalidPmValue();
int pm03PCount = utils::getInvalidPmValue();
int atmpCompensated = utils::getInvalidTemperature();
int ahumCompensated = utils::getInvalidHumidity();
@ -89,28 +89,28 @@ String OpenMetrics::getPayload(void) {
}
if (config.hasSensorPMS1) {
if (utils::isValidPMS(pm01)) {
if (utils::isValidPm(pm01)) {
add_metric("pm1",
"PM1.0 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm01));
}
if (utils::isValidPMS(pm25)) {
if (utils::isValidPm(pm25)) {
add_metric("pm2d5",
"PM2.5 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm25));
}
if (utils::isValidPMS(pm10)) {
if (utils::isValidPm(pm10)) {
add_metric("pm10",
"PM10 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm10));
}
if (utils::isValidPMS03Count(pm03PCount)) {
if (utils::isValidPm03Count(pm03PCount)) {
add_metric("pm0d3",
"PM0.3 concentration as measured by the AirGradient PMS "
"sensor, in number of particules per 100 milliliters",

View File

@ -68,7 +68,6 @@ static LocalServer localServer(Serial, openMetrics, measurements, configuration,
wifiConnector);
static MqttClient mqttClient(Serial);
static int pmFailCount = 0;
static int getCO2FailCount = 0;
static AgFirmwareMode fwMode = FW_MODE_I_33PS;
@ -566,15 +565,20 @@ static void updatePm(void) {
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
pmFailCount = 0;
ag.pms5003.resetFailCount();
} else {
pmFailCount++;
Serial.printf("PMS read failed: %d\r\n", pmFailCount);
if (pmFailCount >= 3) {
measurements.pm01_1 = utils::getInvalidPMS();
measurements.pm25_1 = utils::getInvalidPMS();
measurements.pm10_1 = utils::getInvalidPMS();
measurements.pm03PCount_1 = utils::getInvalidPMS();
ag.pms5003.updateFailCount();
Serial.printf("PMS read failed %d times\r\n", ag.pms5003.getFailCount());
if (ag.pms5003.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
measurements.pm01_1 = utils::getInvalidPmValue();
measurements.pm25_1 = utils::getInvalidPmValue();
measurements.pm10_1 = utils::getInvalidPmValue();
measurements.pm03PCount_1 = utils::getInvalidPmValue();
}
if(ag.pms5003.getFailCount() >= ag.pms5003.getFailCountMax()) {
Serial.printf("PMS failure count reach to max set %d, restarting...", ag.pms5003.getFailCountMax());
ESP.restart();
}
}
}

View File

@ -67,10 +67,10 @@ String OpenMetrics::getPayload(void) {
float _temp = utils::getInvalidTemperature();
float _hum = utils::getInvalidHumidity();
int pm01 = utils::getInvalidPMS();
int pm25 = utils::getInvalidPMS();
int pm10 = utils::getInvalidPMS();
int pm03PCount = utils::getInvalidPMS();
int pm01 = utils::getInvalidPmValue();
int pm25 = utils::getInvalidPmValue();
int pm10 = utils::getInvalidPmValue();
int pm03PCount = utils::getInvalidPmValue();
int atmpCompensated = utils::getInvalidTemperature();
int ahumCompensated = utils::getInvalidHumidity();
@ -89,28 +89,28 @@ String OpenMetrics::getPayload(void) {
}
if (config.hasSensorPMS1) {
if (utils::isValidPMS(pm01)) {
if (utils::isValidPm(pm01)) {
add_metric("pm1",
"PM1.0 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm01));
}
if (utils::isValidPMS(pm25)) {
if (utils::isValidPm(pm25)) {
add_metric("pm2d5",
"PM2.5 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm25));
}
if (utils::isValidPMS(pm10)) {
if (utils::isValidPm(pm10)) {
add_metric("pm10",
"PM10 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm10));
}
if (utils::isValidPMS03Count(pm03PCount)) {
if (utils::isValidPm03Count(pm03PCount)) {
add_metric("pm0d3",
"PM0.3 concentration as measured by the AirGradient PMS "
"sensor, in number of particules per 100 milliliters",

View File

@ -68,7 +68,6 @@ static LocalServer localServer(Serial, openMetrics, measurements, configuration,
wifiConnector);
static MqttClient mqttClient(Serial);
static int pmFailCount = 0;
static uint32_t factoryBtnPressTime = 0;
static int getCO2FailCount = 0;
static AgFirmwareMode fwMode = FW_MODE_I_42PS;
@ -328,9 +327,7 @@ static void factoryConfigReset(void) {
// }
/** Reset WIFI */
// WiFi.enableSTA(true); // Incase offline mode
// WiFi.disconnect(true, true);
wifiConnector.reset();
WiFi.disconnect(true, true);
/** Reset local config */
configuration.reset();
@ -609,15 +606,20 @@ static void updatePm(void) {
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
pmFailCount = 0;
ag.pms5003.resetFailCount();
} else {
pmFailCount++;
Serial.printf("PMS read failed: %d\r\n", pmFailCount);
if (pmFailCount >= 3) {
measurements.pm01_1 = utils::getInvalidPMS();
measurements.pm25_1 = utils::getInvalidPMS();
measurements.pm10_1 = utils::getInvalidPMS();
measurements.pm03PCount_1 = utils::getInvalidPMS();
ag.pms5003.updateFailCount();
Serial.printf("PMS read failed %d times\r\n", ag.pms5003.getFailCount());
if (ag.pms5003.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
measurements.pm01_1 = utils::getInvalidPmValue();
measurements.pm25_1 = utils::getInvalidPmValue();
measurements.pm10_1 = utils::getInvalidPmValue();
measurements.pm03PCount_1 = utils::getInvalidPmValue();
}
if(ag.pms5003.getFailCount() >= ag.pms5003.getFailCountMax()) {
Serial.printf("PMS failure count reach to max set %d, restarting...", ag.pms5003.getFailCountMax());
ESP.restart();
}
}
}

View File

@ -67,10 +67,10 @@ String OpenMetrics::getPayload(void) {
float _temp = utils::getInvalidTemperature();
float _hum = utils::getInvalidHumidity();
int pm01 = utils::getInvalidPMS();
int pm25 = utils::getInvalidPMS();
int pm10 = utils::getInvalidPMS();
int pm03PCount = utils::getInvalidPMS();
int pm01 = utils::getInvalidPmValue();
int pm25 = utils::getInvalidPmValue();
int pm10 = utils::getInvalidPmValue();
int pm03PCount = utils::getInvalidPmValue();
int atmpCompensated = utils::getInvalidTemperature();
int ahumCompensated = utils::getInvalidHumidity();
@ -89,28 +89,28 @@ String OpenMetrics::getPayload(void) {
}
if (config.hasSensorPMS1) {
if (utils::isValidPMS(pm01)) {
if (utils::isValidPm(pm01)) {
add_metric("pm1",
"PM1.0 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm01));
}
if (utils::isValidPMS(pm25)) {
if (utils::isValidPm(pm25)) {
add_metric("pm2d5",
"PM2.5 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm25));
}
if (utils::isValidPMS(pm10)) {
if (utils::isValidPm(pm10)) {
add_metric("pm10",
"PM10 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm10));
}
if (utils::isValidPMS03Count(pm03PCount)) {
if (utils::isValidPm03Count(pm03PCount)) {
add_metric("pm0d3",
"PM0.3 concentration as measured by the AirGradient PMS "
"sensor, in number of particules per 100 milliliters",

View File

@ -88,7 +88,6 @@ static OtaHandler otaHandler;
static LocalServer localServer(Serial, openMetrics, measurements, configuration,
wifiConnector);
static int pmFailCount = 0;
static uint32_t factoryBtnPressTime = 0;
static int getCO2FailCount = 0;
static AgFirmwareMode fwMode = FW_MODE_I_9PSL;
@ -424,8 +423,7 @@ static void factoryConfigReset(void) {
}
/** Reset WIFI */
Serial.println("Set wifi connect to 'airgradient' as default");
WiFi.begin("airgradient", "cleanair");
WiFi.disconnect(true, true);
/** Reset local config */
configuration.reset();
@ -940,6 +938,9 @@ static void configUpdateHandle() {
stateMachine.executeLedBarTest();
}
else if(ag->isOpenAir()) {
stateMachine.executeLedBarTest();
}
appDispHandler();
appLedHandler();
@ -1006,6 +1007,7 @@ static void updateTvoc(void) {
}
static void updatePm(void) {
bool restart = false;
if (ag->isOne()) {
if (ag->pms5003.isFailed() == false) {
measurements.pm01_1 = ag->pms5003.getPm01Ae();
@ -1018,15 +1020,19 @@ static void updatePm(void) {
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
pmFailCount = 0;
ag->pms5003.resetFailCount();
} else {
pmFailCount++;
Serial.printf("PMS read failed: %d\r\n", pmFailCount);
if (pmFailCount >= 3) {
measurements.pm01_1 = utils::getInvalidPMS();
measurements.pm25_1 = utils::getInvalidPMS();
measurements.pm10_1 = utils::getInvalidPMS();
measurements.pm03PCount_1 = utils::getInvalidPMS();
ag->pms5003.updateFailCount();
Serial.printf("PMS read faile %d times\r\n", ag->pms5003.getFailCount());
if (ag->pms5003.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
measurements.pm01_1 = utils::getInvalidPmValue();
measurements.pm25_1 = utils::getInvalidPmValue();
measurements.pm10_1 = utils::getInvalidPmValue();
measurements.pm03PCount_1 = utils::getInvalidPmValue();
}
if (ag->pms5003.getFailCount() >= ag->pms5003.getFailCountMax()) {
restart = true;
}
}
} else {
@ -1050,16 +1056,29 @@ static void updatePm(void) {
Serial.printf("[1] Temperature in C: %0.2f\r\n", measurements.temp_1);
Serial.printf("[1] Relative Humidity: %d\r\n", measurements.hum_1);
Serial.printf("[1] Temperature compensated in C: %0.2f\r\n",
ag->pms5003t_1.temperatureCompensated(measurements.temp_1));
Serial.printf("[1] Relative Humidity compensated: %f\r\n",
ag->pms5003t_1.humidityCompensated(measurements.hum_1));
ag->pms5003t_1.compensateTemp(measurements.temp_1));
Serial.printf("[1] Relative Humidity compensated: %0.2f\r\n",
ag->pms5003t_1.compensateHum(measurements.hum_1));
ag->pms5003t_1.resetFailCount();
} else {
measurements.pm01_1 = utils::getInvalidPMS();
measurements.pm25_1 = utils::getInvalidPMS();
measurements.pm10_1 = utils::getInvalidPMS();
measurements.pm03PCount_1 = utils::getInvalidPMS();
measurements.temp_1 = utils::getInvalidTemperature();
measurements.hum_1 = utils::getInvalidHumidity();
if (configuration.hasSensorPMS1) {
ag->pms5003t_1.updateFailCount();
Serial.printf("[1] PMS read failed %d times\r\n", ag->pms5003t_1.getFailCount());
if (ag->pms5003t_1.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
measurements.pm01_1 = utils::getInvalidPmValue();
measurements.pm25_1 = utils::getInvalidPmValue();
measurements.pm10_1 = utils::getInvalidPmValue();
measurements.pm03PCount_1 = utils::getInvalidPmValue();
measurements.temp_1 = utils::getInvalidTemperature();
measurements.hum_1 = utils::getInvalidHumidity();
}
if (ag->pms5003t_1.getFailCount() >= ag->pms5003t_1.getFailCountMax()) {
restart = true;
}
}
}
if (configuration.hasSensorPMS2 && (ag->pms5003t_2.isFailed() == false)) {
@ -1080,16 +1099,29 @@ static void updatePm(void) {
Serial.printf("[2] Temperature in C: %0.2f\r\n", measurements.temp_2);
Serial.printf("[2] Relative Humidity: %d\r\n", measurements.hum_2);
Serial.printf("[2] Temperature compensated in C: %0.2f\r\n",
ag->pms5003t_1.temperatureCompensated(measurements.temp_2));
Serial.printf("[2] Relative Humidity compensated: %d\r\n",
ag->pms5003t_1.humidityCompensated(measurements.hum_2));
ag->pms5003t_1.compensateTemp(measurements.temp_2));
Serial.printf("[2] Relative Humidity compensated: %0.2f\r\n",
ag->pms5003t_1.compensateHum(measurements.hum_2));
ag->pms5003t_2.resetFailCount();
} else {
measurements.pm01_2 = utils::getInvalidPMS();
measurements.pm25_2 = utils::getInvalidPMS();
measurements.pm10_2 = utils::getInvalidPMS();
measurements.pm03PCount_2 = utils::getInvalidPMS();
measurements.temp_2 = utils::getInvalidTemperature();
measurements.hum_2 = utils::getInvalidHumidity();
if (configuration.hasSensorPMS2) {
ag->pms5003t_2.updateFailCount();
Serial.printf("[2] PMS read failed %d times\r\n", ag->pms5003t_2.getFailCount());
if (ag->pms5003t_2.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
measurements.pm01_2 = utils::getInvalidPmValue();
measurements.pm25_2 = utils::getInvalidPmValue();
measurements.pm10_2 = utils::getInvalidPmValue();
measurements.pm03PCount_2 = utils::getInvalidPmValue();
measurements.temp_2 = utils::getInvalidTemperature();
measurements.hum_2 = utils::getInvalidHumidity();
}
if (ag->pms5003t_2.getFailCount() >= ag->pms5003t_2.getFailCountMax()) {
restart = true;
}
}
}
if (configuration.hasSensorPMS1 && configuration.hasSensorPMS2 &&
@ -1189,6 +1221,11 @@ static void updatePm(void) {
ag->sgp41.setCompensationTemperatureHumidity(temp, hum);
}
}
if (restart) {
Serial.printf("PMS failure count reach to max set %d, restarting...", ag->pms5003.getFailCountMax());
ESP.restart();
}
}
static void sendDataToServer(void) {

View File

@ -67,10 +67,10 @@ String OpenMetrics::getPayload(void) {
float _temp = utils::getInvalidTemperature();
float _hum = utils::getInvalidHumidity();
int pm01 = utils::getInvalidPMS();
int pm25 = utils::getInvalidPMS();
int pm10 = utils::getInvalidPMS();
int pm03PCount = utils::getInvalidPMS();
int pm01 = utils::getInvalidPmValue();
int pm25 = utils::getInvalidPmValue();
int pm10 = utils::getInvalidPmValue();
int pm03PCount = utils::getInvalidPmValue();
int atmpCompensated = utils::getInvalidTemperature();
int ahumCompensated = utils::getInvalidHumidity();
if (config.hasSensorPMS1 && config.hasSensorPMS2) {
@ -118,33 +118,33 @@ String OpenMetrics::getPayload(void) {
atmpCompensated = _temp;
ahumCompensated = _hum;
} else {
atmpCompensated = ag->pms5003t_1.temperatureCompensated(_temp);
ahumCompensated = ag->pms5003t_1.humidityCompensated(_hum);
atmpCompensated = ag->pms5003t_1.compensateTemp(_temp);
ahumCompensated = ag->pms5003t_1.compensateHum(_hum);
}
if (config.hasSensorPMS1 || config.hasSensorPMS2) {
if (utils::isValidPMS(pm01)) {
if (utils::isValidPm(pm01)) {
add_metric("pm1",
"PM1.0 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm01));
}
if (utils::isValidPMS(pm25)) {
if (utils::isValidPm(pm25)) {
add_metric("pm2d5",
"PM2.5 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm25));
}
if (utils::isValidPMS(pm10)) {
if (utils::isValidPm(pm10)) {
add_metric("pm10",
"PM10 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm10));
}
if (utils::isValidPMS03Count(pm03PCount)) {
if (utils::isValidPm03Count(pm03PCount)) {
add_metric("pm0d3",
"PM0.3 concentration as measured by the AirGradient PMS "
"sensor, in number of particules per 100 milliliters",

View File

@ -1,5 +1,5 @@
name=AirGradient Air Quality Sensor
version=3.1.5
version=3.1.7
author=AirGradient <support@airgradient.com>
maintainer=AirGradient <support@airgradient.com>
sentence=ESP32-C3 / ESP8266 library for air quality monitor measuring PM, CO2, Temperature, TVOC and Humidity with OLED display.

View File

@ -306,12 +306,13 @@ void OledDisplay::showDashboard(const char *status) {
/** Draw PM2.5 value */
int pm25 = value.pm25_1;
if (config.hasSensorSHT) {
pm25 = ag->pms5003.compensated(pm25, value.Humidity);
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::isValidPMS(value.pm25_1)) {
sprintf(strBuf, "%d", ag->pms5003.convertPm25ToUsAqi(value.pm25_1));
if (utils::isValidPm(pm25)) {
sprintf(strBuf, "%d", ag->pms5003.convertPm25ToUsAqi(pm25));
} else {
sprintf(strBuf, "%s", "-");
}
@ -319,8 +320,8 @@ void OledDisplay::showDashboard(const char *status) {
DISP()->setFont(u8g2_font_t0_12_tf);
DISP()->drawUTF8(55, 61, "AQI");
} else {
if (utils::isValidPMS(value.pm25_1)) {
sprintf(strBuf, "%d", value.pm25_1);
if (utils::isValidPm(pm25)) {
sprintf(strBuf, "%d", pm25);
} else {
sprintf(strBuf, "%s", "-");
}
@ -366,11 +367,11 @@ void OledDisplay::showDashboard(const char *status) {
/** Set PM */
int pm25 = value.pm25_1;
if(config.hasSensorSHT) {
pm25 = (int)ag->pms5003.compensated(pm25, value.Humidity);
pm25 = (int)ag->pms5003.compensate(pm25, value.Humidity);
}
ag->display.setCursor(0, 12);
if (utils::isValidPMS(value.pm25_1)) {
snprintf(strBuf, sizeof(strBuf), "PM2.5:%d", value.pm25_1);
if (utils::isValidPm(pm25)) {
snprintf(strBuf, sizeof(strBuf), "PM2.5:%d", pm25);
} else {
snprintf(strBuf, sizeof(strBuf), "PM2.5:-");
}

View File

@ -1,5 +1,6 @@
#include "AgStateMachine.h"
#define LED_TEST_BLINK_DELAY 50 /** ms */
#define LED_FAST_BLINK_DELAY 250 /** ms */
#define LED_SLOW_BLINK_DELAY 1000 /** ms */
#define LED_SHORT_BLINK_DELAY 500 /** ms */
@ -305,18 +306,23 @@ void StateMachine::co2Calibration(void) {
void StateMachine::ledBarTest(void) {
if (config.isLedBarTestRequested()) {
if (config.getCountry() == "TH") {
uint32_t tstart = millis();
logInfo("Start run LED test for 2 min");
while (1) {
ledBarRunTest();
uint32_t ms = (uint32_t)(millis() - tstart);
if (ms >= (60 * 1000 * 2)) {
logInfo("LED test after 2 min finish");
break;
if (ag->isOne()) {
if (config.getCountry() == "TH") {
uint32_t tstart = millis();
logInfo("Start run LED test for 2 min");
while (1) {
ledBarRunTest();
uint32_t ms = (uint32_t)(millis() - tstart);
if (ms >= (60 * 1000 * 2)) {
logInfo("LED test after 2 min finish");
break;
}
}
} else {
ledBarRunTest();
}
} else {
}
else if(ag->isOpenAir()) {
ledBarRunTest();
}
}
@ -325,22 +331,31 @@ void StateMachine::ledBarTest(void) {
void StateMachine::ledBarPowerUpTest(void) { ledBarRunTest(); }
void StateMachine::ledBarRunTest(void) {
disp.setText("LED Test", "running", ".....");
runLedTest('r');
ag->ledBar.show();
delay(1000);
runLedTest('g');
ag->ledBar.show();
delay(1000);
runLedTest('b');
ag->ledBar.show();
delay(1000);
runLedTest('w');
ag->ledBar.show();
delay(1000);
runLedTest('n');
ag->ledBar.show();
delay(1000);
if (ag->isOne()) {
disp.setText("LED Test", "running", ".....");
runLedTest('r');
ag->ledBar.show();
delay(1000);
runLedTest('g');
ag->ledBar.show();
delay(1000);
runLedTest('b');
ag->ledBar.show();
delay(1000);
runLedTest('w');
ag->ledBar.show();
delay(1000);
runLedTest('n');
ag->ledBar.show();
delay(1000);
} else if (ag->isOpenAir()) {
for (int i = 0; i < 100; i++) {
ag->statusLed.setOn();
delay(LED_TEST_BLINK_DELAY);
ag->statusLed.setOff();
delay(LED_TEST_BLINK_DELAY);
}
}
}
void StateMachine::runLedTest(char color) {

View File

@ -4,6 +4,39 @@
#include "Main/utils.h"
#include "Libraries/Arduino_JSON/src/Arduino_JSON.h"
#define json_prop_pmFirmware "firmware"
/**
* @brief Get PMS5003 firmware version string
*
* @param fwCode
* @return String
*/
String Measurements::pms5003FirmwareVersion(int fwCode) {
return pms5003FirmwareVersionBase("PMS5003x", fwCode);
}
/**
* @brief Get PMS5003T firmware version string
*
* @param fwCode
* @return String
*/
String Measurements::pms5003TFirmwareVersion(int fwCode) {
return pms5003FirmwareVersionBase("PMS5003x", fwCode);
}
/**
* @brief Get firmware version string
*
* @param prefix Prefix firmware string
* @param fwCode Version code
* @return string
*/
String Measurements::pms5003FirmwareVersionBase(String prefix, int fwCode) {
return prefix + String("-") + String(fwCode);
}
String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
void *_ag, void *_config) {
AirGradient *ag = (AirGradient *)_ag;
@ -21,18 +54,23 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_3() || ag->isBasic()) {
if (config->hasSensorPMS1) {
if (utils::isValidPMS(this->pm01_1)) {
if (utils::isValidPm(this->pm01_1)) {
root["pm01"] = this->pm01_1;
}
if (utils::isValidPMS(this->pm25_1)) {
if (utils::isValidPm(this->pm25_1)) {
root["pm02"] = this->pm25_1;
}
if (utils::isValidPMS(this->pm10_1)) {
if (utils::isValidPm(this->pm10_1)) {
root["pm10"] = this->pm10_1;
}
if (utils::isValidPMS03Count(this->pm03PCount_1)) {
if (utils::isValidPm03Count(this->pm03PCount_1)) {
root["pm003Count"] = this->pm03PCount_1;
}
if (!localServer) {
root[json_prop_pmFirmware] =
this->pms5003FirmwareVersion(ag->pms5003.getFirmwareVersion());
}
}
if (config->hasSensorSHT) {
@ -51,7 +89,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
}
if (config->hasSensorSHT && config->hasSensorPMS1) {
int pm25 = ag->pms5003.compensated(this->pm25_1, this->Humidity);
int pm25 = ag->pms5003.compensate(this->pm25_1, this->Humidity);
if (pm25 >= 0) {
root["pm02Compensated"] = pm25;
}
@ -59,16 +97,16 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
} else {
if (config->hasSensorPMS1 && config->hasSensorPMS2) {
if (utils::isValidPMS(this->pm01_1) && utils::isValidPMS(this->pm01_2)) {
if (utils::isValidPm(this->pm01_1) && utils::isValidPm(this->pm01_2)) {
root["pm01"] = ag->round2((this->pm01_1 + this->pm01_2) / 2.0f);
}
if (utils::isValidPMS(this->pm25_1) && utils::isValidPMS(this->pm25_2)) {
if (utils::isValidPm(this->pm25_1) && utils::isValidPm(this->pm25_2)) {
root["pm02"] = ag->round2((this->pm25_1 + this->pm25_2) / 2.0f);
}
if (utils::isValidPMS(this->pm10_1) && utils::isValidPMS(this->pm10_2)) {
if (utils::isValidPm(this->pm10_1) && utils::isValidPm(this->pm10_2)) {
root["pm10"] = ag->round2((this->pm10_1 + this->pm10_2) / 2.0f);
}
if (utils::isValidPMS(this->pm03PCount_1) && utils::isValidPMS(this->pm03PCount_2)) {
if (utils::isValidPm(this->pm03PCount_1) && utils::isValidPm(this->pm03PCount_2)) {
root["pm003Count"] = ag->round2((this->pm03PCount_1 + this->pm03PCount_2) / 2.0f);
}
@ -76,7 +114,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
if (utils::isValidTemperature(this->temp_1) && utils::isValidTemperature(this->temp_1)) {
root["atmp"] = ag->round2((this->temp_1 + this->temp_2) / 2.0f);
if (localServer) {
val = ag->pms5003t_2.temperatureCompensated((this->temp_1 + this->temp_2) / 2.0f);
val = ag->pms5003t_2.compensateTemp((this->temp_1 + this->temp_2) / 2.0f);
if (utils::isValidTemperature(val)) {
root["atmpCompensated"] = ag->round2(val);
}
@ -85,15 +123,15 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
if (utils::isValidHumidity(this->hum_1) && utils::isValidHumidity(this->hum_1)) {
root["rhum"] = ag->round2((this->hum_1 + this->hum_2) / 2.0f);
if (localServer) {
val = ag->pms5003t_2.humidityCompensated((this->hum_1 + this->hum_2) / 2.0f);
val = ag->pms5003t_2.compensateHum((this->hum_1 + this->hum_2) / 2.0f);
if (utils::isValidHumidity(val)) {
root["rhumCompensated"] = (int)val;
}
}
}
int pm25 = (ag->pms5003t_1.compensated(this->pm25_1, this->temp_1) +
ag->pms5003t_2.compensated(this->pm25_2, this->temp_2)) /
int pm25 = (ag->pms5003t_1.compensate(this->pm25_1, this->temp_1) +
ag->pms5003t_2.compensate(this->pm25_2, this->temp_2)) /
2;
root["pm02Compensated"] = pm25;
}
@ -101,23 +139,23 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
if (fwMode == FW_MODE_O_1PS || fwMode == FW_MODE_O_1PST) {
float val;
if (config->hasSensorPMS1) {
if (utils::isValidPMS(this->pm01_1)) {
if (utils::isValidPm(this->pm01_1)) {
root["pm01"] = this->pm01_1;
}
if (utils::isValidPMS(this->pm25_1)) {
if (utils::isValidPm(this->pm25_1)) {
root["pm02"] = this->pm25_1;
}
if (utils::isValidPMS(this->pm10_1)) {
if (utils::isValidPm(this->pm10_1)) {
root["pm10"] = this->pm10_1;
}
if (utils::isValidPMS03Count(this->pm03PCount_1)) {
if (utils::isValidPm03Count(this->pm03PCount_1)) {
root["pm003Count"] = this->pm03PCount_1;
}
if (utils::isValidTemperature(this->temp_1)) {
root["atmp"] = ag->round2(this->temp_1);
if (localServer) {
val = ag->pms5003t_1.temperatureCompensated(this->temp_1);
val = ag->pms5003t_1.compensateTemp(this->temp_1);
if (utils::isValidTemperature(val)) {
root["atmpCompensated"] = ag->round2(val);
}
@ -127,25 +165,29 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["rhum"] = this->hum_1;
if (localServer) {
val = ag->pms5003t_1.humidityCompensated(this->hum_1);
val = ag->pms5003t_1.compensateHum(this->hum_1);
if (utils::isValidHumidity(val)) {
root["rhumCompensated"] = (int)val;
}
}
}
root["pm02Compensated"] = ag->pms5003t_1.compensated(this->pm25_1, this->temp_1);
root["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->temp_1);
if (!localServer) {
root[json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_1.getFirmwareVersion());
}
}
if (config->hasSensorPMS2) {
if(utils::isValidPMS(this->pm01_2)) {
if(utils::isValidPm(this->pm01_2)) {
root["pm01"] = this->pm01_2;
}
if(utils::isValidPMS(this->pm25_2)) {
if(utils::isValidPm(this->pm25_2)) {
root["pm02"] = this->pm25_2;
}
if(utils::isValidPMS(this->pm10_2)) {
if(utils::isValidPm(this->pm10_2)) {
root["pm10"] = this->pm10_2;
}
if(utils::isValidPMS03Count(this->pm03PCount_2)) {
if(utils::isValidPm03Count(this->pm03PCount_2)) {
root["pm003Count"] = this->pm03PCount_2;
}
@ -154,7 +196,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["atmp"] = ag->round2(this->temp_2);
if (localServer) {
val = ag->pms5003t_2.temperatureCompensated(this->temp_2);
val = ag->pms5003t_2.compensateTemp(this->temp_2);
if (utils::isValidTemperature(val)) {
root["atmpCompensated"] = ag->round2(val);
}
@ -164,35 +206,39 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["rhum"] = this->hum_2;
if (localServer) {
val = ag->pms5003t_2.humidityCompensated(this->hum_2);
val = ag->pms5003t_2.compensateHum(this->hum_2);
if (utils::isValidHumidity(val)) {
root["rhumCompensated"] = (int)val;
}
}
}
root["pm02Compensated"] = ag->pms5003t_2.compensated(this->pm25_2, this->temp_2);
root["pm02Compensated"] = ag->pms5003t_2.compensate(this->pm25_2, this->temp_2);
if(!localServer) {
root[json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_1.getFirmwareVersion());
}
}
} else {
if (fwMode == FW_MODE_O_1P) {
float val;
if (config->hasSensorPMS1) {
if (utils::isValidPMS(this->pm01_1)) {
if (utils::isValidPm(this->pm01_1)) {
root["pm01"] = this->pm01_1;
}
if (utils::isValidPMS(this->pm25_1)) {
if (utils::isValidPm(this->pm25_1)) {
root["pm02"] = this->pm25_1;
}
if (utils::isValidPMS(this->pm10_1)) {
if (utils::isValidPm(this->pm10_1)) {
root["pm10"] = this->pm10_1;
}
if (utils::isValidPMS03Count(this->pm03PCount_1)) {
if (utils::isValidPm03Count(this->pm03PCount_1)) {
root["pm003Count"] = this->pm03PCount_1;
}
if (utils::isValidTemperature(this->temp_1)) {
root["atmp"] = ag->round2(this->temp_1);
if (localServer) {
val = ag->pms5003t_1.temperatureCompensated(this->temp_1);
val = ag->pms5003t_1.compensateTemp(this->temp_1);
if (utils::isValidTemperature(val)) {
root["atmpCompensated"] = ag->round2(val);
}
@ -201,31 +247,35 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
if (utils::isValidHumidity(this->hum_1)) {
root["rhum"] = this->hum_1;
if(localServer) {
val = ag->pms5003t_1.humidityCompensated(this->hum_1);
val = ag->pms5003t_1.compensateHum(this->hum_1);
if(utils::isValidHumidity(val)) {
root["rhumCompensated"] = (int)val;
}
}
}
root["pm02Compensated"] = ag->pms5003t_1.compensated(this->pm25_1, this->temp_1);
root["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->temp_1);
if(!localServer) {
root[json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_1.getFirmwareVersion());
}
} else if (config->hasSensorPMS2) {
if(utils::isValidPMS(this->pm01_2)) {
if(utils::isValidPm(this->pm01_2)) {
root["pm01"] = this->pm01_2;
}
if(utils::isValidPMS(this->pm25_2)) {
if(utils::isValidPm(this->pm25_2)) {
root["pm02"] = this->pm25_2;
}
if(utils::isValidPMS(this->pm10_2)) {
if(utils::isValidPm(this->pm10_2)) {
root["pm10"] = this->pm10_2;
}
if(utils::isValidPMS03Count(this->pm03PCount_2)) {
if(utils::isValidPm03Count(this->pm03PCount_2)) {
root["pm003Count"] = this->pm03PCount_2;
}
if (utils::isValidTemperature(this->temp_2)) {
root["atmp"] = ag->round2(this->temp_2);
if (localServer) {
val = ag->pms5003t_1.temperatureCompensated(this->temp_2);
val = ag->pms5003t_1.compensateTemp(this->temp_2);
if (utils::isValidTemperature(val)) {
root["atmpCompensated"] = ag->round2(val);
}
@ -235,34 +285,38 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["rhum"] = this->hum_2;
if(localServer) {
val = ag->pms5003t_1.humidityCompensated(this->hum_2);
val = ag->pms5003t_1.compensateHum(this->hum_2);
if(utils::isValidHumidity(val)) {
root["rhumCompensated"] = (int)val;
}
}
}
root["pm02Compensated"] = ag->pms5003t_1.compensated(this->pm25_1, this->temp_1);
root["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->temp_1);
if(!localServer) {
root[json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_2.getFirmwareVersion());
}
}
} else {
float val;
if (config->hasSensorPMS1) {
if(utils::isValidPMS(this->pm01_1)) {
if(utils::isValidPm(this->pm01_1)) {
root["channels"]["1"]["pm01"] = this->pm01_1;
}
if(utils::isValidPMS(this->pm25_1)) {
if(utils::isValidPm(this->pm25_1)) {
root["channels"]["1"]["pm02"] = this->pm25_1;
}
if(utils::isValidPMS(this->pm10_1)) {
if(utils::isValidPm(this->pm10_1)) {
root["channels"]["1"]["pm10"] = this->pm10_1;
}
if (utils::isValidPMS03Count(this->pm03PCount_1)) {
if (utils::isValidPm03Count(this->pm03PCount_1)) {
root["channels"]["1"]["pm003Count"] = this->pm03PCount_1;
}
if(utils::isValidTemperature(this->temp_1)) {
root["channels"]["1"]["atmp"] = ag->round2(this->temp_1);
if (localServer) {
val = ag->pms5003t_1.temperatureCompensated(this->temp_1);
val = ag->pms5003t_1.compensateTemp(this->temp_1);
if (utils::isValidTemperature(val)) {
root["channels"]["1"]["atmpCompensated"] = ag->round2(val);
}
@ -272,33 +326,39 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["channels"]["1"]["rhum"] = this->hum_1;
if (localServer) {
val = ag->pms5003t_1.humidityCompensated(this->hum_1);
val = ag->pms5003t_1.compensateHum(this->hum_1);
if (utils::isValidHumidity(val)) {
root["channels"]["1"]["rhumCompensated"] = (int)val;
}
}
}
root["channels"]["1"]["pm02Compensated"] = ag->pms5003t_1.compensated(this->pm25_1, this->temp_1);
root["channels"]["1"]["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->temp_1);
// PMS5003T version
if(!localServer) {
root["channels"]["1"][json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_1.getFirmwareVersion());
}
}
if (config->hasSensorPMS2) {
float val;
if (utils::isValidPMS(this->pm01_2)) {
if (utils::isValidPm(this->pm01_2)) {
root["channels"]["2"]["pm01"] = this->pm01_2;
}
if (utils::isValidPMS(this->pm25_2)) {
if (utils::isValidPm(this->pm25_2)) {
root["channels"]["2"]["pm02"] = this->pm25_2;
}
if (utils::isValidPMS(this->pm10_2)) {
if (utils::isValidPm(this->pm10_2)) {
root["channels"]["2"]["pm10"] = this->pm10_2;
}
if (utils::isValidPMS03Count(this->pm03PCount_2)) {
if (utils::isValidPm03Count(this->pm03PCount_2)) {
root["channels"]["2"]["pm003Count"] = this->pm03PCount_2;
}
if (utils::isValidTemperature(this->temp_2)) {
root["channels"]["2"]["atmp"] = ag->round2(this->temp_2);
if (localServer) {
val = ag->pms5003t_1.temperatureCompensated(this->temp_2);
val = ag->pms5003t_1.compensateTemp(this->temp_2);
if (utils::isValidTemperature(val)) {
root["channels"]["2"]["atmpCompensated"] = ag->round2(val);
}
@ -308,13 +368,18 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
root["channels"]["2"]["rhum"] = this->hum_2;
if (localServer) {
val = ag->pms5003t_1.humidityCompensated(this->hum_2);
val = ag->pms5003t_1.compensateHum(this->hum_2);
if (utils::isValidHumidity(val)) {
root["channels"]["2"]["rhumCompensated"] = (int)val;
}
}
}
root["channels"]["2"]["pm02Compensated"] = ag->pms5003t_2.compensated(this->pm25_2, this->temp_2);
root["channels"]["2"]["pm02Compensated"] = ag->pms5003t_2.compensate(this->pm25_2, this->temp_2);
// PMS5003T version
if(!localServer) {
root["channels"]["2"][json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_2.getFirmwareVersion());
}
}
}
}

View File

@ -6,6 +6,9 @@
class Measurements {
private:
String pms5003FirmwareVersion(int fwCode);
String pms5003TFirmwareVersion(int fwCode);
String pms5003FirmwareVersionBase(String prefix, int fwCode);
public:
Measurements() {
pm25_1 = -1;

View File

@ -41,6 +41,28 @@ bool WifiConnector::connect(void) {
}
}
WiFi.begin();
String wifiSSID = WIFI()->getWiFiSSID(true);
if (wifiSSID.isEmpty()) {
logInfo("Connected WiFi is empty, connect to default wifi \"" +
String(this->defaultSsid) + String("\""));
/** Set wifi connect */
WiFi.begin(this->defaultSsid, this->defaultPassword);
/** Wait for wifi connect to AP */
int count = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
count++;
if (count >= 15) {
logError("Try connect to default wifi \"" + String(this->defaultSsid) +
String("\" failed"));
break;
}
}
}
WIFI()->setConfigPortalBlocking(false);
WIFI()->setConnectTimeout(15);
WIFI()->setTimeout(WIFI_CONNECT_COUNTDOWN_MAX);
@ -383,3 +405,11 @@ bool WifiConnector::hasConfigurated(void) {
* @return false
*/
bool WifiConnector::isConfigurePorttalTimeout(void) { return connectorTimeout; }
/**
* @brief Set wifi connect to default WiFi
*
*/
void WifiConnector::setDefault(void) {
WiFi.begin("airgradient", "cleanair");
}

View File

@ -46,6 +46,10 @@ public:
String localIpStr(void);
bool hasConfigurated(void);
bool isConfigurePorttalTimeout(void);
const char* defaultSsid = "airgradient";
const char* defaultPassword = "cleanair";
void setDefault(void);
};
#endif /** _AG_WIFI_CONNECTOR_H_ */

View File

@ -65,6 +65,10 @@ bool AirGradient::isOne(void) {
return boardType == BoardType::ONE_INDOOR;
}
bool AirGradient::isOpenAir(void) {
return boardType == BoardType::OPEN_AIR_OUTDOOR;
}
bool AirGradient::isPro4_2(void) {
return boardType == BoardType::DIY_PRO_INDOOR_V4_2;
}

View File

@ -15,7 +15,7 @@
#include "Main/utils.h"
#ifndef GIT_VERSION
#define GIT_VERSION "3.1.5-snap"
#define GIT_VERSION "3.1.7-snap"
#endif
/**
@ -135,6 +135,14 @@ public:
*/
bool isOne(void);
/**
* @brief Check that Airgradient object is OPEN_AIR
*
* @return true
* @return false
*/
bool isOpenAir(void);
/**
* @brief Check that Airgradient object is DIY_PRO 4.2 indoor
*

View File

@ -48,14 +48,14 @@ bool utils::isValidCO2(int16_t value) {
return false;
}
bool utils::isValidPMS(int value) {
bool utils::isValidPm(int value) {
if ((value >= VALID_PMS_MIN) && (value <= VALID_PMS_MAX)) {
return true;
}
return false;
}
bool utils::isValidPMS03Count(int value) {
bool utils::isValidPm03Count(int value) {
if (value >= VALID_PMS03COUNT_MIN) {
return true;
}
@ -82,7 +82,7 @@ float utils::getInvalidHumidity(void) { return INVALID_HUMIDITY; }
int utils::getInvalidCO2(void) { return INVALID_CO2; }
int utils::getInvalidPMS(void) { return INVALID_PMS; }
int utils::getInvalidPmValue(void) { return INVALID_PMS; }
int utils::getInvalidNOx(void) { return INVALID_NOX; }

View File

@ -14,14 +14,14 @@ public:
static bool isValidTemperature(float value);
static bool isValidHumidity(float value);
static bool isValidCO2(int16_t value);
static bool isValidPMS(int value);
static bool isValidPMS03Count(int value);
static bool isValidPm(int value);
static bool isValidPm03Count(int value);
static bool isValidNOx(int value);
static bool isValidVOC(int value);
static float getInvalidTemperature(void);
static float getInvalidHumidity(void);
static int getInvalidCO2(void);
static int getInvalidPMS(void);
static int getInvalidPmValue(void);
static int getInvalidNOx(void);
static int getInvalidVOC(void);
};

View File

@ -12,6 +12,7 @@ bool PMSBase::begin(Stream *stream) {
this->stream = stream;
failed = true;
failCount = 0;
lastRead = 0; // To read buffer on handle without wait after 1.5sec
this->stream->flush();
@ -147,6 +148,27 @@ void PMSBase::handle() {
*/
bool PMSBase::isFailed(void) { return failed; }
/**
* @brief Increate number of fail
*
*/
void PMSBase::updateFailCount(void) {
if (failCount < failCountMax) {
failCount++;
}
}
void PMSBase::resetFailCount(void) { failCount = 0; }
/**
* @brief Get number of fail
*
* @return int
*/
int PMSBase::getFailCount(void) { return failCount; }
int PMSBase::getFailCountMax(void) { return failCountMax; }
/**
* @brief Read PMS 0.1 ug/m3 with CF = 1 PM estimates
*
@ -245,6 +267,20 @@ int16_t PMSBase::getTemp(void) { return toI16(&package[24]); }
*/
uint16_t PMSBase::getHum(void) { return toU16(&package[26]); }
/**
* @brief Get firmware version code
*
* @return uint8_t
*/
uint8_t PMSBase::getFirmwareVersion(void) { return package[28]; }
/**
* @brief Ge PMS5003 error code
*
* @return uint8_t
*/
uint8_t PMSBase::getErrorCode(void) { return package[29]; }
/**
* @brief Convert PMS2.5 to US AQI unit
*
@ -273,29 +309,32 @@ int PMSBase::pm25ToAQI(int pm02) {
/**
* @brief Correction PM2.5
*
* Formula: https://www.airgradient.com/documentation/correction-algorithms/
*
* @param pm25 Raw PM2.5 value
* @param humidity Humidity value (%)
* @return int
*/
int PMSBase::compensated(int pm25, float humidity) {
int PMSBase::compensate(int pm25, float humidity) {
float value;
float fpm25 = pm25;
if (humidity < 0) {
humidity = 0;
}
if (humidity > 100) {
humidity = 100;
humidity = 100.0f;
}
if(pm25 < 30) {
value = (pm25 * 0.524f) - (humidity * 0.0862f) + 5.75f;
} else if(pm25 < 50) {
value = (0.786f * (pm25 / 20 - 3 / 2) + 0.524f * (1 - (pm25 / 20 - 3 / 2))) * pm25 - (0.0862f * humidity) + 5.75f;
} else if(pm25 < 210) {
value = (0.786f * pm25) - (0.0862f * humidity) + 5.75f;
} else if(pm25 < 260) {
value = (0.69f * (pm25/50 - 21/5) + 0.786f * (1 - (pm25/50 - 21/5))) * pm25 - (0.0862f * humidity * (1 - (pm25/50 - 21/5))) + (2.966f * (pm25/50 -21/5)) + (5.75f * (1 - (pm25/50 - 21/5))) + (8.84f * (1.e-4) * pm25* (pm25/50 - 21/5));
} else {
value = 2.966f + (0.69f * pm25) + (8.84f * (1.e-4) * pm25);
if(pm25 < 30) { /** pm2.5 < 30 */
value = (fpm25 * 0.524f) - (humidity * 0.0862f) + 5.75f;
} else if(pm25 < 50) { /** 30 <= pm2.5 < 50 */
value = (0.786f * (fpm25 * 0.05f - 1.5f) + 0.524f * (1.0f - (fpm25 * 0.05f - 1.5f))) * fpm25 - (0.0862f * humidity) + 5.75f;
} else if(pm25 < 210) { /** 50 <= pm2.5 < 210 */
value = (0.786f * fpm25) - (0.0862f * humidity) + 5.75f;
} else if(pm25 < 260) { /** 210 <= pm2.5 < 260 */
value = (0.69f * (fpm25 * 0.02f - 4.2f) + 0.786f * (1.0f - (fpm25 * 0.02f - 4.2f))) * fpm25 - (0.0862f * humidity * (1.0f - (fpm25 * 0.02f - 4.2f))) + (2.966f * (fpm25 * 0.02f - 4.2f)) + (5.75f * (1.0f - (fpm25 * 0.02f - 4.2f))) + (8.84f * (1.e-4) * fpm25 * fpm25 * (fpm25 * 0.02f - 4.2f));
} else { /** 260 <= pm2.5 */
value = 2.966f + (0.69f * fpm25) + (8.84f * (1.e-4) * fpm25 * fpm25);
}
if(value < 0) {

View File

@ -3,11 +3,17 @@
#include <Arduino.h>
#define PMS_FAIL_COUNT_SET_INVALID 3
class PMSBase {
public:
bool begin(Stream *stream);
void handle();
bool isFailed(void);
void updateFailCount(void);
void resetFailCount(void);
int getFailCount(void);
int getFailCountMax(void);
uint16_t getRaw0_1(void);
uint16_t getRaw2_5(void);
uint16_t getRaw10(void);
@ -26,9 +32,11 @@ public:
/** For PMS5003T*/
int16_t getTemp(void);
uint16_t getHum(void);
uint8_t getFirmwareVersion(void);
uint8_t getErrorCode(void);
int pm25ToAQI(int pm02);
int compensated(int pm25, float humidity);
int compensate(int pm25, float humidity);
private:
Stream *stream;
@ -36,6 +44,8 @@ private:
int packageIndex;
bool failed = false;
uint32_t lastRead;
const int failCountMax = 10;
int failCount = 0;
int16_t toI16(char *buf);
uint16_t toU16(char* buf);

View File

@ -78,7 +78,7 @@ bool PMS5003::begin(void) {
return false;
}
#endif
_ver = pms.getFirmwareVersion();
this->_isBegin = true;
return true;
}
@ -124,14 +124,30 @@ int PMS5003::convertPm25ToUsAqi(int pm25) { return pms.pm25ToAQI(pm25); }
/**
* @brief Correct PM2.5
*
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
*
* @param pm25 PM2.5 raw value
* @param humidity Humidity value
* @return float
* @return int
*/
int PMS5003::compensated(int pm25, float humidity) {
return pms.compensated(pm25, humidity);
int PMS5003::compensate(int pm25, float humidity) {
return pms.compensate(pm25, humidity);
}
/**
* @brief Get sensor firmware version
*
* @return int
*/
int PMS5003::getFirmwareVersion(void) { return _ver; }
/**
* @brief Get sensor error code
*
* @return uint8_t
*/
uint8_t PMS5003::getErrorCode(void) { return pms.getErrorCode(); }
/**
* @brief Check device initialized or not
*
@ -175,3 +191,25 @@ void PMS5003::handle(void) { pms.handle(); }
* @return false Communication timeout or sensor has removed
*/
bool PMS5003::isFailed(void) { return pms.isFailed(); }
void PMS5003::updateFailCount(void) {
pms.updateFailCount();
}
void PMS5003::resetFailCount(void) {
pms.resetFailCount();
}
/**
* @brief Get number of fail count
*
* @return int
*/
int PMS5003::getFailCount(void) { return pms.getFailCount(); }
/**
* @brief Get number of fail count max
*
* @return int
*/
int PMS5003::getFailCountMax(void) { return pms.getFailCountMax(); }

View File

@ -19,15 +19,22 @@ public:
void end(void);
void handle(void);
bool isFailed(void);
void updateFailCount(void);
void resetFailCount(void);
int getFailCount(void);
int getFailCountMax(void);
int getPm01Ae(void);
int getPm25Ae(void);
int getPm10Ae(void);
int getPm03ParticleCount(void);
int convertPm25ToUsAqi(int pm25);
int compensated(int pm25, float humidity);
int compensate(int pm25, float humidity);
int getFirmwareVersion(void);
uint8_t getErrorCode(void);
private:
bool _isBegin = false;
int _ver;
BoardType _boardDef;
PMSBase pms;
const BoardDef *bsp;

View File

@ -103,7 +103,7 @@ bool PMS5003T::begin(void) {
return false;
}
#endif
_ver = pms.getFirmwareVersion();
this->_isBegin = true;
return true;
}
@ -167,14 +167,30 @@ float PMS5003T::getRelativeHumidity(void) {
/**
* @brief Correct PM2.5
*
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
*
* @param pm25 PM2.5 raw value
* @param humidity Humidity value
* @return float
* @return int
*/
float PMS5003T::compensated(int pm25, float humidity) {
return pms.compensated(pm25, humidity);
int PMS5003T::compensate(int pm25, float humidity) {
return pms.compensate(pm25, humidity);
}
/**
* @brief Get module(s) firmware version
*
* @return int Version code
*/
int PMS5003T::getFirmwareVersion(void) { return _ver; }
/**
* @brief Get sensor error code
*
* @return uint8_t
*/
uint8_t PMS5003T::getErrorCode(void) { return pms.getErrorCode(); }
/**
* @brief Check device initialized or not
*
@ -216,3 +232,24 @@ void PMS5003T::handle(void) { pms.handle(); }
*/
bool PMS5003T::isFailed(void) { return pms.isFailed(); }
void PMS5003T::updateFailCount(void) {
pms.updateFailCount();
}
void PMS5003T::resetFailCount(void) {
pms.resetFailCount();
}
/**
* @brief Get fail count
*
* @return int
*/
int PMS5003T::getFailCount(void) { return pms.getFailCount(); }
/**
* @brief Get fail count max
*
* @return int
*/
int PMS5003T::getFailCountMax(void) { return pms.getFailCountMax(); }

View File

@ -22,6 +22,10 @@ public:
void handle(void);
bool isFailed(void);
void updateFailCount(void);
void resetFailCount(void);
int getFailCount(void);
int getFailCountMax(void);
int getPm01Ae(void);
int getPm25Ae(void);
int getPm10Ae(void);
@ -29,11 +33,14 @@ public:
int convertPm25ToUsAqi(int pm25);
float getTemperature(void);
float getRelativeHumidity(void);
float compensated(int pm25, float humidity);
int compensate(int pm25, float humidity);
int getFirmwareVersion(void);
uint8_t getErrorCode(void);
private:
bool _isBegin = false;
bool _isSleep = false;
int _ver; /** Firmware version code */
BoardType _boardDef;
const BoardDef *bsp;

View File

@ -4,14 +4,30 @@ PMS5003TBase::PMS5003TBase() {}
PMS5003TBase::~PMS5003TBase() {}
float PMS5003TBase::temperatureCompensated(float temp) {
/**
* @brief Compensate the temperature
*
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
*
* @param temp
* @return * float
*/
float PMS5003TBase::compensateTemp(float temp) {
if (temp < 10.0f) {
return temp * 1.327f - 6.738f;
}
return temp * 1.181f - 5.113f;
}
float PMS5003TBase::humidityCompensated(float hum) {
/**
* @brief Compensate the humidity
*
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
*
* @param temp
* @return * float
*/
float PMS5003TBase::compensateHum(float hum) {
hum = hum * 1.259f + 7.34f;
if (hum > 100.0f) {

View File

@ -8,8 +8,8 @@ private:
public:
PMS5003TBase();
~PMS5003TBase();
float temperatureCompensated(float temp);
float humidityCompensated(float hum);
float compensateTemp(float temp);
float compensateHum(float hum);
};
#endif