🔧 Update: Enhanced error handling and logging across various modules

**Änderungen:**
-  app.py: Hinzugefügt, um CSRF-Fehler zu behandeln
-  models.py: Fehlerprotokollierung bei der Suche nach Gastanfragen per OTP
-  api.py: Fehlerprotokollierung beim Markieren von Benachrichtigungen als gelesen
-  calendar.py: Fallback-Daten zurückgeben, wenn keine Kalenderereignisse vorhanden sind
-  guest.py: Status-Check-Seite für Gäste aktualisiert
-  hardware_integration.py: Debugging-Informationen für erweiterte Geräteinformationen hinzugefügt
-  tapo_status_manager.py: Rückgabewert für Statusabfrage hinzugefügt

**Ergebnis:**
- Verbesserte Fehlerbehandlung und Protokollierung für eine robustere Anwendung
- Bessere Nachverfolgbarkeit von Fehlern und Systemverhalten

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-06-15 22:45:20 +02:00
parent 7e156099d5
commit 956c24d8ca
552 changed files with 11252 additions and 2424 deletions

View File

@ -92,12 +92,16 @@ class TapoController:
else:
tapo_logger.info("✅ tapo controller initialisiert")
def toggle_plug(self, ip: str, state: bool, username: str = None, password: str = None) -> bool:
def toggle_plug(self, ip: str, state: bool, username: str = None, password: str = None, debug: bool = True) -> bool:
"""
Schaltet eine TP-Link Tapo P100/P110-Steckdose ein oder aus
Args:
ip: IP-Adresse der Steckdose
state: True für An, False für Aus
username: Optional - Tapo-Benutzername
password: Optional - Tapo-Passwort
debug: Aktiviert erweiterte Debug-Ausgaben
state: True = ein, False = aus
username: Benutzername (optional, nutzt Standard wenn nicht angegeben)
password: Passwort (optional, nutzt Standard wenn nicht angegeben)
@ -115,31 +119,69 @@ class TapoController:
tapo_logger.debug(f"🔧 verwende globale tapo-anmeldedaten für {ip}")
start_time = time.time()
for attempt in range(self.retry_count):
try:
if debug:
tapo_logger.debug(f"🔌 Versuch {attempt+1}/{self.retry_count}: Verbinde zu Tapo-Steckdose {ip}")
# P100-Verbindung herstellen
p100 = PyP100.P100(ip, username, password)
if debug:
tapo_logger.debug(f"🤝 Handshake mit {ip}...")
p100.handshake()
if debug:
tapo_logger.debug(f"🔐 Login bei {ip}...")
p100.login()
# Steckdose schalten
action_time = time.time()
if state:
if debug:
tapo_logger.debug(f"⚡ Schalte {ip} EIN...")
p100.turnOn()
tapo_logger.info(f"tapo-steckdose {ip} erfolgreich eingeschaltet")
tapo_logger.info(f"Tapo-Steckdose {ip} erfolgreich eingeschaltet")
else:
if debug:
tapo_logger.debug(f"🔴 Schalte {ip} AUS...")
p100.turnOff()
tapo_logger.info(f"tapo-steckdose {ip} erfolgreich ausgeschaltet")
tapo_logger.info(f"Tapo-Steckdose {ip} erfolgreich ausgeschaltet")
response_time = int((time.time() - start_time) * 1000)
if debug:
tapo_logger.debug(f"⏱️ Schaltvorgang für {ip} abgeschlossen in {response_time}ms")
# Status-Logging
new_status = "on" if state else "off"
self._log_plug_status(None, new_status, ip, response_time_ms=response_time)
return True
except Exception as e:
action = "ein" if state else "aus"
tapo_logger.warning(f"⚠️ versuch {attempt+1}/{self.retry_count} fehlgeschlagen beim {action}schalten von {ip}: {str(e)}")
response_time = int((time.time() - start_time) * 1000)
if debug:
tapo_logger.warning(f"⚠️ Versuch {attempt+1}/{self.retry_count} fehlgeschlagen beim {action}schalten von {ip}: {str(e)}")
tapo_logger.debug(f"🔍 Fehlerdetails: Typ={type(e).__name__}, Zeit={response_time}ms")
# Status-Logging bei Fehler
self._log_plug_status(None, "disconnected", ip,
response_time_ms=response_time,
error_message=str(e))
if attempt < self.retry_count - 1:
time.sleep(1) # Kurze pause vor erneutem versuch
if debug:
tapo_logger.debug(f"⏳ Warte 1 Sekunde vor erneutem Versuch...")
time.sleep(1)
else:
tapo_logger.error(f"fehler beim {action}schalten der tapo-steckdose {ip}: {str(e)}")
tapo_logger.error(f"Alle {self.retry_count} Versuche fehlgeschlagen beim {action}schalten der Tapo-Steckdose {ip}")
if debug:
tapo_logger.debug(f"💀 Finale Fehlerdetails: {str(e)}")
return False
@ -196,7 +238,7 @@ class TapoController:
return False
def check_outlet_status(self, ip: str, username: str = None, password: str = None,
printer_id: int = None) -> Tuple[bool, str]:
printer_id: int = None, debug: bool = True) -> Tuple[bool, str]:
"""
Überprüft den Status einer TP-Link Tapo P110-Steckdose
@ -223,11 +265,23 @@ class TapoController:
start_time = time.time()
try:
if debug:
tapo_logger.debug(f"🔍 Status-Check für Tapo-Steckdose {ip} gestartet")
# TP-Link Tapo P100 Verbindung herstellen
p100 = PyP100.P100(ip, username, password)
if debug:
tapo_logger.debug(f"🤝 Handshake mit {ip}...")
p100.handshake()
if debug:
tapo_logger.debug(f"🔐 Login bei {ip}...")
p100.login()
if debug:
tapo_logger.debug(f"📊 Geräteinformationen von {ip} abrufen...")
# Geräteinformationen abrufen
device_info = p100.getDeviceInfo()
@ -236,10 +290,18 @@ class TapoController:
status = "on" if device_on else "off"
response_time = int((time.time() - start_time) * 1000)
tapo_logger.debug(f"✅ tapo-steckdose {ip}: status = {status}")
if debug:
tapo_logger.debug(f"✅ Tapo-Steckdose {ip}: Status = {status}, Reaktionszeit = {response_time}ms")
tapo_logger.debug(f"📋 Device-Info: {device_info}")
tapo_logger.info(f"✅ Tapo-Steckdose {ip}: Status = {status}")
# Erweiterte Informationen sammeln
extra_info = self._collect_device_info(p100, device_info)
extra_info = self._collect_device_info(p100, device_info, debug=debug)
if debug and extra_info:
tapo_logger.debug(f"🔋 Zusätzliche Informationen für {ip}: {extra_info}")
# Logging: erfolgreicher status-check
self._log_plug_status(printer_id, status, ip,
@ -254,7 +316,13 @@ class TapoController:
except Exception as e:
response_time = int((time.time() - start_time) * 1000)
tapo_logger.debug(f"⚠️ fehler bei tapo-steckdosen-status-check {ip}: {str(e)}")
if debug:
tapo_logger.warning(f"⚠️ Fehler bei Tapo-Steckdosen-Status-Check {ip}: {str(e)}")
tapo_logger.debug(f"🔍 Fehlerdetails: Typ={type(e).__name__}, Zeit={response_time}ms")
tapo_logger.debug(f"💀 Exception-Details: {repr(e)}")
tapo_logger.error(f"❌ Status-Check für {ip} fehlgeschlagen: {str(e)}")
# Logging: fehlgeschlagener status-check
self._log_plug_status(printer_id, "disconnected", ip,
@ -541,7 +609,7 @@ class TapoController:
return status_dict
def _collect_device_info(self, p100: 'PyP100.P100', device_info: dict) -> dict:
def _collect_device_info(self, p100: 'PyP100.P100', device_info: dict, debug: bool = False) -> dict:
"""
Sammelt erweiterte Geräteinformationen von der Tapo-Steckdose
@ -555,24 +623,50 @@ class TapoController:
extra_info = {}
try:
if debug:
tapo_logger.debug(f"🔋 Sammle erweiterte Geräteinformationen...")
# Stromverbrauch abrufen (nur bei P110)
try:
if debug:
tapo_logger.debug(f"⚡ Versuche Energieverbrauch abzurufen...")
energy_usage = p100.getEnergyUsage()
if energy_usage:
extra_info['power_consumption'] = energy_usage.get('current_power', 0)
extra_info['voltage'] = energy_usage.get('voltage_mv', 0) / 1000.0
extra_info['current'] = energy_usage.get('current_ma', 0) / 1000.0
except:
if debug:
tapo_logger.debug(f"🔌 Stromverbrauch: {extra_info['power_consumption']}W")
tapo_logger.debug(f"⚡ Spannung: {extra_info['voltage']}V")
tapo_logger.debug(f"🔄 Strom: {extra_info['current']}A")
else:
if debug:
tapo_logger.debug(f" Keine Energiedaten verfügbar (vermutlich P100)")
except Exception as energy_error:
if debug:
tapo_logger.debug(f"⚠️ Energiemessung nicht verfügbar: {energy_error}")
pass # P100 unterstützt keine Energiemessung
# Firmware-Version
# Firmware und Hardware-Informationen
extra_info['firmware_version'] = device_info.get('fw_ver', 'unknown')
extra_info['hardware_version'] = device_info.get('hw_ver', 'unknown')
extra_info['device_id'] = device_info.get('device_id', 'unknown')
extra_info['mac_address'] = device_info.get('mac', 'unknown')
if debug:
tapo_logger.debug(f"📋 Firmware: {extra_info['firmware_version']}")
tapo_logger.debug(f"🔧 Hardware: {extra_info['hardware_version']}")
tapo_logger.debug(f"🆔 Device-ID: {extra_info['device_id']}")
tapo_logger.debug(f"🌐 MAC: {extra_info['mac_address']}")
except Exception as e:
tapo_logger.debug(f"Konnte erweiterte Geräteinformationen nicht abrufen: {e}")
if debug:
tapo_logger.warning(f"⚠️ Fehler beim Sammeln erweiterter Geräteinformationen: {e}")
tapo_logger.debug(f"🔍 Fehlerdetails: {repr(e)}")
else:
tapo_logger.debug(f"Konnte erweiterte Geräteinformationen nicht abrufen: {e}")
return extra_info