Skip to content

Power airtime monotonic windows due to light sleep. #10582

Open
h3lix1 wants to merge 2 commits into
meshtastic:developfrom
h3lix1:power-airtime-monotonic-windows
Open

Power airtime monotonic windows due to light sleep. #10582
h3lix1 wants to merge 2 commits into
meshtastic:developfrom
h3lix1:power-airtime-monotonic-windows

Conversation

@h3lix1
Copy link
Copy Markdown
Contributor

@h3lix1 h3lix1 commented May 30, 2026

Power Airtime Monotonic Windows

Summary

This change updates airtime accounting to advance from monotonic uptime instead of the AirTime thread's once-per-second scheduler tick.

Before this change, AirTime::runOnce() incremented an internal secSinceBoot counter by one each time the thread ran. On devices using light sleep, the scheduler can be paused while real time continues. That means the channel-utilization and TX-utilization windows could decay according to awake scheduler time, not elapsed wall time.

After this change, airtime windows are synchronized from millis() before airtime is logged or read. Packets observed after wake are counted in the current elapsed-time bucket, and buckets crossed during sleep are cleared or rotated immediately.

Motivation

The power-saving work makes ESP32 nodes enter light sleep quickly after packet processing. That exposed a mismatch in airtime accounting:

  • Channel utilization is intended to be a rolling 60-second view.
  • TX utilization is intended to be a rolling 60-minute view.
  • Historical airtime reports are intended to use hour-sized periods.
  • The old implementation advanced those windows only when the AirTime thread ran.

When a node slept frequently, old airtime could remain in the active channel-utilization window for longer than 60 real seconds. This could make the channel appear busy after the channel had actually been quiet from the node's point of view.

Code Changes

The change is isolated to:

  • src/airtime.cpp
  • src/airtime.h

The new private helper is:

void AirTime::syncNow();

syncNow() uses millis() as the time source. It intentionally does not use RTC, GPS, NTP, or mesh time, because wall-clock time can move backward or forward. Airtime windows should be based on monotonic uptime.

The helper is called from:

  • logAirtime()
  • airtimeReport()
  • getSecondsSinceBoot()
  • channelUtilizationPercent()
  • utilizationTXPercent()
  • runOnce()
  • airtimeRotatePeriod()

Calling it from both readers and writers matters because a node may wake, receive a packet, or make a send-gating decision before the periodic AirTime thread runs again.

Window Behavior

Channel utilization keeps the existing six 10-second buckets:

#define CHANNEL_UTILIZATION_PERIODS 6

If one or more 10-second boundaries were crossed while the scheduler was paused, syncNow() clears each crossed bucket. If the elapsed time is large enough to cover the full 60-second window, it clears the whole channel-utilization window.
TX utilization keeps the existing 60 one-minute buckets:

#define MINUTES_IN_HOUR 60

If one or more minute boundaries were crossed, syncNow() clears those buckets. If the elapsed time covers the full hour, it clears the full TX-utilization window.

Historical airtime reports keep the existing hour-sized periods:

#define SECONDS_PER_PERIOD 3600
#define PERIODS_TO_LOG 8

If one or more hour boundaries were crossed, syncNow() rotates the report periods. If the elapsed time covers all retained periods, it clears the full report window.

Expected Runtime Impact

The main behavioral change is that channel utilization and TX utilization decay according to elapsed monotonic uptime, including time spent in light sleep.
This can affect send-gating decisions that use:

airTime->isTxAllowedChannelUtil(...)
airTime->isTxAllowedAirUtil()

🤝 Attestations

  • I have tested that my proposed changes behave as described.
  • I have tested that my proposed changes do not cause any obvious regressions on the following devices:
    • Heltec (Lora32) V3
    • LilyGo T-Deck
    • LilyGo T-Beam
    • RAK WisBlock 4631
    • Seeed Studio T-1000E tracker card
    • Other (please specify below)
      Heltec v4.3

@github-actions github-actions Bot added the enhancement New feature or request label May 30, 2026
@m1nl
Copy link
Copy Markdown
Contributor

m1nl commented May 30, 2026

need to review your code more carefully, but isn't that duplicate of 9778, which looks like has been closed as I didn't receive feedback / review from maintainers?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants