diff --git a/app.py b/app.py index 61f039a..5ab0e93 100644 --- a/app.py +++ b/app.py @@ -33,6 +33,50 @@ current_hub: MouldKing | None = None current_module = None # Module6_0 oder Module4_0 current_device = None # Device0/1/2 je nach hub_id +import threading +import time + +# Globale Variable für den letzten erfolgreichen Check (optional) +last_successful_check = time.time() + +def connection_monitor(): + """Background-Thread: Prüft alle 5 Sekunden, ob der Hub noch antwortet""" + global current_device, current_module, current_hub, last_successful_check + + while True: + if current_device is not None: + try: + # Harter Test: Kanal 0 kurz auf 0.1 und zurück auf 0.0 setzen + current_device.SetChannel(0, 0.1) + time.sleep(0.05) # winzige Pause + current_device.SetChannel(0, 0.0) + + last_successful_check = time.time() + logger.debug("Monitor: Hub antwortet → SetChannel-Test OK") + + except Exception as e: + logger.warning(f"Monitor: Hub scheint weg zu sein: {str(e)}") + + # Sauber trennen + try: + current_device.Disconnect() + except: + pass + + current_device = None + current_module = None + current_hub = None + + # Optional: Frontend benachrichtigen (z. B. über WebSocket später) + + time.sleep(5) # Prüfintervall: 5 Sekunden + +# Thread starten (daemon=True → beendet sich mit der App) +monitor_thread = threading.Thread(target=connection_monitor, daemon=True) +monitor_thread.start() + +logger.info("Background-Monitor für Hub-Verbindung gestartet") + def load_configs(): configs = [] for filename in os.listdir(app.config['CONFIG_DIR']): @@ -254,40 +298,17 @@ def api_connect(): @app.route('/api/status', methods=['GET']) def api_status(): - global current_device, current_module, current_hub - - if current_device is None: - logger.debug("Status-Check: Kein Device aktiv") - return jsonify({"connected": False, "message": "Keine aktive Verbindung"}), 200 - - try: - # Harter Test: Setze Kanal 0 (A) kurz auf 0.1 und sofort zurück auf 0.0 - # Das ist fast unsichtbar (nur ein minimaler Impuls), aber zwingt den Hub zu reagieren - current_device.SetChannel(0, 0.1) - current_device.SetChannel(0, 0.0) - - logger.debug("Status-Check: Harter Test (SetChannel 0.1 → 0.0) erfolgreich → Hub lebt") + global current_device + + if current_device is not None: return jsonify({ "connected": True, "message": "Verbunden" }) - - except Exception as e: - logger.warning(f"Status-Check: Harter Test fehlgeschlagen → Hub wahrscheinlich weg: {str(e)}") - - # Sauber aufräumen - try: - current_device.Disconnect() - except: - pass - - current_device = None - current_module = None - current_hub = None - + else: return jsonify({ "connected": False, - "message": f"Hub reagiert nicht mehr: {str(e)}" + "message": "Keine aktive Verbindung" }), 200 diff --git a/static/js/app.js b/static/js/app.js index 4dd86b0..231d1ac 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -295,18 +295,17 @@ document.addEventListener('DOMContentLoaded', () => { const statusBadge = document.getElementById('connection-status'); function updateStatus(connected, message = '') { - if (!statusBadge) return; + if (!statusBadge) return; - if (connected) { - statusBadge.className = 'badge bg-success px-3 py-2 fs-6'; - statusBadge.innerHTML = ' Verbunden' + (message ? ` – ${message}` : ''); - if (reconnectSection) reconnectSection.style.display = 'none'; - } else { - statusBadge.className = 'badge bg-danger px-3 py-2 fs-6'; - statusBadge.innerHTML = ' Getrennt' + (message ? ` – ${message}` : ''); - showReconnect(); - } + if (connected) { + statusBadge.className = 'badge bg-success px-3 py-2 fs-6'; + statusBadge.innerHTML = ' Verbunden'; + } else { + statusBadge.className = 'badge bg-danger px-3 py-2 fs-6'; + statusBadge.innerHTML = ' Getrennt' + (message ? ` – ${message}` : ''); + showReconnect(); } +} // Initialer Status updateStatus(false);