Projektarbeit-MYP/backend/app - Kopie/docs/live_drucker_system.md

11 KiB

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)

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:

{
    "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:

{
    "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:

{
    "success": true,
    "message": "Drucker-Monitor-Cache erfolgreich geleert"
}

POST /api/printers/monitor/initialize-outlets (Admin)

Initialisiert alle Drucker-Steckdosen (schaltet sie aus).

Response:

{
    "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

// Auto-Start auf relevanten Seiten
const relevantPages = ['/printers', '/dashboard', '/admin'];
if (relevantPages.some(page => currentPath.includes(page))) {
    window.printerMonitor.start();
}

Event-Handler registrieren

// 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

// Für kritische Operationen
window.printerMonitor.enableFastUpdates();  // 5 Sekunden Intervall

// Später wieder deaktivieren
window.printerMonitor.disableFastUpdates(); // 30 Sekunden Intervall

Cache-Management

// Cache leeren und neu laden
await window.printerMonitor.clearCache();

// Sofortige Aktualisierung ohne Cache
await window.printerMonitor.forceUpdate();

Admin-Funktionen

// 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:

GET http://192.168.0.110/status
Authorization: Basic dXNlcjpwYXNzd29yZA==

Response:
{
    "system": {
        "get_sysinfo": {
            "relay_state": 1  // 1 = on, 0 = off
        }
    }
}

Generische APIs

# 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

# 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

# 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

# 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

-- 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

# 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")