Files
2026-03-11 23:03:02 +01:00

202 lines
6.1 KiB
Python

## -*- coding: utf-8 -*-
# wifi_manager.py
# GNU GENERAL PUBLIC LICENSE: (c) DD miraceti.net
import utime as time # @UnresolvedImport
import ubinascii # @UnresolvedImport
import network # @UnresolvedImport
'''
Management de la WiFi pour ESP32 (MicroPython).
Usage:
SSID = "ssid_8chars"
PASSWORD = "ChangeMeSoon"
if __name__ == "__main__":
try:
WiFi = WifiManager(mode='AP')
wifi = WiFi(SSID, PASSWORD)
wifi.start()
n=0
while True:
time.sleep(5.0)
print(n, wifi.status())
n += 1
except KeyboardInterrupt:
pass
finally:
wifi.stop()
print("Arrêt")
'''
class WifiBase:
ssid = None
password = None
channel = 1
hidden = False
max_clients = 4
authmode = 3
_iface= None
_mode='AP'
wifi_delay = 1.5
def start(self):
pass
def stop(self):
pass
def status(self):
pass
def restart(self):
if_was = self._iface.active()
self._iface.active(False)
time.sleep(self.wifi_delay)
if if_was:
self._iface.active(True)
return self.status()
def get_ip(self):
return self._iface.ifconfig()[0] if self._iface.active() else None
def get_ssid(self):
return self._iface.config('essid') if self._iface.active() else None
def get_rssi(self):
return self._iface.status('rssi') if self._iface.isconnected() else None
def get_iface(self):
return self._mode
class APManager(WifiBase):
"""
Gestion WiFi pour ESP32 (MicroPython).
Arguments (tous optionnels selon le mode) :
ssid (str) : nom du réseau AP ou SSID à rejoindre
password (str) : mot de passe AP ou STA (min 8 chars si authmode != 0)
channel (int) : canal pour AP (1-13)
hidden (bool) : AP caché ou non
max_clients (int) : nombre max de clients en AP
authmode (int) : 0=OPEN,1=WEP,2=WPAPSK,3=WPAPSK/SAE,4=SAEs
timeout_connect: délai pour connecter
"""
def __init__(self, ssid=None, password=None, channel=1, hidden=False,
max_clients=4, authmode=3, timeout_connect=15):
self.ssid = ssid or b"ESP32-" + ubinascii.hexlify(self._iface.config('mac')[-3:]).decode()
self.password = password or ''
self.channel = channel if 1 <= channel <= 13 else 1
self.hidden = bool(hidden)
self.max_clients = max_clients if max_clients > 0 else 4
self.authmode = authmode
self.timeout_connect = timeout_connect
self._iface= network.WLAN(network.AP_IF)
self._mode = 'AP'
def start(self):
if not self._iface.active():
self._iface.active(True)
cfg_auth = 0 if not self.password else self.authmode
try:
self._iface.config(essid=self.ssid, password=self.password, authmode=cfg_auth,
channel=self.channel, hidden=self.hidden, max_clients=self.max_clients)
except Exception as e:
print("start error", e)
return False
time.sleep(self.wifi_delay)
print("Démarrage de la wifi:", self.status())
return True
def stop(self):
if self._iface.active():
self._iface.active(False)
print("Déconnexion de la wifi:", self.status())
def status(self):
return {
'iface': self.get_iface(),
'active': self._iface.active(),
'ssid': self.get_ssid(),
'ip': self.get_ip(),
}
class STAManager(WifiBase):
"""
Gestion WiFi pour ESP32 (MicroPython).
Arguments (tous optionnels selon le mode) :
ssid (str) : nom du réseau AP ou SSID à rejoindre
password (str) : mot de passe AP ou STA (min 8 chars si authmode != 0)
authmode (int) : 0=OPEN,1=WEP,2=WPAPSK,3=WPAPSK/SAE,4=SAEs
timeout_connect: délai pour connecter
"""
def __init__(self, ssid=None, password=None, authmode=3, timeout_connect=10):
self.ssid = ssid
self.password = password
self.authmode = authmode
self.timeout_connect = timeout_connect
self._iface= network.WLAN(network.STA_IF)
self._mode = 'STA'
def start(self):
try:
if not self.ssid:
raise ValueError("SSID requis pour le mode STA")
if self.password and len(self.password) < 8:
raise ValueError("Mot de passe WPA/WPA2 doit faire >=8 caractères")
#self._iface.disconnect()
self._iface.active(False)
time.sleep(self.wifi_delay)
self._iface.active(True)
self._iface.connect(self.ssid, self.password)
t0 = time.time()
wait, n = 0.1, 0
print('Tentative de connexion au réseau...')
while not self._iface.isconnected():
time.sleep(wait)
wait = min(0.5, wait + 0.05)
n+=1
print(n, '> Essai de connexion...', 'status>', self._iface.status())
if (time.time() - t0) > self.timeout_connect:
raise Exception('Timeout connexion atteint') # @UndefinedVariable
time.sleep(self.wifi_delay)
print("Démarrage de la wifi:", self.status())
return True
except Exception as e:
print(f"STA connect() raised: {e}")
return False
def stop(self):
if self._iface.isconnected():
try:
self._iface.disconnect()
except Exception:
pass
print("Déconnexion de la wifi", self.status())
def status(self):
return {
'iface': self.get_iface(),
'active': self._iface.active(),
'connected': self._iface.isconnected(),
'ip': self.get_ip(),
'rssi': self.get_rssi()
}
def WifiManager(mode='AP'):
return APManager if mode == 'AP' else STAManager