feat: Fehlerbehandlung für WiFi-Verbindungen verbessert und Fallback-AP-Start optimiert; Versionsnummer auf 1.0.77 erhöht
This commit is contained in:
25
app.py
25
app.py
@@ -1,14 +1,24 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""PiCopy v2 - USB Copy Service mit WiFi-Fallback AP"""
|
"""PiCopy v2 - USB Copy Service mit WiFi-Fallback AP"""
|
||||||
|
|
||||||
|
import traceback
|
||||||
import urllib.request as _urlreq
|
import urllib.request as _urlreq
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from flask import Flask, render_template, send_file
|
from flask import Flask, render_template, send_file, jsonify
|
||||||
|
|
||||||
from picopy.config import VERSION, BASE_DIR, RAW_BASE
|
from picopy.config import VERSION, BASE_DIR, RAW_BASE, log
|
||||||
|
|
||||||
|
# Absoluter Pfad zum templates/-Verzeichnis, unabhängig vom Arbeitsverzeichnis
|
||||||
|
_HERE = Path(__file__).parent
|
||||||
|
app = Flask(__name__, template_folder=str(_HERE / 'templates'))
|
||||||
|
|
||||||
|
|
||||||
|
@app.errorhandler(Exception)
|
||||||
|
def _handle_exception(e):
|
||||||
|
log.error('Unbehandelter Fehler:\n' + traceback.format_exc())
|
||||||
|
return jsonify(error=str(e)), 500
|
||||||
|
|
||||||
app = Flask(__name__, template_folder='templates')
|
|
||||||
|
|
||||||
from routes import register_routes
|
from routes import register_routes
|
||||||
register_routes(app)
|
register_routes(app)
|
||||||
@@ -49,7 +59,14 @@ if __name__ == '__main__':
|
|||||||
from picopy.wifi import wifi_monitor
|
from picopy.wifi import wifi_monitor
|
||||||
from picopy.wireguard import wg_monitor
|
from picopy.wireguard import wg_monitor
|
||||||
from picopy.system import update_check_loop
|
from picopy.system import update_check_loop
|
||||||
from picopy.config import log, load_cfg
|
from picopy.config import load_cfg
|
||||||
|
|
||||||
|
# Startprüfung: Template vorhanden?
|
||||||
|
tmpl = _HERE / 'templates' / 'index.html'
|
||||||
|
if not tmpl.exists():
|
||||||
|
log.error(f'FEHLER: Template nicht gefunden: {tmpl}')
|
||||||
|
else:
|
||||||
|
log.info(f'Template gefunden: {tmpl}')
|
||||||
|
|
||||||
cleanup_stale_mounts()
|
cleanup_stale_mounts()
|
||||||
load_state()
|
load_state()
|
||||||
|
|||||||
@@ -95,12 +95,18 @@ 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)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
|
# Scan erzwingen – sonst findet nmcli das Netz nach dem Boot nicht im Cache
|
||||||
|
log.info('WiFi-Scan läuft...')
|
||||||
|
nm('dev', 'wifi', 'rescan')
|
||||||
|
time.sleep(4)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# --wait 15: nmcli gibt nach 15 s auf; subprocess-Timeout als Sicherheitsnetz
|
# --wait 45: genug Zeit für Scan + WPA-Handshake + DHCP
|
||||||
r = subprocess.run(
|
r = subprocess.run(
|
||||||
['nmcli', '--wait', '15', 'dev', 'wifi', 'connect', ssid,
|
['nmcli', '--wait', '45', 'dev', 'wifi', 'connect', ssid,
|
||||||
'password', password, 'name', NM_CLIENT_CON, 'ifname', 'wlan0'],
|
'password', password, 'name', NM_CLIENT_CON, 'ifname', 'wlan0'],
|
||||||
capture_output=True, text=True, timeout=25,
|
capture_output=True, text=True, timeout=55,
|
||||||
)
|
)
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
log.warning(f'WiFi-Verbindung Timeout (SSID: {ssid})')
|
log.warning(f'WiFi-Verbindung Timeout (SSID: {ssid})')
|
||||||
@@ -166,6 +172,8 @@ def wifi_monitor():
|
|||||||
_wait_for_nm()
|
_wait_for_nm()
|
||||||
_purge_foreign_wifi_profiles()
|
_purge_foreign_wifi_profiles()
|
||||||
|
|
||||||
|
connect_failures = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
update_wifi_state()
|
update_wifi_state()
|
||||||
@@ -173,22 +181,31 @@ def wifi_monitor():
|
|||||||
mode = wifi_state['mode']
|
mode = wifi_state['mode']
|
||||||
|
|
||||||
cfg = load_cfg()
|
cfg = load_cfg()
|
||||||
|
|
||||||
if mode == 'disconnected':
|
|
||||||
ssid = cfg.get('wifi_ssid', '')
|
ssid = cfg.get('wifi_ssid', '')
|
||||||
pw = cfg.get('wifi_password', '')
|
pw = cfg.get('wifi_password', '')
|
||||||
|
|
||||||
|
if mode == 'client':
|
||||||
|
connect_failures = 0 # Verbindung OK – Zähler zurücksetzen
|
||||||
|
|
||||||
|
elif mode == 'disconnected':
|
||||||
connected = False
|
connected = False
|
||||||
if ssid:
|
if ssid:
|
||||||
|
log.info(f'Verbindungsversuch {connect_failures + 1}: {ssid}')
|
||||||
connected = connect_client_wifi(ssid, pw)
|
connected = connect_client_wifi(ssid, pw)
|
||||||
if connected:
|
if connected:
|
||||||
|
connect_failures = 0
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
update_wifi_state()
|
update_wifi_state()
|
||||||
|
else:
|
||||||
|
connect_failures += 1
|
||||||
|
|
||||||
if not connected:
|
# AP erst starten wenn kein SSID konfiguriert ODER nach 2 Fehlversuchen
|
||||||
|
if not connected and (not ssid or connect_failures >= 2):
|
||||||
ap_ssid = cfg.get('ap_ssid', 'PiCopy')
|
ap_ssid = cfg.get('ap_ssid', 'PiCopy')
|
||||||
ap_pw = cfg.get('ap_password', 'PiCopy123')
|
ap_pw = cfg.get('ap_password', 'PiCopy123')
|
||||||
|
log.info(f'Starte Fallback-AP nach {connect_failures} Fehlversuchen')
|
||||||
if start_ap(ap_ssid, ap_pw):
|
if start_ap(ap_ssid, ap_pw):
|
||||||
|
connect_failures = 0
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
with wifi_lock:
|
with wifi_lock:
|
||||||
wifi_state.update(mode='ap', ssid=ap_ssid, ip='10.42.0.1')
|
wifi_state.update(mode='ap', ssid=ap_ssid, ip='10.42.0.1')
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ def r_wifi_connect():
|
|||||||
update_wifi_state()
|
update_wifi_state()
|
||||||
else:
|
else:
|
||||||
if ap_was_active:
|
if ap_was_active:
|
||||||
start_ap(cfg.get('ap_ssid', 'PiCopy'), cfg.get('ap_password', 'PiCopy,'))
|
start_ap(cfg.get('ap_ssid', 'PiCopy'), cfg.get('ap_password', 'PiCopy123'))
|
||||||
update_wifi_state()
|
update_wifi_state()
|
||||||
|
|
||||||
threading.Thread(target=_connect, daemon=True).start()
|
threading.Thread(target=_connect, daemon=True).start()
|
||||||
|
|||||||
Reference in New Issue
Block a user