Admin WiFi : scan réseaux, connexion, mots de passe mémorisés

- Module backend/wifi.py : scan nmcli, connexion, mots de passe persistés dans data/wifi_passwords.json
- Gère la locale FR (oui/non), déduplique les AP multiples, prend le meilleur signal
- Onglet WiFi dans le menu admin avec statut, scan, clavier virtuel AZERTY complet
- Réseaux enregistrés avec bouton connecter/oublier et affichage temporaire du mdp
- API: /api/wifi/status, /api/wifi/scan, /api/wifi/connect, /api/wifi/saved, /api/wifi/password/{ssid}

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 19:29:12 +02:00
parent 4e431507fc
commit 8dabba65bb
5 changed files with 647 additions and 2 deletions

View File

@@ -38,6 +38,7 @@ from backend.evenements import (
)
from backend.evenements import DOSSIER_EVENEMENTS
from backend.eclairage import analyser_frame as analyser_eclairage, dernier_resultat as dernier_eclairage
from backend.wifi import wifi_status, wifi_scan, wifi_connect, wifi_saved_list, wifi_forget, wifi_get_password
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(name)s] %(message)s")
log = logging.getLogger("photobooth")
@@ -1402,6 +1403,48 @@ async def api_quitter_navigateur():
return {"succes": True}
# --- API WiFi ---
@app.get("/api/wifi/status")
async def api_wifi_status():
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, wifi_status)
@app.get("/api/wifi/scan")
async def api_wifi_scan():
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, wifi_scan)
@app.post("/api/wifi/connect")
async def api_wifi_connect(donnees: dict):
ssid = donnees.get("ssid", "")
password = donnees.get("password")
if not ssid:
return JSONResponse({"erreur": "SSID requis"}, status_code=400)
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, wifi_connect, ssid, password)
@app.get("/api/wifi/saved")
async def api_wifi_saved():
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, wifi_saved_list)
@app.delete("/api/wifi/saved/{ssid}")
async def api_wifi_forget(ssid: str):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, wifi_forget, ssid)
@app.get("/api/wifi/password/{ssid}")
async def api_wifi_password(ssid: str):
mdp = wifi_get_password(ssid)
return {"ssid": ssid, "password": mdp}
# --- WebSocket ---
@app.websocket("/ws")