🔧 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:
@@ -44,10 +44,15 @@ class TapoStatusManager:
|
||||
self._last_check = {}
|
||||
self.check_interval = 30 # Sekunden zwischen Status-Checks
|
||||
|
||||
# Session-spezifischer Status-Cache für Benutzer-Sessions
|
||||
self._session_cache = {}
|
||||
self._session_cache_lock = threading.RLock()
|
||||
self._session_cache_ttl = 300 # 5 Minuten für Session-Cache
|
||||
|
||||
# Thread-Pool für asynchrone Operationen
|
||||
self._executor = ThreadPoolExecutor(max_workers=6)
|
||||
|
||||
logger.info("TapoStatusManager initialisiert")
|
||||
logger.info("TapoStatusManager mit Session-Caching initialisiert")
|
||||
|
||||
def get_printer_status(self, printer_id: int) -> Dict[str, any]:
|
||||
"""
|
||||
@@ -441,6 +446,220 @@ class TapoStatusManager:
|
||||
logger.error(f"Fehler beim Abrufen der Kalender-Status: {str(e)}")
|
||||
return []
|
||||
|
||||
def get_session_status(self, session_id: str, printer_ids: List[int] = None) -> Dict[str, any]:
|
||||
"""
|
||||
Holt den gecachten Status für eine Session
|
||||
|
||||
Args:
|
||||
session_id: Session-ID
|
||||
printer_ids: Optional - spezifische Drucker-IDs
|
||||
|
||||
Returns:
|
||||
Dict mit Session-spezifischen Status-Daten
|
||||
"""
|
||||
try:
|
||||
with self._session_cache_lock:
|
||||
session_data = self._session_cache.get(session_id, {})
|
||||
|
||||
# Prüfe Cache-Gültigkeit
|
||||
cache_time = session_data.get('timestamp', datetime.min)
|
||||
if (datetime.now() - cache_time).total_seconds() > self._session_cache_ttl:
|
||||
# Cache abgelaufen
|
||||
self._session_cache.pop(session_id, None)
|
||||
return self._create_fresh_session_status(session_id, printer_ids)
|
||||
|
||||
# Wenn spezifische Drucker angefragt, filtere diese
|
||||
if printer_ids:
|
||||
filtered_status = {}
|
||||
for printer_id in printer_ids:
|
||||
if str(printer_id) in session_data.get('printers', {}):
|
||||
filtered_status[str(printer_id)] = session_data['printers'][str(printer_id)]
|
||||
|
||||
return {
|
||||
'timestamp': session_data['timestamp'],
|
||||
'session_id': session_id,
|
||||
'printers': filtered_status,
|
||||
'from_cache': True
|
||||
}
|
||||
|
||||
return session_data
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Abrufen des Session-Status: {str(e)}")
|
||||
return self._create_fresh_session_status(session_id, printer_ids)
|
||||
|
||||
def update_session_status(self, session_id: str, printer_id: int = None) -> bool:
|
||||
"""
|
||||
Aktualisiert den Session-Status-Cache
|
||||
|
||||
Args:
|
||||
session_id: Session-ID
|
||||
printer_id: Optional - spezifischer Drucker
|
||||
|
||||
Returns:
|
||||
bool: True wenn erfolgreich
|
||||
"""
|
||||
try:
|
||||
with self._session_cache_lock:
|
||||
if printer_id:
|
||||
# Einzelnen Drucker aktualisieren
|
||||
printer_status = self.get_printer_status(printer_id)
|
||||
|
||||
if session_id not in self._session_cache:
|
||||
self._session_cache[session_id] = {
|
||||
'timestamp': datetime.now(),
|
||||
'session_id': session_id,
|
||||
'printers': {}
|
||||
}
|
||||
|
||||
self._session_cache[session_id]['printers'][str(printer_id)] = printer_status
|
||||
self._session_cache[session_id]['timestamp'] = datetime.now()
|
||||
else:
|
||||
# Alle Drucker aktualisieren
|
||||
self._session_cache[session_id] = self._create_fresh_session_status(session_id)
|
||||
|
||||
logger.debug(f"Session-Status für {session_id} aktualisiert")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Aktualisieren des Session-Status: {str(e)}")
|
||||
return False
|
||||
|
||||
def clear_session_cache(self, session_id: str = None) -> bool:
|
||||
"""
|
||||
Löscht Session-Cache
|
||||
|
||||
Args:
|
||||
session_id: Optional - spezifische Session, sonst alle
|
||||
|
||||
Returns:
|
||||
bool: True wenn erfolgreich
|
||||
"""
|
||||
try:
|
||||
with self._session_cache_lock:
|
||||
if session_id:
|
||||
self._session_cache.pop(session_id, None)
|
||||
logger.debug(f"Session-Cache für {session_id} gelöscht")
|
||||
else:
|
||||
self._session_cache.clear()
|
||||
logger.debug("Kompletter Session-Cache gelöscht")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Löschen des Session-Cache: {str(e)}")
|
||||
return False
|
||||
|
||||
def _create_fresh_session_status(self, session_id: str, printer_ids: List[int] = None) -> Dict[str, any]:
|
||||
"""
|
||||
Erstellt frischen Session-Status
|
||||
|
||||
Args:
|
||||
session_id: Session-ID
|
||||
printer_ids: Optional - spezifische Drucker-IDs
|
||||
|
||||
Returns:
|
||||
Dict mit frischen Status-Daten
|
||||
"""
|
||||
try:
|
||||
db_session = get_db_session()
|
||||
|
||||
# Alle oder spezifische Drucker laden
|
||||
if printer_ids:
|
||||
printers = db_session.query(Printer).filter(Printer.id.in_(printer_ids)).all()
|
||||
else:
|
||||
printers = db_session.query(Printer).all()
|
||||
|
||||
session_data = {
|
||||
'timestamp': datetime.now(),
|
||||
'session_id': session_id,
|
||||
'printers': {},
|
||||
'from_cache': False
|
||||
}
|
||||
|
||||
# Status für jeden Drucker abrufen
|
||||
for printer in printers:
|
||||
printer_status = self.get_printer_status(printer.id)
|
||||
session_data['printers'][str(printer.id)] = printer_status
|
||||
|
||||
# In Session-Cache speichern
|
||||
with self._session_cache_lock:
|
||||
self._session_cache[session_id] = session_data
|
||||
|
||||
db_session.close()
|
||||
return session_data
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Erstellen frischen Session-Status: {str(e)}")
|
||||
return {
|
||||
'timestamp': datetime.now(),
|
||||
'session_id': session_id,
|
||||
'printers': {},
|
||||
'error': str(e),
|
||||
'from_cache': False
|
||||
}
|
||||
|
||||
def get_session_cache_stats(self) -> Dict[str, any]:
|
||||
"""
|
||||
Gibt Session-Cache-Statistiken zurück
|
||||
|
||||
Returns:
|
||||
Dict mit Cache-Statistiken
|
||||
"""
|
||||
try:
|
||||
with self._session_cache_lock:
|
||||
stats = {
|
||||
'total_sessions': len(self._session_cache),
|
||||
'cache_ttl_seconds': self._session_cache_ttl,
|
||||
'cache_size_bytes': len(str(self._session_cache)),
|
||||
'sessions': {}
|
||||
}
|
||||
|
||||
for session_id, data in self._session_cache.items():
|
||||
stats['sessions'][session_id] = {
|
||||
'timestamp': data.get('timestamp', datetime.min).isoformat(),
|
||||
'printer_count': len(data.get('printers', {})),
|
||||
'age_seconds': (datetime.now() - data.get('timestamp', datetime.now())).total_seconds()
|
||||
}
|
||||
|
||||
return stats
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Abrufen der Cache-Statistiken: {str(e)}")
|
||||
return {'error': str(e)}
|
||||
|
||||
def cleanup_expired_session_cache(self) -> int:
|
||||
"""
|
||||
Bereinigt abgelaufene Session-Cache-Einträge
|
||||
|
||||
Returns:
|
||||
int: Anzahl gelöschter Einträge
|
||||
"""
|
||||
try:
|
||||
expired_count = 0
|
||||
current_time = datetime.now()
|
||||
|
||||
with self._session_cache_lock:
|
||||
expired_sessions = []
|
||||
|
||||
for session_id, data in self._session_cache.items():
|
||||
cache_time = data.get('timestamp', datetime.min)
|
||||
if (current_time - cache_time).total_seconds() > self._session_cache_ttl:
|
||||
expired_sessions.append(session_id)
|
||||
|
||||
for session_id in expired_sessions:
|
||||
self._session_cache.pop(session_id, None)
|
||||
expired_count += 1
|
||||
|
||||
if expired_count > 0:
|
||||
logger.info(f"Session-Cache bereinigt: {expired_count} abgelaufene Einträge entfernt")
|
||||
|
||||
return expired_count
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Bereinigen des Session-Cache: {str(e)}")
|
||||
return 0
|
||||
|
||||
def _get_status_color(self, status: str) -> str:
|
||||
"""Gibt die Farbe für einen Status zurück"""
|
||||
colors = {
|
||||
|
Reference in New Issue
Block a user