diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp index 3373966c2..5418d6620 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.cpp +++ b/src/modules/Telemetry/AirQualityTelemetry.cpp @@ -208,6 +208,10 @@ int32_t AirQualityTelemetryModule::runOnce() if (!sensor->isActive()) { LOG_DEBUG("Waking up: %s", sensor->sensorName); + if (awakeAheadOfTimeMs == 0) + startAirQualityTelemetryCycle = millis(); + awakeAheadOfTimeMs = max(awakeAheadOfTimeMs, sensor->wakeUpTimeMs()); + // TODO multiple sensors with different wake up times collide return sensor->wakeUp(); } @@ -219,19 +223,35 @@ int32_t AirQualityTelemetryModule::runOnce() } bool telemetryDue = (lastTelemetry == 0) || !Throttle::isWithinTimespanMs(lastTelemetry, telemetryIntervalMs); - bool phoneDue = (lastSentToPhone == 0) || !Throttle::isWithinTimespanMs(lastSentToPhone, sendToPhoneIntervalMs); if (telemetryDue && telemetryAllowed) { - sendTelemetry(); - - if (transmitHistory) { - transmitHistory->setLastSentToMesh(TX_HISTORY_KEY_AIR_QUALITY_TELEMETRY); + if (sendTelemetry()) { + if (transmitHistory) { + transmitHistory->setLastSentToMesh(TX_HISTORY_KEY_AIR_QUALITY_TELEMETRY); + } + // Correct the awake time, trimming to 0 + const unsigned long elapsed = millis() - startAirQualityTelemetryCycle; + awakeAheadOfTimeMs = elapsed >= awakeAheadOfTimeMs ? 0 : awakeAheadOfTimeMs - elapsed; + // LOG_DEBUG("Time to publish. Correcting ahead of time by: %d", awakeAheadOfTimeMs); + } else { + awakeAheadOfTimeMs = 0; } } else if (phoneDue && phoneAllowed) { // Mesh transmission isn't due yet, but we can still update the phone. - sendTelemetry(NODENUM_BROADCAST, true); - lastSentToPhone = millis(); + if (sendTelemetry(NODENUM_BROADCAST, true)) { + lastSentToPhone = millis(); + // Correct the awake time, trimming to 0 + const unsigned long elapsed = millis() - startAirQualityTelemetryCycle; + awakeAheadOfTimeMs = elapsed >= awakeAheadOfTimeMs ? 0 : awakeAheadOfTimeMs - elapsed; + // LOG_DEBUG("Time to publish. Correcting ahead of time by: %d", awakeAheadOfTimeMs); + } else { + awakeAheadOfTimeMs = 0; + } + } else { + // if for some reason we end up here after waking up, but not able to send, then reset + // the counter + awakeAheadOfTimeMs = 0; } // Send to sleep sensors that can be to save power @@ -253,7 +273,13 @@ int32_t AirQualityTelemetryModule::runOnce() // mistime the pending deep sleep return FIVE_SECONDS_MS; } - return min(sendToPhoneIntervalMs, result); + + // Update next interval if we were ahead + uint32_t correctedIntervalMs = sendToPhoneIntervalMs + awakeAheadOfTimeMs; + awakeAheadOfTimeMs = 0; + startAirQualityTelemetryCycle = 0; + LOG_DEBUG("Corrected interval in ms: %u", correctedIntervalMs); + return min(correctedIntervalMs, result); } bool AirQualityTelemetryModule::wantUIFrame() diff --git a/src/modules/Telemetry/AirQualityTelemetry.h b/src/modules/Telemetry/AirQualityTelemetry.h index 4cc5af420..7a7bfff5a 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.h +++ b/src/modules/Telemetry/AirQualityTelemetry.h @@ -66,6 +66,8 @@ class AirQualityTelemetryModule : private concurrency::OSThread, private: bool firstTime = true; + int32_t awakeAheadOfTimeMs = 0; + int32_t startAirQualityTelemetryCycle = 0; meshtastic_MeshPacket *lastMeasurementPacket; uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute // uint32_t sendToPhoneIntervalMs = 1000; // Send to phone every minute