From 00c3251b9618e6457eccfc7b4d762bde4b9a88d0 Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Thu, 29 May 2025 23:24:13 +0200 Subject: [PATCH] "Refactor job scheduling and printer monitoring" --- backend/app/app.py | 52 ++++++++++------------------ backend/app/utils/job_scheduler.py | 37 ++++++++++++-------- backend/app/utils/printer_monitor.py | 26 +++++++------- 3 files changed, 53 insertions(+), 62 deletions(-) diff --git a/backend/app/app.py b/backend/app/app.py index 8cf1a44a..6004d715 100644 --- a/backend/app/app.py +++ b/backend/app/app.py @@ -1283,8 +1283,10 @@ def kiosk_restart_system(): @measure_execution_time(logger=printers_logger, task_name="Drucker-Status-Prüfung") def check_printer_status(ip_address: str, timeout: int = 7) -> Tuple[str, bool]: """ - Überprüft den Status eines Druckers anhand der IP-Adresse. - Gibt den Status und die Erreichbarkeit zurück. + Überprüft den Status eines Druckers anhand der Steckdosen-Logik: + - Steckdose erreichbar aber AUS = Drucker ONLINE (bereit zum Drucken) + - Steckdose erreichbar und AN = Drucker PRINTING (druckt gerade) + - Steckdose nicht erreichbar = Drucker OFFLINE (kritischer Fehler) Args: ip_address: IP-Adresse des Druckers oder der Steckdose @@ -1297,7 +1299,7 @@ def check_printer_status(ip_address: str, timeout: int = 7) -> Tuple[str, bool]: reachable = False try: - # Überprüfen, ob die Steckdose online ist + # Überprüfen, ob die Steckdose erreichbar ist import socket # Erst Port 9999 versuchen (Tapo-Standard) @@ -1318,48 +1320,30 @@ def check_printer_status(ip_address: str, timeout: int = 7) -> Tuple[str, bool]: # Geräteinformationen abrufen device_info = p100.getDeviceInfo() - # Status auswerten + # 🎯 KORREKTE LOGIK: Status auswerten if device_info.get('device_on', False): - status = "online" + # Steckdose an = Drucker PRINTING (druckt gerade) + status = "printing" + printers_logger.info(f"🖨️ Drucker {ip_address}: PRINTING (Steckdose an - druckt gerade)") else: - status = "standby" + # Steckdose aus = Drucker ONLINE (bereit zum Drucken) + status = "online" + printers_logger.info(f"✅ Drucker {ip_address}: ONLINE (Steckdose aus - bereit zum Drucken)") - printers_logger.info(f"✅ Tapo-Steckdose {ip_address}: Status = {status}") except Exception as e: printers_logger.error(f"❌ Fehler bei Tapo-Status-Check für {ip_address}: {str(e)}") reachable = False status = "error" else: - # Alternativ HTTP/HTTPS versuchen - try: - # HTTP auf Port 80 - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.settimeout(timeout) - result = sock.connect_ex((ip_address, 80)) - sock.close() + # Steckdose nicht erreichbar = kritischer Fehler + printers_logger.warning(f"❌ Drucker {ip_address}: OFFLINE (Steckdose nicht erreichbar)") + reachable = False + status = "offline" - if result == 0: - reachable = True - status = "online" # Standarddrucker ohne Tapo-Steckdose - else: - # HTTPS auf Port 443 - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.settimeout(timeout) - result = sock.connect_ex((ip_address, 443)) - sock.close() - - if result == 0: - reachable = True - status = "online" - except Exception as e: - printers_logger.error(f"❌ Fehler bei Socket-Check für {ip_address}: {str(e)}") - reachable = False - status = "error" - except Exception as e: - printers_logger.error(f"❌ Fehler bei Verbindungsprüfung zu {ip_address}: {str(e)}") - status = "error" + printers_logger.error(f"❌ Unerwarteter Fehler bei Status-Check für {ip_address}: {str(e)}") reachable = False + status = "error" return status, reachable diff --git a/backend/app/utils/job_scheduler.py b/backend/app/utils/job_scheduler.py index 8cb90cd7..c35a3d64 100644 --- a/backend/app/utils/job_scheduler.py +++ b/backend/app/utils/job_scheduler.py @@ -293,8 +293,8 @@ class BackgroundTaskScheduler: Args: ip: IP-Adresse der Steckdose state: True = Ein, False = Aus - username: Benutzername für die Steckdose (optional) - password: Passwort für die Steckdose (optional) + username: Benutzername für die Steckdose (wird überschrieben mit globalen Credentials) + password: Passwort für die Steckdose (wird überschrieben mit globalen Credentials) Returns: bool: True wenn erfolgreich geschaltet @@ -307,12 +307,11 @@ class BackgroundTaskScheduler: self.logger.error("❌ PyP100-Modul nicht installiert - Steckdose kann nicht geschaltet werden") return False - # Anmeldedaten aus Einstellungen verwenden, falls nicht angegeben - if not username or not password: - from config.settings import TAPO_USERNAME, TAPO_PASSWORD - username = TAPO_USERNAME - password = TAPO_PASSWORD - self.logger.debug(f"🔧 Verwende globale Tapo-Anmeldedaten für {ip}") + # IMMER globale Anmeldedaten verwenden (da diese funktionieren) + from config.settings import TAPO_USERNAME, TAPO_PASSWORD + username = TAPO_USERNAME + password = TAPO_PASSWORD + self.logger.debug(f"🔧 Verwende globale Tapo-Anmeldedaten für {ip}") # P100-Verbindung herstellen (P100 statt P110 verwenden) p100 = PyP100.P100(ip, username, password) @@ -338,7 +337,9 @@ class BackgroundTaskScheduler: def toggle_printer_plug(self, printer_id: int, state: bool) -> bool: """ - Schaltet die Steckdose eines Druckers ein oder aus. + Schaltet die Steckdose eines Druckers ein oder aus mit korrektem Status-Mapping: + - Steckdose AUS = Drucker ONLINE (bereit zum Drucken) + - Steckdose AN = Drucker PRINTING (druckt gerade) Args: printer_id: ID des Druckers @@ -367,16 +368,24 @@ class BackgroundTaskScheduler: success = self.toggle_plug( ip=printer.plug_ip, state=state, - username=printer.plug_username, - password=printer.plug_password + username=printer.plug_username, # Wird überschrieben mit globalen Credentials + password=printer.plug_password # Wird überschrieben mit globalen Credentials ) if success: - # Status in Datenbank aktualisieren - printer.status = "online" if state else "offline" + # Status in Datenbank aktualisieren entsprechend der neuen Logik + if state: + # Steckdose eingeschaltet = Drucker druckt + printer.status = "printing" + self.logger.info(f"🖨️ Drucker {printer.name}: Status auf 'printing' gesetzt (Steckdose eingeschaltet)") + else: + # Steckdose ausgeschaltet = Drucker bereit + printer.status = "online" + self.logger.info(f"✅ Drucker {printer.name}: Status auf 'online' gesetzt (Steckdose ausgeschaltet - bereit)") + printer.last_checked = datetime.now() db_session.commit() - self.logger.info(f"✅ Status für Drucker {printer.name} aktualisiert: {'online' if state else 'offline'}") + self.logger.info(f"✅ Status für Drucker {printer.name} erfolgreich aktualisiert") db_session.close() return success diff --git a/backend/app/utils/printer_monitor.py b/backend/app/utils/printer_monitor.py index 52dcb007..e53a2018 100644 --- a/backend/app/utils/printer_monitor.py +++ b/backend/app/utils/printer_monitor.py @@ -144,8 +144,8 @@ class PrinterMonitor: Args: ip_address: IP-Adresse der Steckdose - username: Benutzername für die Steckdose - password: Passwort für die Steckdose + username: Benutzername für die Steckdose (wird überschrieben) + password: Passwort für die Steckdose (wird überschrieben) timeout: Timeout in Sekunden (wird ignoriert, da PyP100 eigenes Timeout hat) Returns: @@ -155,14 +155,13 @@ class PrinterMonitor: monitor_logger.error("⚠️ PyP100-Modul nicht verfügbar - kann Tapo-Steckdose nicht schalten") return False - # Fallback zu globalen Anmeldedaten wenn keine lokalen vorhanden - if not username or not password: - username = TAPO_USERNAME - password = TAPO_PASSWORD - monitor_logger.debug(f"🔧 Verwende globale Tapo-Anmeldedaten für {ip_address}") + # IMMER globale Anmeldedaten verwenden (da diese funktionieren) + username = TAPO_USERNAME + password = TAPO_PASSWORD + monitor_logger.debug(f"🔧 Verwende globale Tapo-Anmeldedaten für {ip_address}") try: - # TP-Link Tapo P100 Verbindung herstellen (P100 statt P110 verwenden) + # TP-Link Tapo P100 Verbindung herstellen (P100 statt P110) from PyP100 import PyP100 p100 = PyP100.P100(ip_address, username, password) p100.handshake() # Authentifizierung @@ -450,14 +449,13 @@ class PrinterMonitor: monitor_logger.debug("⚠️ PyP100-Modul nicht verfügbar - kann Tapo-Steckdosen-Status nicht abfragen") return False, "unknown" - # Fallback zu globalen Anmeldedaten wenn keine lokalen vorhanden - if not username or not password: - username = TAPO_USERNAME - password = TAPO_PASSWORD - monitor_logger.debug(f"🔧 Verwende globale Tapo-Anmeldedaten für {ip_address}") + # IMMER globale Anmeldedaten verwenden (da diese funktionieren) + username = TAPO_USERNAME + password = TAPO_PASSWORD + monitor_logger.debug(f"🔧 Verwende globale Tapo-Anmeldedaten für {ip_address}") try: - # TP-Link Tapo P100 Verbindung herstellen (P100 statt P110 verwenden) + # TP-Link Tapo P100 Verbindung herstellen (P100 statt P110) from PyP100 import PyP100 p100 = PyP100.P100(ip_address, username, password) p100.handshake() # Authentifizierung