mirror of
https://github.com/meshtastic/firmware.git
synced 2026-10-01 02:35:28 -04:00
* 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.
46 lines
1.7 KiB
C++
46 lines
1.7 KiB
C++
#pragma once
|
|
|
|
#include "DebugConfiguration.h"
|
|
#include "NodeDB.h"
|
|
#include "configuration.h"
|
|
#include "sleep.h"
|
|
|
|
class BaseTelemetryModule
|
|
{
|
|
protected:
|
|
bool isSensorOrRouterRole() const
|
|
{
|
|
return config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR ||
|
|
config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ||
|
|
config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE;
|
|
}
|
|
|
|
/// True for a SENSOR role node with power saving enabled, the only combination that deep
|
|
/// sleeps between telemetry broadcasts
|
|
bool isPowerSavingSensor() const
|
|
{
|
|
return config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR && config.power.is_power_saving;
|
|
}
|
|
|
|
/**
|
|
* Call while a deep sleep is pending (sleepOnNextExecution): the telemetry packet queued by
|
|
* sendTelemetry() goes out asynchronously, and sleeping while it is still queued or on air
|
|
* truncates the transmission. Returns true if the caller should reschedule in
|
|
* PREFLIGHT_SLEEP_RETRY_MS and check again. Bounded by MAX_PREFLIGHT_SLEEP_DEFERRALS so a
|
|
* busy mesh can't keep the node awake forever. Reset preflightSleepDeferrals to 0 whenever
|
|
* sleepOnNextExecution is armed.
|
|
*/
|
|
bool shouldDeferDeepSleep()
|
|
{
|
|
if (doPreflightSleep(true) || preflightSleepDeferrals >= MAX_PREFLIGHT_SLEEP_DEFERRALS)
|
|
return false;
|
|
preflightSleepDeferrals++;
|
|
LOG_DEBUG("Radio busy, defer deep sleep");
|
|
return true;
|
|
}
|
|
|
|
// While sleepOnNextExecution is pending, counts how often the deep sleep was postponed
|
|
// because doPreflightSleep() vetoed it (e.g. radio still transmitting)
|
|
uint32_t preflightSleepDeferrals = 0;
|
|
};
|