feat: Verbesserung der WLAN-Verwaltung durch Deaktivierung von Autoconnect für Fremdprofile und Anpassung der Wartezeit auf NetworkManager

This commit is contained in:
2026-05-17 17:34:28 +02:00
parent e3e1c11a8a
commit 17dfe7e905

View File

@@ -5,7 +5,7 @@ import threading
import time import time
from picopy.config import ( from picopy.config import (
NM_AP_CON, NM_CLIENT_CON, WIFI_BOOT_WAIT, NM_AP_CON, NM_CLIENT_CON,
load_cfg, log load_cfg, log
) )
@@ -81,6 +81,17 @@ def stop_ap():
nm('con', 'down', NM_AP_CON) 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): def connect_client_wifi(ssid, password):
log.info(f'Verbinde mit WiFi: {ssid}') log.info(f'Verbinde mit WiFi: {ssid}')
nm('con', 'delete', NM_CLIENT_CON) nm('con', 'delete', NM_CLIENT_CON)
@@ -98,6 +109,7 @@ def connect_client_wifi(ssid, password):
ok = r.returncode == 0 ok = r.returncode == 0
if ok: if ok:
log.info(f'Verbunden mit {ssid}') log.info(f'Verbunden mit {ssid}')
_takeover_wifi_autoconnect()
else: else:
log.error(f'WiFi-Verbindung fehlgeschlagen: {r.stderr.strip()}') log.error(f'WiFi-Verbindung fehlgeschlagen: {r.stderr.strip()}')
return ok return ok
@@ -139,19 +151,49 @@ def update_wifi_state():
wifi_state.update(mode='disconnected', ssid='', ip='') 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(): def wifi_monitor():
log.info(f'WiFi-Monitor: warte {WIFI_BOOT_WAIT}s auf Verbindung...') log.info('WiFi-Monitor: warte auf NetworkManager...')
time.sleep(WIFI_BOOT_WAIT) _wait_for_nm()
first_run = True
while True: while True:
try: try:
update_wifi_state() update_wifi_state()
with wifi_lock: with wifi_lock:
mode = wifi_state['mode'] 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': if mode == 'disconnected':
cfg = load_cfg() ssid = picopy_ssid
ssid = cfg.get('wifi_ssid', '')
pw = cfg.get('wifi_password', '') pw = cfg.get('wifi_password', '')
connected = False connected = False
@@ -163,7 +205,7 @@ def wifi_monitor():
if not connected: if not connected:
ap_ssid = cfg.get('ap_ssid', 'PiCopy') 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): if start_ap(ap_ssid, ap_pw):
time.sleep(3) time.sleep(3)
with wifi_lock: with wifi_lock: