From 17dfe7e9054c7c246361193a9898b89b4d4e6606 Mon Sep 17 00:00:00 2001 From: Tobias Leuschner Date: Sun, 17 May 2026 17:34:28 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Verbesserung=20der=20WLAN-Verwaltung=20?= =?UTF-8?q?durch=20Deaktivierung=20von=20Autoconnect=20f=C3=BCr=20Fremdpro?= =?UTF-8?q?file=20und=20Anpassung=20der=20Wartezeit=20auf=20NetworkManager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- picopy/wifi.py | 54 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/picopy/wifi.py b/picopy/wifi.py index 5b062a4..2d2812b 100644 --- a/picopy/wifi.py +++ b/picopy/wifi.py @@ -5,7 +5,7 @@ import threading import time from picopy.config import ( - NM_AP_CON, NM_CLIENT_CON, WIFI_BOOT_WAIT, + NM_AP_CON, NM_CLIENT_CON, load_cfg, log ) @@ -81,6 +81,17 @@ def stop_ap(): nm('con', 'down', NM_AP_CON) +def _takeover_wifi_autoconnect(): + """Deaktiviert Autoconnect aller Fremd-WLAN-Profile, damit NM beim Boot PiCopy-WiFi bevorzugt.""" + r = nm('-t', '-f', 'NAME,TYPE', 'con', 'show') + for line in r.stdout.splitlines(): + parts = line.split(':', 1) + if len(parts) == 2 and parts[1] == '802-11-wireless' and parts[0] not in (NM_CLIENT_CON, NM_AP_CON): + nm('con', 'mod', parts[0], 'connection.autoconnect', 'no') + log.info(f'Autoconnect für Fremdprofil deaktiviert: {parts[0]}') + nm('con', 'mod', NM_CLIENT_CON, 'connection.autoconnect', 'yes') + + def connect_client_wifi(ssid, password): log.info(f'Verbinde mit WiFi: {ssid}') nm('con', 'delete', NM_CLIENT_CON) @@ -98,6 +109,7 @@ def connect_client_wifi(ssid, password): ok = r.returncode == 0 if ok: log.info(f'Verbunden mit {ssid}') + _takeover_wifi_autoconnect() else: log.error(f'WiFi-Verbindung fehlgeschlagen: {r.stderr.strip()}') return ok @@ -139,19 +151,49 @@ def update_wifi_state(): wifi_state.update(mode='disconnected', ssid='', ip='') +def _wait_for_nm(max_wait: int = 30) -> None: + """Wartet bis NetworkManager bereit ist, statt eine feste Zeit zu schlafen.""" + for i in range(max_wait): + r = nm('general', 'status') + if r.returncode == 0: + if i > 0: + log.info(f'NetworkManager bereit nach {i}s') + return + time.sleep(1) + log.warning('NetworkManager nach 30s noch nicht bereit') + + def wifi_monitor(): - log.info(f'WiFi-Monitor: warte {WIFI_BOOT_WAIT}s auf Verbindung...') - time.sleep(WIFI_BOOT_WAIT) + log.info('WiFi-Monitor: warte auf NetworkManager...') + _wait_for_nm() + + first_run = True while True: try: update_wifi_state() with wifi_lock: mode = wifi_state['mode'] + current_conn = wifi_state.get('ssid', '') + + cfg = load_cfg() + picopy_ssid = cfg.get('wifi_ssid', '') + + # Beim ersten Durchlauf: falls ein Fremdprofil (Imager) verbunden ist + # und PiCopy eine eigene SSID kennt → zu PiCopy-WiFi wechseln + if first_run and mode == 'client' and current_conn != NM_CLIENT_CON and picopy_ssid: + log.info(f'Fremdprofil aktiv ({current_conn}), wechsle zu PiCopy-WiFi ({picopy_ssid})...') + connected = connect_client_wifi(picopy_ssid, cfg.get('wifi_password', '')) + if connected: + time.sleep(5) + update_wifi_state() + with wifi_lock: + mode = wifi_state['mode'] + + first_run = False if mode == 'disconnected': - cfg = load_cfg() - ssid = cfg.get('wifi_ssid', '') + ssid = picopy_ssid pw = cfg.get('wifi_password', '') connected = False @@ -163,7 +205,7 @@ def wifi_monitor(): if not connected: ap_ssid = cfg.get('ap_ssid', 'PiCopy') - ap_pw = cfg.get('ap_password', 'PiCopy,') + ap_pw = cfg.get('ap_password', 'PiCopy123') if start_ap(ap_ssid, ap_pw): time.sleep(3) with wifi_lock: