← index #17339PR #3937
Related · high · value 0.412
QUERY · ISSUE

sta_if.status() unreliable

openby robtinkersopened 2025-05-22updated 2026-03-16
bugport-esp32

Port, board and/or hardware

esp32 port

MicroPython version

MicroPython v1.25.0 on 2025-04-15; Generic ESP32 module with ESP32

Reproduction

import network, time
from sys import print_exception

REAL_SSID = 'MyNetwork'
REAL_PASS = 'MyPassword'

NETWORKS = (('FakeNetwork1', '12345678'), (REAL_SSID, REAL_PASS), ('FakeNetwork2', '12345678'), ('FakeNetwork3', '12345678'))

STATUS_LOOKUP = {
    network.STAT_ASSOC_FAIL: 'ASSOC_FAIL',
    network.STAT_BEACON_TIMEOUT: 'BEACON_TIMEOUT',
    network.STAT_CONNECTING: 'CONNECTING',
    network.STAT_CONNECT_FAIL: 'CONNECT_FAIL',
    network.STAT_GOT_IP: 'GOT_IP',
    network.STAT_HANDSHAKE_TIMEOUT: 'HANDSHAKE_TIMEOUT',
    network.STAT_IDLE: 'IDLE',
    network.STAT_NO_AP_FOUND: 'NO_AP_FOUND',
    network.STAT_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD: 'NO_AP_FOUND_IN_AUTHMODE_THRESHOLD',
    network.STAT_NO_AP_FOUND_IN_RSSI_THRESHOLD: 'NO_AP_FOUND_IN_RSSI_THRESHOLD',
    network.STAT_NO_AP_FOUND_W_COMPATIBLE_SECURITY: 'NO_AP_FOUND_W_COMPATIBLE_SECURITY',
    network.STAT_WRONG_PASSWORD: 'WRONG_PASSWORD',
}

def print_status_loop(interface, duration):
    old_status = None
    t0 = time.ticks_ms()
    while True:
        tt = time.ticks_diff(time.ticks_ms(), t0)
        if tt > duration * 1000:
            break
        status = interface.status()
        if old_status != status:
            old_status = status
            print(tt, STATUS_LOOKUP.get(status, str(status)))

sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)

for network in NETWORKS:
    print( '======== disconnect()')
    try: sta_if.disconnect()
    except Exception as e: print_exception(e)
    print_status_loop(sta_if, 5)
    print(f'======== connect({network[0]}, ...)')
    sta_if.connect(*network)
    print_status_loop(sta_if, 5)

Expected behaviour

I would expect the connect() call to reliably initialise the status to something (CONNECTING?)

I would expect the disconnect() call to reliably set the status to something (IDLE?)

Observed behaviour

connect() only works as I expect if the previous connect() call eventually GOT_IP, but not otherwise.

disconnect() almost works as I expect if the previous connect() call eventually GOT_IP, but not otherwise.

======== disconnect()
0 IDLE
======== connect(FakeNetwork1, ...)
0 CONNECTING
2417 NO_AP_FOUND
======== disconnect()
0 NO_AP_FOUND
======== connect(MyNetwork, ...)
0 NO_AP_FOUND
1398 GOT_IP
======== disconnect()
0 GOT_IP
1 IDLE
======== connect(FakeNetwork2, ...)
0 IDLE
2417 NO_AP_FOUND
======== disconnect()
0 NO_AP_FOUND
======== connect(FakeNetwork3, ...)
0 NO_AP_FOUND

Additional Information

I would like to loop through a bunch of pre-configured wifi networks to find one that works (e.g. for a portable device).

Unfortunately if a .connect() call doesn't eventually connect (the usual case in my scenario), then polling .status() becomes unreliable and I have to guess an appropriate timer and wait for .isconnected() for each ssid/pass, significantly slowing down startup if the working network is down the list.

Code of Conduct

Yes, I agree

CANDIDATE · PULL REQUEST

Implement status() for ESP32 STA_IF Resolves #3913

closedby mitchinsopened 2018-07-11updated 2018-07-13

Implements the default method (no args) which provides the link status for the STA_IF on ESP32 devices.

Implementation is inspired and consistent with ESP8266, success codes are named similarly, as are most error names. Error codes and names for wifi disconnect are otherwise taken (returned directly) from what the ESP-IDF gives us but are defined in the const dictionary where appropriate.

Success codes are number from 1000 upwards so as not to clash with the 8-bit error codes from ESP-IDF.

Tested connection. failure and success on Wemos R32 device, it seems to return as expected.

wifi_log.txt

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied