Merge pull request #303 from airgradienthq/fix/ce-tvoc

Fix incorrect TVOC / NOx values when when network option is cellular
This commit is contained in:
Samuel Siburian
2025-04-15 12:25:39 +07:00
committed by GitHub
4 changed files with 53 additions and 26 deletions

View File

@@ -117,7 +117,7 @@ enum NetworkOption {
}; };
NetworkOption networkOption; NetworkOption networkOption;
TaskHandle_t handleNetworkTask = NULL; TaskHandle_t handleNetworkTask = NULL;
static bool otaInProgress = false; static bool firmwareUpdateInProgress = false;
static uint32_t factoryBtnPressTime = 0; static uint32_t factoryBtnPressTime = 0;
static AgFirmwareMode fwMode = FW_MODE_I_9PSL; static AgFirmwareMode fwMode = FW_MODE_I_9PSL;
@@ -318,8 +318,8 @@ void loop() {
// Schedule to feed external watchdog // Schedule to feed external watchdog
watchdogFeedSchedule.run(); watchdogFeedSchedule.run();
if (otaInProgress) { if (firmwareUpdateInProgress) {
// OTA currently in progress, temporarily disable running sensor schedules // Firmare update currently in progress, temporarily disable running sensor schedules
delay(10000); delay(10000);
return; return;
} }
@@ -562,28 +562,17 @@ void checkForFirmwareUpdate(void) {
agOta = new AirgradientOTACellular(cellularCard); agOta = new AirgradientOTACellular(cellularCard);
} }
// Indicate main task that ota is performing // Indicate main task that firmware update is in progress
Serial.println("Check for firmware update, disabling main task"); firmwareUpdateInProgress = true;
otaInProgress = true;
if (configuration.hasSensorSGP && networkOption == UseCellular) {
// Only for cellular because it can disturb i2c line
Serial.println("Disable SGP41 task for cellular OTA");
ag->sgp41.end();
}
agOta->setHandlerCallback(otaHandlerCallback); agOta->setHandlerCallback(otaHandlerCallback);
agOta->updateIfAvailable(ag->deviceId().c_str(), GIT_VERSION); agOta->updateIfAvailable(ag->deviceId().c_str(), GIT_VERSION);
// Only goes to this line if OTA is not success // Only goes to this line if firmware update is not success
// Handled by otaHandlerCallback // Handled by otaHandlerCallback
otaInProgress = false; // Indicate main task that firmware update finish
if (configuration.hasSensorSGP && networkOption == UseCellular) { firmwareUpdateInProgress = false;
// Re-start SGP41 task
if (!sgp41Init()) {
Serial.println("Failed re-start SGP41 task");
}
}
delete agOta; delete agOta;
Serial.println(); Serial.println();
@@ -591,14 +580,25 @@ void checkForFirmwareUpdate(void) {
void otaHandlerCallback(AirgradientOTA::OtaResult result, const char *msg) { void otaHandlerCallback(AirgradientOTA::OtaResult result, const char *msg) {
switch (result) { switch (result) {
case AirgradientOTA::Starting: case AirgradientOTA::Starting: {
Serial.println("Firmware update starting...");
if (configuration.hasSensorSGP && networkOption == UseCellular) {
// Temporary pause SGP41 task while cellular firmware update is in progress
ag->sgp41.pause();
}
displayExecuteOta(result, fwNewVersion, 0); displayExecuteOta(result, fwNewVersion, 0);
break; break;
}
case AirgradientOTA::InProgress: case AirgradientOTA::InProgress:
Serial.printf("OTA progress: %s\n", msg); Serial.printf("OTA progress: %s\n", msg);
displayExecuteOta(result, "", std::stoi(msg)); displayExecuteOta(result, "", std::stoi(msg));
break; break;
case AirgradientOTA::Failed: case AirgradientOTA::Failed:
displayExecuteOta(result, "", 0);
if (configuration.hasSensorSGP && networkOption == UseCellular) {
ag->sgp41.resume();
}
break;
case AirgradientOTA::Skipped: case AirgradientOTA::Skipped:
case AirgradientOTA::AlreadyUpToDate: case AirgradientOTA::AlreadyUpToDate:
displayExecuteOta(result, "", 0); displayExecuteOta(result, "", 0);
@@ -665,7 +665,11 @@ static void displayExecuteOta(AirgradientOTA::OtaResult result, String msg, int
} }
delay(1000); delay(1000);
} }
oledDisplay.setAirGradient(0);
if (ag->isOne()) {
oledDisplay.setAirGradient(0);
oledDisplay.setBrightness(0);
}
break; break;
} }
default: default:
@@ -1548,10 +1552,7 @@ void restartIfCeClientIssueOverTwoHours() {
void networkingTask(void *args) { void networkingTask(void *args) {
// OTA check on boot // OTA check on boot
#ifdef ESP8266 #ifndef ESP8266
// ota not supported
#else
// because cellular it takes too long, watchdog triggered
checkForFirmwareUpdate(); checkForFirmwareUpdate();
checkForUpdateSchedule.update(); checkForUpdateSchedule.update();
#endif #endif

View File

@@ -131,6 +131,22 @@ void Sgp41::handle(void) {
} }
#else #else
void Sgp41::pause() {
onPause = true;
Serial.println("Pausing SGP41 handler task");
// Set latest value to invalid
tvocRaw = utils::getInvalidVOC();
tvoc = utils::getInvalidVOC();
noxRaw = utils::getInvalidNOx();
nox = utils::getInvalidNOx();
}
void Sgp41::resume() {
onPause = false;
Serial.println("Resuming SGP41 handler task");
}
/** /**
* @brief Handle the sensor conditioning and run time udpate value, This method * @brief Handle the sensor conditioning and run time udpate value, This method
* must not call, it's called on private task * must not call, it's called on private task
@@ -152,6 +168,11 @@ void Sgp41::_handle(void) {
uint16_t srawVoc, srawNox; uint16_t srawVoc, srawNox;
for (;;) { for (;;) {
vTaskDelay(pdMS_TO_TICKS(1000)); vTaskDelay(pdMS_TO_TICKS(1000));
if (onPause) {
continue;
}
if (getRawSignal(srawVoc, srawNox)) { if (getRawSignal(srawVoc, srawNox)) {
tvocRaw = srawVoc; tvocRaw = srawVoc;
noxRaw = srawNox; noxRaw = srawNox;

View File

@@ -18,6 +18,10 @@ public:
bool begin(TwoWire &wire, Stream &stream); bool begin(TwoWire &wire, Stream &stream);
void handle(void); void handle(void);
#else #else
/* pause _handle task to read sensor */
void pause();
/* resume _handle task to read sensor */
void resume();
void _handle(void); void _handle(void);
#endif #endif
void end(void); void end(void);
@@ -32,6 +36,7 @@ public:
int getTvocLearningOffset(void); int getTvocLearningOffset(void);
private: private:
bool onPause = false;
bool onConditioning = true; bool onConditioning = true;
bool ready = false; bool ready = false;
bool _isBegin = false; bool _isBegin = false;