From ed02f66ca25d87185d187e5a7f94df83c6ebb942 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Thu, 16 May 2024 21:12:02 +0700 Subject: [PATCH 01/15] Correct OTA update process show message on display --- examples/OneOpenAir/OneOpenAir.ino | 20 ++++++++++++++++++++ examples/OneOpenAir/OtaHandler.h | 21 ++++++++++++++++----- src/AgOledDisplay.cpp | 27 ++++++++++++++++++++++++++- src/AgOledDisplay.h | 2 ++ 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index ed911d5..35bcaeb 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -519,6 +519,26 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { delay(2500); break; } + case OtaState::OTA_STATE_SKIP: { + if (ag->isOne()) { + oledDisplay.showNewFirmwareSkipped(); + } else { + Serial.println("Firmware update: Skipped"); + } + + delay(2500); + break; + } + case OtaState::OTA_STATE_UP_TO_DATE: { + if (ag->isOne()) { + oledDisplay.showNewFirmwareUpToDate(); + } else { + Serial.println("Firmware update: up to date"); + } + + delay(2500); + break; + } case OtaState::OTA_STATE_PROCESSING: { if (ag->isOne()) { oledDisplay.showNewFirmwareUpdating(String(processing)); diff --git a/examples/OneOpenAir/OtaHandler.h b/examples/OneOpenAir/OtaHandler.h index 3dc4242..33fa233 100644 --- a/examples/OneOpenAir/OtaHandler.h +++ b/examples/OneOpenAir/OtaHandler.h @@ -18,6 +18,8 @@ enum OtaUpdateOutcome { enum OtaState { OTA_STATE_BEGIN, OTA_STATE_FAIL, + OTA_STATE_SKIP, + OTA_STATE_UP_TO_DATE, OTA_STATE_PROCESSING, OTA_STATE_SUCCESS }; @@ -40,13 +42,22 @@ public: config.url = urlAsChar; OtaUpdateOutcome ret = attemptToPerformOta(&config); Serial.println(ret); - if (ret == OtaUpdateOutcome::UPDATE_PERFORMED) { - if (this->callback) { + if (this->callback) { + switch (ret) { + case OtaUpdateOutcome::UPDATE_PERFORMED: this->callback(OtaState::OTA_STATE_SUCCESS, ""); - } - } else { - if(this->callback) { + break; + case OtaUpdateOutcome::UDPATE_SKIPPED: + this->callback(OtaState::OTA_STATE_SKIP, ""); + break; + case OtaUpdateOutcome::ALREADY_UP_TO_DATE: + this->callback(OtaState::OTA_STATE_UP_TO_DATE, ""); + break; + case OtaUpdateOutcome::UPDATE_FAILED: this->callback(OtaState::OTA_STATE_FAIL, ""); + break; + default: + break; } } } diff --git a/src/AgOledDisplay.cpp b/src/AgOledDisplay.cpp index d5164e2..125c887 100644 --- a/src/AgOledDisplay.cpp +++ b/src/AgOledDisplay.cpp @@ -381,6 +381,31 @@ void OledDisplay::showNewFirmwareFailed(void) { DISP()->setFont(u8g2_font_t0_16_tf); setCentralText(20, "Firmware Update"); setCentralText(40, "Failed"); - setCentralText(60, String("Retry after 24h")); + } while (DISP()->nextPage()); +} + +void OledDisplay::showNewFirmwareSkipped(void) { + if (isDisplayOff) { + return; + } + + DISP()->firstPage(); + do { + DISP()->setFont(u8g2_font_t0_16_tf); + setCentralText(20, "Firmware Update"); + setCentralText(40, "skipped"); + } while (DISP()->nextPage()); +} + +void OledDisplay::showNewFirmwareUpToDate(void) { + if (isDisplayOff) { + return; + } + + DISP()->firstPage(); + do { + DISP()->setFont(u8g2_font_t0_16_tf); + setCentralText(20, "Firmware Update"); + setCentralText(40, "up to date"); } while (DISP()->nextPage()); } diff --git a/src/AgOledDisplay.h b/src/AgOledDisplay.h index 9d06354..7bd7614 100644 --- a/src/AgOledDisplay.h +++ b/src/AgOledDisplay.h @@ -40,6 +40,8 @@ public: void showNewFirmwareUpdating(String percent); void showNewFirmwareSuccess(String count); void showNewFirmwareFailed(void); + void showNewFirmwareSkipped(void); + void showNewFirmwareUpToDate(void); }; #endif /** _AG_OLED_DISPLAY_H_ */ From c04ab90fd208f07d1a1baafd70ebe958f4c14591 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Fri, 17 May 2024 10:32:20 +0700 Subject: [PATCH 02/15] Update OTA processing message. Fix always retry of bootCount = 0 --- examples/OneOpenAir/OneOpenAir.ino | 11 +++++++++-- src/AgOledDisplay.cpp | 3 ++- src/AgValue.h | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index 35bcaeb..67ea2e0 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -549,6 +549,11 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { break; } case OtaState::OTA_STATE_SUCCESS: { + if (ag->isOne()) { + oledDisplay.showNewFirmwareUpdating(String(100)); + delay(250); + } + int i = 6; while(i != 0) { i = i - 1; @@ -564,6 +569,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { delay(1000); } + oledDisplay.setBrightness(0); esp_restart(); } break; @@ -877,11 +883,12 @@ static void configUpdateHandle() { fwNewVersion = configuration.newFirmwareVersion(); if (fwNewVersion.length()) { bool doOta = false; - if (measurements.otaBootCount == 0) { + if (measurements.otaBootCount < 0) { doOta = true; Serial.println("First OTA"); } else { - if ((measurements.bootCount - measurements.otaBootCount) >= 30) { + int bootDiff = measurements.bootCount - measurements.otaBootCount; + if (bootDiff >= 30) { doOta = true; } else { Serial.println( diff --git a/src/AgOledDisplay.cpp b/src/AgOledDisplay.cpp index 125c887..5e6699d 100644 --- a/src/AgOledDisplay.cpp +++ b/src/AgOledDisplay.cpp @@ -380,7 +380,8 @@ void OledDisplay::showNewFirmwareFailed(void) { do { DISP()->setFont(u8g2_font_t0_16_tf); setCentralText(20, "Firmware Update"); - setCentralText(40, "Failed"); + setCentralText(40, "fail, will retry"); + // setCentralText(60, "will retry"); } while (DISP()->nextPage()); } diff --git a/src/AgValue.h b/src/AgValue.h index 7446411..a30857e 100644 --- a/src/AgValue.h +++ b/src/AgValue.h @@ -69,7 +69,7 @@ public: int countPosition; const int targetCount = 20; int bootCount; - int otaBootCount; + int otaBootCount = -1; String toString(bool isLocal, AgFirmwareMode fwMode, int rssi, void* _ag, void* _config); }; From 6e54409512d519bcf4dca0e2005a675c81fcaa5b Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Fri, 17 May 2024 20:17:49 +0700 Subject: [PATCH 03/15] rename function --- examples/OneOpenAir/OneOpenAir.ino | 17 ++++++----------- src/AgOledDisplay.cpp | 14 +++++++------- src/AgOledDisplay.h | 12 ++++++------ 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index 67ea2e0..f52a394 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -502,7 +502,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { switch (state) { case OtaState::OTA_STATE_BEGIN: { if (ag->isOne()) { - oledDisplay.showNewFirmwareVersion(msg); + oledDisplay.showFirmwareUpdateVersion(msg); } else { Serial.println("New firmware: " + msg); } @@ -511,7 +511,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { } case OtaState::OTA_STATE_FAIL: { if (ag->isOne()) { - oledDisplay.showNewFirmwareFailed(); + oledDisplay.showFirmwareUpdateFailed(); } else { Serial.println("Error: Firmware update: failed"); } @@ -521,7 +521,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { } case OtaState::OTA_STATE_SKIP: { if (ag->isOne()) { - oledDisplay.showNewFirmwareSkipped(); + oledDisplay.showFirmwareUpdateSkipped(); } else { Serial.println("Firmware update: Skipped"); } @@ -531,7 +531,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { } case OtaState::OTA_STATE_UP_TO_DATE: { if (ag->isOne()) { - oledDisplay.showNewFirmwareUpToDate(); + oledDisplay.showFirmwareUpdateUpToDate(); } else { Serial.println("Firmware update: up to date"); } @@ -541,7 +541,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { } case OtaState::OTA_STATE_PROCESSING: { if (ag->isOne()) { - oledDisplay.showNewFirmwareUpdating(String(processing)); + oledDisplay.showFirmwareUpdateProgress(processing); } else { Serial.println("Firmware update: " + String(processing) + String("%")); } @@ -549,11 +549,6 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { break; } case OtaState::OTA_STATE_SUCCESS: { - if (ag->isOne()) { - oledDisplay.showNewFirmwareUpdating(String(100)); - delay(250); - } - int i = 6; while(i != 0) { i = i - 1; @@ -562,7 +557,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { while (i != 0) { i = i - 1; if (ag->isOne()) { - oledDisplay.showNewFirmwareSuccess(String(i)); + oledDisplay.showFirmwareUpdateSuccess(String(i)); } else { Serial.println("Rebooting... " + String(i)); } diff --git a/src/AgOledDisplay.cpp b/src/AgOledDisplay.cpp index 5e6699d..ccce42a 100644 --- a/src/AgOledDisplay.cpp +++ b/src/AgOledDisplay.cpp @@ -330,7 +330,7 @@ void OledDisplay::setBrightness(int percent) { } } -void OledDisplay::showNewFirmwareVersion(String version) { +void OledDisplay::showFirmwareUpdateVersion(String version) { if (isDisplayOff) { return; } @@ -344,7 +344,7 @@ void OledDisplay::showNewFirmwareVersion(String version) { } while (DISP()->nextPage()); } -void OledDisplay::showNewFirmwareUpdating(String percent) { +void OledDisplay::showFirmwareUpdateProgress(int percent) { if (isDisplayOff) { return; } @@ -353,11 +353,11 @@ void OledDisplay::showNewFirmwareUpdating(String percent) { do { DISP()->setFont(u8g2_font_t0_16_tf); setCentralText(20, "Firmware Update"); - setCentralText(50, String("Updating... ") + percent + String("%")); + setCentralText(50, String("Updating... ") + String(percent) + String("%")); } while (DISP()->nextPage()); } -void OledDisplay::showNewFirmwareSuccess(String count) { +void OledDisplay::showFirmwareUpdateSuccess(String count) { if (isDisplayOff) { return; } @@ -371,7 +371,7 @@ void OledDisplay::showNewFirmwareSuccess(String count) { } while (DISP()->nextPage()); } -void OledDisplay::showNewFirmwareFailed(void) { +void OledDisplay::showFirmwareUpdateFailed(void) { if (isDisplayOff) { return; } @@ -385,7 +385,7 @@ void OledDisplay::showNewFirmwareFailed(void) { } while (DISP()->nextPage()); } -void OledDisplay::showNewFirmwareSkipped(void) { +void OledDisplay::showFirmwareUpdateSkipped(void) { if (isDisplayOff) { return; } @@ -398,7 +398,7 @@ void OledDisplay::showNewFirmwareSkipped(void) { } while (DISP()->nextPage()); } -void OledDisplay::showNewFirmwareUpToDate(void) { +void OledDisplay::showFirmwareUpdateUpToDate(void) { if (isDisplayOff) { return; } diff --git a/src/AgOledDisplay.h b/src/AgOledDisplay.h index 7bd7614..1013935 100644 --- a/src/AgOledDisplay.h +++ b/src/AgOledDisplay.h @@ -36,12 +36,12 @@ public: void showDashboard(void); void showDashboard(const char *status); void setBrightness(int percent); - void showNewFirmwareVersion(String version); - void showNewFirmwareUpdating(String percent); - void showNewFirmwareSuccess(String count); - void showNewFirmwareFailed(void); - void showNewFirmwareSkipped(void); - void showNewFirmwareUpToDate(void); + void showFirmwareUpdateVersion(String version); + void showFirmwareUpdateProgress(int percent); + void showFirmwareUpdateSuccess(String count); + void showFirmwareUpdateFailed(void); + void showFirmwareUpdateSkipped(void); + void showFirmwareUpdateUpToDate(void); }; #endif /** _AG_OLED_DISPLAY_H_ */ From 6ea0ab9272607a1e254395044d7c72211b6ee1b8 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Fri, 17 May 2024 20:18:59 +0700 Subject: [PATCH 04/15] Set process 100% after received firmware file. --- examples/OneOpenAir/OtaHandler.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/OneOpenAir/OtaHandler.h b/examples/OneOpenAir/OtaHandler.h index 33fa233..a845f8b 100644 --- a/examples/OneOpenAir/OtaHandler.h +++ b/examples/OneOpenAir/OtaHandler.h @@ -138,6 +138,9 @@ private: int data_read = esp_http_client_read(client, upgrade_data_buf, OTA_BUF_SIZE); if (data_read == 0) { + if (this->callback) { + this->callback(OtaState::OTA_STATE_PROCESSING, String(100)); + } Serial.println("Connection closed, all data received"); break; } From 3e2e8b15eb0b3d2946ae4e1e4c04626396f8af8b Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Tue, 4 Jun 2024 15:51:01 +0700 Subject: [PATCH 05/15] Fix: WiFi configuration not reset in offline mode. --- examples/OneOpenAir/OneOpenAir.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index 5edc5c0..5f84c26 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -420,6 +420,7 @@ static void factoryConfigReset(void) { } /** Reset WIFI */ + WiFi.enableSTA(true); // Incase offline mode WiFi.disconnect(true, true); /** Reset local config */ From 11ecea1493e89c9277e511b403d9816e5ebecf55 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Tue, 4 Jun 2024 18:01:28 +0700 Subject: [PATCH 06/15] Change `showFirmwareUpdateSuccess` input from`String` to `int` --- src/AgOledDisplay.cpp | 4 ++-- src/AgOledDisplay.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AgOledDisplay.cpp b/src/AgOledDisplay.cpp index ccce42a..bd8ee95 100644 --- a/src/AgOledDisplay.cpp +++ b/src/AgOledDisplay.cpp @@ -357,7 +357,7 @@ void OledDisplay::showFirmwareUpdateProgress(int percent) { } while (DISP()->nextPage()); } -void OledDisplay::showFirmwareUpdateSuccess(String count) { +void OledDisplay::showFirmwareUpdateSuccess(int count) { if (isDisplayOff) { return; } @@ -367,7 +367,7 @@ void OledDisplay::showFirmwareUpdateSuccess(String count) { DISP()->setFont(u8g2_font_t0_16_tf); setCentralText(20, "Firmware Update"); setCentralText(40, "Success"); - setCentralText(60, String("Rebooting... ") + count); + setCentralText(60, String("Rebooting... ") + String(count)); } while (DISP()->nextPage()); } diff --git a/src/AgOledDisplay.h b/src/AgOledDisplay.h index 1013935..4073f0f 100644 --- a/src/AgOledDisplay.h +++ b/src/AgOledDisplay.h @@ -38,7 +38,7 @@ public: void setBrightness(int percent); void showFirmwareUpdateVersion(String version); void showFirmwareUpdateProgress(int percent); - void showFirmwareUpdateSuccess(String count); + void showFirmwareUpdateSuccess(int count); void showFirmwareUpdateFailed(void); void showFirmwareUpdateSkipped(void); void showFirmwareUpdateUpToDate(void); From ef6b0415290df29837c80ef44a0844823b07c262 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Tue, 4 Jun 2024 18:01:55 +0700 Subject: [PATCH 07/15] Fix: ota not callback on first powerup perform --- examples/OneOpenAir/OneOpenAir.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index e323b9a..d794795 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -219,6 +219,7 @@ void setup() { #ifdef ESP8266 // ota not supported #else + otaHandler.setHandlerCallback(otaHandlerCallback); otaHandler.updateFirmwareIfOutdated(ag->deviceId()); /** Update first OTA */ @@ -485,6 +486,7 @@ static bool sgp41Init(void) { } static void otaHandlerCallback(OtaState state, String mesasge) { + Serial.println("OTA message: " + mesasge); switch (state) { case OtaState::OTA_STATE_BEGIN: displayExecuteOta(state, fwNewVersion, 0); @@ -562,7 +564,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) { while (i != 0) { i = i - 1; if (ag->isOne()) { - oledDisplay.showFirmwareUpdateSuccess(String(i)); + oledDisplay.showFirmwareUpdateSuccess(i); } else { Serial.println("Rebooting... " + String(i)); } From 037bb371843f68ad510ec5c0a505367fdc4d187c Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Tue, 4 Jun 2024 18:29:35 +0700 Subject: [PATCH 08/15] Change macro name `SERVER_CONFIG_UPDATE_INTERVAL' to `SERVER_CONFIG_SYNC_INTERVAL` --- examples/BASIC/BASIC.ino | 4 ++-- examples/OneOpenAir/OneOpenAir.ino | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/BASIC/BASIC.ino b/examples/BASIC/BASIC.ino index ea1bb1b..524d0a8 100644 --- a/examples/BASIC/BASIC.ino +++ b/examples/BASIC/BASIC.ino @@ -41,7 +41,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License #define LED_BAR_COUNT_INIT_VALUE (-1) /** */ #define LED_BAR_ANIMATION_PERIOD 100 /** ms */ #define DISP_UPDATE_INTERVAL 5000 /** ms */ -#define SERVER_CONFIG_UPDATE_INTERVAL 30000 /** ms */ +#define SERVER_CONFIG_SYNC_INTERVAL 30000 /** ms */ #define SERVER_SYNC_INTERVAL 60000 /** ms */ #define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */ #define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */ @@ -82,7 +82,7 @@ bool hasSensorPMS = true; bool hasSensorSHT = true; int pmFailCount = 0; int getCO2FailCount = 0; -AgSchedule configSchedule(SERVER_CONFIG_UPDATE_INTERVAL, +AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL, updateServerConfiguration); AgSchedule serverSchedule(SERVER_SYNC_INTERVAL, sendDataToServer); AgSchedule dispSchedule(DISP_UPDATE_INTERVAL, dispHandler); diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index e3a09bd..640af60 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -55,7 +55,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License #define LED_BAR_ANIMATION_PERIOD 100 /** ms */ #define DISP_UPDATE_INTERVAL 2500 /** ms */ -#define SERVER_CONFIG_UPDATE_INTERVAL 15000 /** ms */ +#define SERVER_CONFIG_SYNC_INTERVAL 15000 /** ms */ #define SERVER_SYNC_INTERVAL 60000 /** ms */ #define MQTT_SYNC_INTERVAL 60000 /** ms */ #define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */ @@ -118,7 +118,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing); AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplayLedBarSchedule); -AgSchedule configSchedule(SERVER_CONFIG_UPDATE_INTERVAL, +AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL, configurationUpdateSchedule); AgSchedule agApiPostSchedule(SERVER_SYNC_INTERVAL, sendDataToServer); AgSchedule co2Schedule(SENSOR_CO2_UPDATE_INTERVAL, co2Update); From f7e811e34baf2e839a46fd3b454092fb9bc61b32 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Tue, 4 Jun 2024 18:30:33 +0700 Subject: [PATCH 09/15] Update server GET configure period to `60` sec --- examples/BASIC/BASIC.ino | 2 +- examples/OneOpenAir/OneOpenAir.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/BASIC/BASIC.ino b/examples/BASIC/BASIC.ino index 524d0a8..eed4818 100644 --- a/examples/BASIC/BASIC.ino +++ b/examples/BASIC/BASIC.ino @@ -41,7 +41,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License #define LED_BAR_COUNT_INIT_VALUE (-1) /** */ #define LED_BAR_ANIMATION_PERIOD 100 /** ms */ #define DISP_UPDATE_INTERVAL 5000 /** ms */ -#define SERVER_CONFIG_SYNC_INTERVAL 30000 /** ms */ +#define SERVER_CONFIG_SYNC_INTERVAL 60000 /** ms */ #define SERVER_SYNC_INTERVAL 60000 /** ms */ #define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */ #define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */ diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index 640af60..dbd1385 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -55,7 +55,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License #define LED_BAR_ANIMATION_PERIOD 100 /** ms */ #define DISP_UPDATE_INTERVAL 2500 /** ms */ -#define SERVER_CONFIG_SYNC_INTERVAL 15000 /** ms */ +#define SERVER_CONFIG_SYNC_INTERVAL 60000 /** ms */ #define SERVER_SYNC_INTERVAL 60000 /** ms */ #define MQTT_SYNC_INTERVAL 60000 /** ms */ #define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */ From 0b12f56513320f726f06c97ca5a33726635eaa15 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Tue, 4 Jun 2024 22:17:20 +0700 Subject: [PATCH 10/15] add `bootCount` to measure report --- src/AgValue.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AgValue.cpp b/src/AgValue.cpp index 14580ff..c3bcc85 100644 --- a/src/AgValue.cpp +++ b/src/AgValue.cpp @@ -174,6 +174,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi, } } root["boot"] = bootCount; + root["bootCount"] = bootCount; if (localServer) { root["ledMode"] = config->getLedBarModeName(); From d2d81f6b4be457a38caa991e76c6110dd100eebe Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Wed, 5 Jun 2024 09:29:30 +0700 Subject: [PATCH 11/15] OTA update each 60 min --- examples/OneOpenAir/OneOpenAir.ino | 53 +++++++++++++----------------- src/AgValue.h | 1 - 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index e3a09bd..5bcd200 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -64,6 +64,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License #define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */ #define SENSOR_TEMP_HUM_UPDATE_INTERVAL 2000 /** ms */ #define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */ +#define FIRMWARE_CHECK_FOR_UPDATE_MS (60*60*1000) /** ms */ /** I2C define */ #define I2C_SDA_PIN 7 @@ -113,6 +114,7 @@ static void factoryConfigReset(void); static void wdgFeedUpdate(void); static void ledBarEnabledUpdate(void); static bool sgp41Init(void); +static void firmwareCheckForUpdate(void); static void otaHandlerCallback(OtaState state, String mesasge); static void displayExecuteOta(OtaState state, String msg, int processing); @@ -126,6 +128,7 @@ AgSchedule pmsSchedule(SENSOR_PM_UPDATE_INTERVAL, updatePm); AgSchedule tempHumSchedule(SENSOR_TEMP_HUM_UPDATE_INTERVAL, tempHumUpdate); AgSchedule tvocSchedule(SENSOR_TVOC_UPDATE_INTERVAL, updateTvoc); AgSchedule watchdogFeedSchedule(60000, wdgFeedUpdate); +AgSchedule checkForUpdateSchedule(FIRMWARE_CHECK_FOR_UPDATE_MS, firmwareCheckForUpdate); void setup() { /** Serial for print debug message */ @@ -219,11 +222,8 @@ void setup() { #ifdef ESP8266 // ota not supported #else - otaHandler.setHandlerCallback(otaHandlerCallback); - otaHandler.updateFirmwareIfOutdated(ag->deviceId()); - - /** Update first OTA */ - measurements.otaBootCount = 0; + firmwareCheckForUpdate(); + checkForUpdateSchedule.update(); #endif apiClient.fetchServerConfiguration(); @@ -313,6 +313,9 @@ void loop() { /** check that local configura changed then do some action */ configUpdateHandle(); + + /** Firmware check for update handle */ + checkForUpdateSchedule.run(); } static void co2Update(void) { @@ -489,6 +492,20 @@ static bool sgp41Init(void) { return false; } +static void firmwareCheckForUpdate(void) { + Serial.println(); + Serial.println("firmwareCheckForUpdate:"); + + if (wifiConnector.isConnected()) { + Serial.println("firmwareCheckForUpdate: Perform"); + otaHandler.setHandlerCallback(otaHandlerCallback); + otaHandler.updateFirmwareIfOutdated(ag->deviceId()); + } else { + Serial.println("firmwareCheckForUpdate: Ignored"); + } + Serial.println(); +} + static void otaHandlerCallback(OtaState state, String mesasge) { Serial.println("OTA message: " + mesasge); switch (state) { @@ -904,32 +921,6 @@ static void configUpdateHandle() { stateMachine.executeLedBarTest(); } - fwNewVersion = configuration.newFirmwareVersion(); - if (fwNewVersion.length()) { - bool doOta = false; - if (measurements.otaBootCount < 0) { - doOta = true; - Serial.println("First OTA"); - } else { - /** Only check for update each 1h*/ - const float otaBootCount = 60.0f / (SERVER_SYNC_INTERVAL / 60000.0f); - if ((measurements.bootCount - measurements.otaBootCount) >= (int)otaBootCount) { - doOta = true; - } else { - Serial.println( - "OTA ignore, try again next " + - String(30 - (measurements.bootCount - measurements.otaBootCount)) + - String(" boots")); - } - } - - if (doOta) { - measurements.otaBootCount = measurements.bootCount; - otaHandler.setHandlerCallback(otaHandlerCallback); - otaHandler.updateFirmwareIfOutdated(ag->deviceId()); - } - } - appDispHandler(); appLedHandler(); } diff --git a/src/AgValue.h b/src/AgValue.h index a30857e..3176482 100644 --- a/src/AgValue.h +++ b/src/AgValue.h @@ -69,7 +69,6 @@ public: int countPosition; const int targetCount = 20; int bootCount; - int otaBootCount = -1; String toString(bool isLocal, AgFirmwareMode fwMode, int rssi, void* _ag, void* _config); }; From 3da4900462caf4587bc50391fe8972d1ade8f460 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Wed, 5 Jun 2024 09:58:08 +0700 Subject: [PATCH 12/15] Update show mesage on display --- examples/OneOpenAir/OneOpenAir.ino | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index e3a09bd..15614eb 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -166,16 +166,6 @@ void setup() { /** Connecting wifi */ bool connectToWifi = false; if (ag->isOne()) { - if (ledBarButtonTest) { - if (ag->button.getState() == PushButton::BUTTON_PRESSED) { - WiFi.begin("airgradient", "cleanair"); - Serial.println("WiFi Credential reset to factory defaults"); - ESP.restart(); - } - } else { - ledBarEnabledUpdate(); - } - /** Show message confirm offline mode, should me perform if LED bar button * test pressed */ if (ledBarButtonTest == false) { @@ -432,6 +422,7 @@ static void factoryConfigReset(void) { Serial.println("Factory reset successful"); } delay(3000); + oledDisplay.setText("","",""); ESP.restart(); } } @@ -664,6 +655,24 @@ static void oneIndoorInit(void) { } } + /** Check for button to reset WiFi connecto to "airgraident" after test LED + * bar */ + if (ledBarButtonTest) { + if (ag->button.getState() == ag->button.BUTTON_PRESSED) { + WiFi.begin("airgradient", "cleanair"); + oledDisplay.setText("Configure WiFi", "connect to", "\'airgradient\'"); + delay(2500); + oledDisplay.setText("Rebooting...", "",""); + delay(2500); + oledDisplay.setText("","",""); + ESP.restart(); + } + } + ledBarEnabledUpdate(); + + /** Show message init sensor */ + oledDisplay.setText("Sensor", "initializing...", ""); + /** Init sensor SGP41 */ if (sgp41Init() == false) { dispSensorNotFound("SGP41"); From 2ae90444bbcdf3c7aa20e382918b8ced7e596122 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Wed, 5 Jun 2024 14:31:34 +0700 Subject: [PATCH 13/15] Fix reboot device after WiFi Connector perform but not connected --- examples/OneOpenAir/OneOpenAir.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index 9aef26e..e93912d 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -244,6 +244,8 @@ void setup() { } else { oledDisplay.showRebooting(); delay(2500); + oledDisplay.setText("", "", ""); + ESP.restart(); } } } From da323b1a461639a1618637ea658de6cba68a2322 Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Wed, 5 Jun 2024 19:01:25 +0700 Subject: [PATCH 14/15] fix reboot device after WiFi portal configure timeout. --- examples/OneOpenAir/OneOpenAir.ino | 10 ++++++---- src/AgWiFiConnector.cpp | 10 ++++++++++ src/AgWiFiConnector.h | 3 +++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/examples/OneOpenAir/OneOpenAir.ino b/examples/OneOpenAir/OneOpenAir.ino index e93912d..e124765 100644 --- a/examples/OneOpenAir/OneOpenAir.ino +++ b/examples/OneOpenAir/OneOpenAir.ino @@ -242,10 +242,12 @@ void setup() { ledBarEnabledUpdate(); } } else { - oledDisplay.showRebooting(); - delay(2500); - oledDisplay.setText("", "", ""); - ESP.restart(); + if (wifiConnector.isConfigurePorttalTimeout()) { + oledDisplay.showRebooting(); + delay(2500); + oledDisplay.setText("", "", ""); + ESP.restart(); + } } } } diff --git a/src/AgWiFiConnector.cpp b/src/AgWiFiConnector.cpp index c8a9d8d..f71a9cd 100644 --- a/src/AgWiFiConnector.cpp +++ b/src/AgWiFiConnector.cpp @@ -53,6 +53,7 @@ bool WifiConnector::connect(void) { WIFI()->setAPCallback([this](WiFiManager *obj) { _wifiApCallback(); }); WIFI()->setSaveConfigCallback([this]() { _wifiSaveConfig(); }); WIFI()->setSaveParamsCallback([this]() { _wifiSaveParamCallback(); }); + WIFI()->setConfigPortalTimeoutCallback([this](){}); if (ag->isOne()) { disp.setText("Connecting to", "WiFi", "..."); } else { @@ -245,6 +246,7 @@ void WifiConnector::_wifiSaveParamCallback(void) { bool WifiConnector::_wifiConfigPortalActive(void) { return WIFI()->getConfigPortalActive(); } +void WifiConnector::_wifiTimeoutCallback(void) { connectorTimeout = true; } #endif /** * @brief Process WiFiManager connection @@ -352,3 +354,11 @@ bool WifiConnector::hasConfigurated(void) { } return true; } + +/** + * @brief Get WiFi connection porttal timeout. + * + * @return true + * @return false + */ +bool WifiConnector::isConfigurePorttalTimeout(void) { return connectorTimeout; } diff --git a/src/AgWiFiConnector.h b/src/AgWiFiConnector.h index 090f0d2..b4e76a7 100644 --- a/src/AgWiFiConnector.h +++ b/src/AgWiFiConnector.h @@ -24,6 +24,7 @@ private: bool hasConfig; uint32_t lastRetry; bool hasPortalConfig = false; + bool connectorTimeout = false; bool wifiClientConnected(void); @@ -44,6 +45,7 @@ public: void _wifiSaveConfig(void); void _wifiSaveParamCallback(void); bool _wifiConfigPortalActive(void); + void _wifiTimeoutCallback(void); #endif void _wifiProcess(); bool isConnected(void); @@ -51,6 +53,7 @@ public: int RSSI(void); String localIpStr(void); bool hasConfigurated(void); + bool isConfigurePorttalTimeout(void); }; #endif /** _AG_WIFI_CONNECTOR_H_ */ From 6aa19ea3e6050963f38298dc2c7dd8cd5b55666c Mon Sep 17 00:00:00 2001 From: Phat Nguyen Date: Thu, 6 Jun 2024 08:44:12 +0700 Subject: [PATCH 15/15] Set next version --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 6dfaf5b..2d34956 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AirGradient Air Quality Sensor -version=3.1.0-beta.1 +version=3.1.3 author=AirGradient maintainer=AirGradient sentence=ESP32-C3 / ESP8266 library for air quality monitor measuring PM, CO2, Temperature, TVOC and Humidity with OLED display.