Fix SENSOR power saving deep sleep truncating TX and skipping sleep on failed reads (#10939)

* Fix SENSOR power saving deep sleep behavior

Deep sleep could be entered while a telemetry packet was still queued
or on air, truncating the transmission. canSleep() gained a deepSleep
parameter and now vetoes in that case; light sleep is unchanged.
Telemetry modules defer a pending deep sleep (bounded to 30s) until the
radio is idle and no longer let the sensor polling interval override
the 5s pre-sleep grace period. A failed sensor read still arms deep
sleep instead of leaving the node awake for a full telemetry interval.

Fixes #10890
Fixes #10932

* Deduplicate telemetry deep sleep deferral logic

Move the radio-busy deferral and its counter into BaseTelemetryModule
and add an isPowerSavingSensor() helper. Removes the telemetry-specific
counter from OSThread. The sleep arming block stays per module because
it needs protected OSThread members not visible to the base class.
This commit is contained in:
Thomas Göttgens
2026-07-08 07:30:46 -05:00
committed by GitHub
co-authored by GitHub
parent ba473bf529
commit 38074f584f
11 changed files with 162 additions and 48 deletions
+8 -3
View File
@@ -141,8 +141,12 @@ class RadioInterface
* Return true if we think the board can go to sleep (i.e. our tx queue is empty, we are not sending or receiving)
*
* This method must be used before putting the CPU into deep or light sleep.
*
* @param deepSleep true when the radio itself is about to be powered down (deep sleep or
* shutdown) - an in-flight transmission then vetoes sleep, since it would be truncated on
* air. false for a light sleep where the radio stays powered and finishes the TX on its own.
*/
virtual bool canSleep() { return true; }
virtual bool canSleep(bool deepSleep = false) { return true; }
virtual bool wideLora() { return false; }
@@ -314,8 +318,9 @@ class RadioInterface
*/
void applyModemConfig();
/// Return 0 if sleep is okay
int preflightSleepCb(void *unused = NULL) { return canSleep() ? 0 : 1; }
/// Return 0 if sleep is okay. A non-NULL argument means the radio is about to be powered
/// down (deep sleep / shutdown), see doPreflightSleep()
int preflightSleepCb(void *deepSleep = NULL) { return canSleep(deepSleep != NULL) ? 0 : 1; }
int notifyDeepSleepCb(void *unused = NULL);