# Live-Druckererkennungs-System - MYP Platform ## Übersicht Das Live-Druckererkennungs-System überwacht kontinuierlich den Status aller konfigurierten Drucker und bietet Echtzeit-Updates mit Session-Caching und automatischer Steckdosen-Initialisierung. ## Features ### 🔄 Live-Monitoring - **Echtzeit-Status-Updates** alle 30 Sekunden - **Parallele Abfragen** für bessere Performance - **Automatische Fehlerbehandlung** mit exponential backoff - **Adaptive Aktualisierungsintervalle** basierend auf Seitensichtbarkeit ### 💾 Session-Caching - **Session-basierter Cache** für schnelle Zugriffe (30 Sekunden TTL) - **Datenbank-Cache** für persistente Daten (5 Minuten TTL) - **Threadsicheres Caching** mit Locks - **Automatische Cache-Invalidierung** ### 🔌 Steckdosen-Initialisierung - **Automatischer Start** beim Programmstart - **Einheitlicher Startzustand** (alle Steckdosen ausgeschaltet) - **Fehlertolerante Initialisierung** mit detailliertem Logging - **Admin-gesteuerte manuelle Initialisierung** ### 📊 Status-Kategorien - **Online**: Drucker eingeschaltet und erreichbar - **Standby**: Drucker ausgeschaltet aber Steckdose erreichbar - **Offline**: Drucker/Steckdose nicht erreichbar - **Unreachable**: Grundkonnektivität fehlgeschlagen - **Unconfigured**: Unvollständige Konfiguration ## Backend-Architektur ### PrinterMonitor Klasse (`utils/printer_monitor.py`) ```python class PrinterMonitor: def __init__(self): self.session_cache = {} # Session-Cache für schnelle Zugriffe self.db_cache = {} # DB-Cache für persistente Daten self.cache_lock = threading.Lock() self.session_cache_ttl = 30 # 30 Sekunden self.db_cache_ttl = 300 # 5 Minuten ``` #### Hauptmethoden ##### `initialize_all_outlets_on_startup()` - Schaltet beim Programmstart alle Steckdosen aus - Setzt alle Drucker in den gleichen Startzustand - Protokolliert detaillierte Ergebnisse ##### `get_live_printer_status(use_session_cache=True)` - Holt Live-Status mit mehrstufigem Caching - Prüft Session-Cache → DB-Cache → Live-Abfrage - Aktualisiert beide Cache-Ebenen ##### `_check_single_printer_status(printer, timeout=7)` - Überprüft einzelnen Drucker mit umfassenden Tests - Ping-Test für Grundkonnektivität - Smart-Plug-Status-Abfrage über HTTP-APIs - Unterstützt verschiedene Smart-Plug-Typen ## API-Endpunkte ### GET `/api/printers/monitor/live-status` Holt Live-Druckerstatus mit Session-Caching. **Parameter:** - `use_cache` (optional): Verwende Session-Cache (default: true) **Response:** ```json { "success": true, "printers": { "1": { "id": 1, "name": "Printer 1", "status": "online", "active": true, "ip_address": "192.168.0.100", "plug_ip": "192.168.0.110", "location": "Werk 040 - Berlin - TBA", "last_checked": "2025-01-05T10:30:00", "ping_successful": true, "outlet_reachable": true, "outlet_state": "on" } }, "summary": { "total": 6, "online": 2, "offline": 1, "standby": 2, "unreachable": 1, "unconfigured": 0 }, "cache_used": true, "timestamp": "2025-01-05T10:30:00", "total_printers": 6 } ``` ### GET `/api/printers/monitor/summary` Schnelle Status-Zusammenfassung ohne vollständige Details. **Response:** ```json { "success": true, "summary": { "total": 6, "online": 2, "offline": 1, "standby": 2, "unreachable": 1, "unconfigured": 0 }, "timestamp": "2025-01-05T10:30:00" } ``` ### POST `/api/printers/monitor/clear-cache` Löscht alle Monitor-Caches (Session und DB). **Response:** ```json { "success": true, "message": "Drucker-Monitor-Cache erfolgreich geleert" } ``` ### POST `/api/printers/monitor/initialize-outlets` (Admin) Initialisiert alle Drucker-Steckdosen (schaltet sie aus). **Response:** ```json { "success": true, "message": "Steckdosen-Initialisierung abgeschlossen: 5/6 erfolgreich", "results": { "Printer 1": true, "Printer 2": true, "Printer 3": false, "Printer 4": true, "Printer 5": true, "Printer 6": true }, "statistics": { "total": 6, "successful": 5, "failed": 1 } } ``` ## Frontend-Integration ### PrinterMonitor JavaScript-Klasse (`static/js/printer_monitor.js`) #### Automatischer Start ```javascript // Auto-Start auf relevanten Seiten const relevantPages = ['/printers', '/dashboard', '/admin']; if (relevantPages.some(page => currentPath.includes(page))) { window.printerMonitor.start(); } ``` #### Event-Handler registrieren ```javascript // Status-Updates abonnieren window.printerMonitor.onUpdate((data) => { if (data.type === 'update') { updatePrinterDisplay(data.printers); updateSummary(data.summary); // Änderungen anzeigen data.changes.forEach(change => { if (change.type === 'status_change') { showStatusChangeNotification(change); } }); } }); ``` #### Schnelle Updates aktivieren ```javascript // Für kritische Operationen window.printerMonitor.enableFastUpdates(); // 5 Sekunden Intervall // Später wieder deaktivieren window.printerMonitor.disableFastUpdates(); // 30 Sekunden Intervall ``` #### Cache-Management ```javascript // Cache leeren und neu laden await window.printerMonitor.clearCache(); // Sofortige Aktualisierung ohne Cache await window.printerMonitor.forceUpdate(); ``` #### Admin-Funktionen ```javascript // Steckdosen initialisieren (nur für Admins) try { const result = await window.printerMonitor.initializeAllOutlets(); console.log('Initialisierung erfolgreich:', result.statistics); } catch (error) { console.error('Initialisierung fehlgeschlagen:', error); } ``` ## Smart-Plug-Unterstützung Das System unterstützt verschiedene Smart-Plug-APIs: ### TP-Link Tapo ```http GET http://192.168.0.110/status Authorization: Basic dXNlcjpwYXNzd29yZA== Response: { "system": { "get_sysinfo": { "relay_state": 1 // 1 = on, 0 = off } } } ``` ### Generische APIs ```http # Status-Abfrage GET http://192.168.0.110/api/status GET http://192.168.0.110/relay/status GET http://192.168.0.110/state # Steckdose ausschalten POST http://192.168.0.110/relay/off POST http://192.168.0.110/api/relay/off POST http://192.168.0.110/set?relay=off ``` ## Konfiguration ### Drucker-Modell erweitern ```python # models.py class Printer(Base): # ... bestehende Felder ... plug_ip = Column(String(50), nullable=False) plug_username = Column(String(100), nullable=False) plug_password = Column(String(100), nullable=False) last_checked = Column(DateTime, nullable=True) ``` ### Rate-Limiting ```python # Rate-Limits für API-Endpunkte (bereits in RATE_LIMITS konfiguriert) @limit_requests("printer_monitor_live") # 5 Anfragen pro Minute @limit_requests("printer_monitor_summary") # 10 Anfragen pro 30 Sekunden @limit_requests("printer_monitor_cache") # 3 Anfragen pro 2 Minuten @limit_requests("printer_monitor_init") # 2 Anfragen pro 5 Minuten # Konfiguration in utils/rate_limiter.py: RATE_LIMITS = { 'printer_monitor_live': RateLimit(5, 60, "Zu viele Live-Status-Anfragen..."), 'printer_monitor_summary': RateLimit(10, 30, "Zu viele Zusammenfassungs-Anfragen..."), 'printer_monitor_cache': RateLimit(3, 120, "Zu viele Cache-Lösch-Anfragen..."), 'printer_monitor_init': RateLimit(2, 300, "Zu viele Initialisierungs-Anfragen..."), } ``` ## Logging ### Log-Kategorien - **INFO**: Normale Operationen, Status-Updates - **WARNING**: Fehlerhafte Konfigurationen, Initialisierungsprobleme - **ERROR**: Kritische Fehler, Netzwerkprobleme - **DEBUG**: Detaillierte Ping/HTTP-Informationen ### Beispiel-Logs ``` 2025-01-05 10:30:00 - printer_monitor - INFO - 🖨️ Drucker-Monitor initialisiert 2025-01-05 10:30:01 - printer_monitor - INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart... 2025-01-05 10:30:02 - printer_monitor - INFO - ✅ Printer 1: Steckdose ausgeschaltet 2025-01-05 10:30:03 - printer_monitor - WARNING - ❌ Printer 3: Steckdose konnte nicht ausgeschaltet werden 2025-01-05 10:30:05 - printer_monitor - INFO - 🎯 Steckdosen-Initialisierung abgeschlossen: 5/6 erfolgreich ``` ## Performance-Optimierungen ### Threading - **Parallele Drucker-Abfragen** mit ThreadPoolExecutor - **Maximale Worker**: min(anzahl_drucker, 8) - **Timeout-Handling** für hängende Anfragen ### Caching-Strategie 1. **Session-Cache** (30s): Sofortige Antworten für wiederholte Anfragen 2. **DB-Cache** (5min): Reduziert Datenbankzugriffe 3. **Adaptive TTL**: Längere Cache-Zeiten bei Fehlern ### Netzwerk-Optimierungen - **Kurze Ping-Timeouts** (3s) für schnelle Konnektivitätsprüfung - **HTTP-Timeouts** (5-7s) für Smart-Plug-APIs - **Exponential Backoff** bei wiederholten Fehlern ## Fehlerbehandlung ### Automatische Wiederherstellung - **Fehler-Zähler** mit maximal 3 Versuchen - **Intervall-Erhöhung** bei wiederholten Fehlern - **Cache-Fallback** bei Netzwerkproblemen ### Graceful Degradation - **Teilweise Ergebnisse** bei einzelnen Drucker-Fehlern - **Letzte bekannte Werte** aus Cache bei Totalausfall - **Benutzerbenachrichtigung** über Systemprobleme ## Wartung und Monitoring ### System-Health-Checks ```bash # Cache-Status prüfen curl -X GET /api/printers/monitor/summary # Cache leeren curl -X POST /api/printers/monitor/clear-cache # Vollständige Aktualisierung curl -X GET "/api/printers/monitor/live-status?use_cache=false" ``` ### Database-Wartung ```sql -- Alte last_checked Werte bereinigen UPDATE printers SET last_checked = NULL WHERE last_checked < datetime('now', '-1 day'); -- Drucker-Status-Statistiken SELECT status, COUNT(*) FROM printers GROUP BY status; ``` ## Troubleshooting ### Häufige Probleme #### Problem: Drucker werden als "unreachable" angezeigt **Lösung:** 1. Netzwerkverbindung prüfen 2. IP-Adressen in Datenbank validieren 3. Firewall-Regeln überprüfen #### Problem: Steckdosen-Initialisierung schlägt fehl **Lösung:** 1. Smart-Plug-Konfiguration prüfen (IP, Username, Password) 2. API-Endpunkte testen 3. Timeout-Werte erhöhen #### Problem: Cache funktioniert nicht **Lösung:** 1. Session-Konfiguration prüfen 2. Cache manuell leeren 3. Speicher-Limits überprüfen ### Debug-Befehle ```python # Einzelnen Drucker testen from utils.printer_monitor import printer_monitor status = printer_monitor._check_single_printer_status(printer) # Cache-Inhalt prüfen print(printer_monitor.db_cache) # Steckdose manuell testen success = printer_monitor._turn_outlet_off("192.168.0.110", "user", "pass") ```