-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Wifi power management #10271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wifi power management #10271
Conversation
Trying on ESP32-S2 QT Py & Pico W (3 of each to run each port with each power setting overnight). Not yet exercising the new get/set power APIs. Consistently get adafruit-circuitpython-adafruit_qtpy_esp32s2-en_US-20250420-main-PR10271-f8ed46a.uf2 adafruit-circuitpython-raspberry_pi_pico_w-en_US-20250420-main-PR10271-f8ed46a.uf2 code.pyimport time
import os
import traceback
import supervisor
import microcontroller
import wifi
import socketpool
import adafruit_requests
TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html"
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool)
def connect():
while not wifi.radio.connected:
try:
wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
print(f"{wifi.radio.ipv4_address}")
except Exception as ex:
traceback.print_exception(ex, ex, ex.__traceback__)
time.sleep(5)
# uncomment one of the three as appropriate, or leave all commented for default MIN
# wifi.radio.power_management = wifi.PowerManagement.NONE
wifi.radio.power_management = wifi.PowerManagement.MIN
# wifi.radio.power_management = wifi.PowerManagement.MAX
# increase delay between requests each time
interval_sec = 0
increment_sec = 60
timer_sec = time.time() - interval_sec
while True:
if time.time() - timer_sec > interval_sec:
try:
connect()
print(f"Fetching URL...")
with requests.get(TEXT_URL) as r:
print(f"{interval_sec:>5} {wifi.radio.power_management} {r.status_code} {r.reason.decode()} {r.content}")
interval_sec += increment_sec
timer_sec = time.time()
except Exception as ex:
traceback.print_exception(ex, ex, ex.__traceback__)
time.sleep(5)
# supervisor.reload()
# microcontroller.reset() (edited to match proper API) |
… wifi-power-management
The crashes @anecdata is seeing are totally unrelated to this PR. I am seeing the same crashes on the tip of |
Testing now on all six boards. If it behaves like it used to (on Pico W), the more aggressive power management settings may cause Interim Update: Both ports, at each power management level, have run so far with 20-minute intervals between requests, with no wifi disconnections. So it's looking good for no regressions. There are a number of requests exceptions along the way (more on Traceback (most recent call last):
File "adafruit_requests.py", line 658, in request
OSError: [Errno 116] ETIMEDOUT
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "code.py", line 37, in <module>
File "adafruit_requests.py", line 711, in get
File "adafruit_requests.py", line 671, in request
OutOfRetries: Repeated socket failures but I've repurposed the I have not done any actual power usage testing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original issue with more aggressive power management on Pico W in #6958 was [Errno 2] No such file/directory
, typically after about a 5 minute interval between network transactions, requiring a reset to recover. The wifi connection to the AP was not lost.
I have not seen that behavior on either espressif
or raspberrypi
port, using any of the new power management settings (NONE
, MIN
, MAX
) running overnight, with intervals between requests of 40 minutes and more. Also no wifi disconnections at all.
Trying to reproduce the original issue on Pico W, using the deprecated cyw43
power management values of 0x111022
and 0xa11c82
:
-
0xa11c82
: A single test ran with 20-minute interval between requests without issue. -
0x111022
: One test got repeatedgaierror: (-2, 'Name or service not known')
after hitting the 22 minute interval between requests. Not sure if that is related. A second test ran fine with over 40 minute interval between requests.
In any case, no regressions were found with the new values, indicating to me that this is a relatively safe change. Users can turn off power management if the default isn't getting them the results they want (or change it to MAX
). And advanced users on Pico W can tweak the detailed values using cyw43
if they wish.
@anecdata thank you for the testing! I'm marking this ready for review now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Thank you.
wifi.radio.listen_interval
was inadvertently not added when #9476 was merged. Instead of fixing that directly, I've redone wifi power management so the same API can be used for both Espressif and CYW43 (Pico W et al).The old
cyw43
API is still available, but now there a propertywifi.radio.power_management
which can take valueswifi.PowerManagement.{MIN,MAX,NONE}
. On CYW43, these correspond to the "PERFORMANCE", "AGGRESSIVE", and "DISABLED" CYW43-specific values. The default value isMIN
.I also corrected the current CYW43 values, which hadn't yet incorporated the upstream fixes in georgerobotics/cyw43-driver#126.
Because of all these changes, it would be good to re-test these various power-savings modes, as discussed in #10170. @anecdata, when you have time, could you test build artifacts from this PR, against the performance tests you used in the past for these kinds of settings? Thank you. I will make it draft for now. If anyone else is interested in testing, that would be great?
I did wifi smoke tests (pings and HTTP and HTTPS fetches on ESP32-S3 and Pico W with all the different power-management settings.