Files
Projektarbeit-MYP/backend/DOCS/STECKDOSEN_STARTUP_INITIALISIERUNG.md
2025-06-20 08:56:51 +02:00

7.4 KiB

Steckdosen-Startup-Initialisierung

Übersicht

Dieses Dokument beschreibt die implementierte Lösung für die automatische Initialisierung aller Tapo-Steckdosen beim Systemstart. Die Lösung stellt sicher, dass alle im Netzwerk erreichbaren Steckdosen beim Start des MYP-Systems in einen einheitlichen Zustand versetzt werden: AUS = FREI.

Zielsetzung

Alle Steckdosen müssen via Scheduler zu Beginn in den selben Zustand versetzt werden (aus = frei), wenn sie im Netzwerk verfügbar / erreichbar sind.

Implementierung

1. Erweiterte Job Scheduler Klasse

Datei: utils/job_scheduler.py

Die BackgroundTaskScheduler Klasse wurde um eine neue Methode erweitert:

def initialize_all_outlets_on_startup(self) -> Dict[str, bool]:
    """
    Initialisiert alle konfigurierten Steckdosen beim Systemstart.
    
    Schaltet alle im Netzwerk erreichbaren Tapo-Steckdosen aus, um einen
    einheitlichen Startzustand (aus = frei) zu gewährleisten.
    
    Returns:
        Dict[str, bool]: Ergebnis der Initialisierung pro Drucker
    """

Funktionsweise:

  1. Einmalige Ausführung: Flag _outlets_initialized verhindert mehrfache Initialisierung
  2. Datenbankabfrage: Lädt alle aktiven Drucker mit Steckdosen-Konfiguration
  3. Netzwerk-Check: Prüft Erreichbarkeit jeder Steckdose via Ping
  4. Status-Prüfung: Ermittelt aktuellen Steckdosen-Status (an/aus)
  5. Intelligente Schaltung: Schaltet nur die Steckdosen aus, die aktuell eingeschaltet sind
  6. Datenbank-Update: Aktualisiert Drucker-Status in der Datenbank
  7. Umfassendes Logging: Detaillierte Protokollierung aller Aktionen

2. Erweiterte Hardware-Integration

Datei: utils/hardware_integration.py

Die DruckerSteuerung Klasse wurde um folgende Methoden erweitert:

def ping_address(self, ip: str, timeout: int = 5) -> bool:
    """Prüft die Netzwerk-Erreichbarkeit einer IP-Adresse."""

def turn_off(self, ip: str, username: str = None, password: str = None, printer_id: int = None) -> bool:
    """Schaltet eine Tapo-Steckdose aus."""

def turn_on(self, ip: str, username: str = None, password: str = None, printer_id: int = None) -> bool:
    """Schaltet eine Tapo-Steckdose ein."""

Funktionen:

  • Netzwerk-Testing: Socket-basierte Erreichbarkeitsprüfung
  • Tapo-Steuerung: Native PyP100/PyP110 Bibliothek-Integration
  • Fehlerbehandlung: Robuste Exception-Behandlung
  • Simulation-Modus: Fallback wenn Tapo-Bibliotheken nicht verfügbar

3. App-Startup-Integration

Datei: app.py

Die Steckdosen-Initialisierung wurde in den App-Startup-Prozess integriert.

Ablauf beim Systemstart

1. System-Boot

[STARTUP] 🚀 Starte MYP System
[STARTUP] Initialisiere Datenbank...
[STARTUP] ✅ Datenbank initialisiert
[STARTUP] Prüfe Initial-Admin...
[STARTUP] ✅ Admin-Benutzer geprüft
[STARTUP] Initialisiere statische Drucker...
[STARTUP] ✅ Statische Drucker konfiguriert
[STARTUP] Starte Queue Manager...
[STARTUP] ✅ Queue Manager gestartet
[STARTUP] Starte Job Scheduler...
[STARTUP] ✅ Job Scheduler gestartet

2. Steckdosen-Initialisierung

[STARTUP] Initialisiere Steckdosen (alle auf 'aus' = frei)...
[scheduler] 🚀 Starte Steckdosen-Initialisierung beim Systemstart...
[scheduler] 🔍 Prüfe 5 konfigurierte Steckdosen...
[scheduler] 🔌 Verarbeite Drucker_1 (192.168.0.100)...
[scheduler] 📡 192.168.0.100: ✅ erreichbar
[scheduler] ✓ Drucker_1: Bereits ausgeschaltet - keine Aktion nötig
[scheduler] 🔌 Verarbeite Drucker_2 (192.168.0.101)...
[scheduler] 📡 192.168.0.101: ✅ erreichbar
[scheduler] 🔄 Drucker_2: Schalte Steckdose von 'an' auf 'aus' um...
[scheduler] ✅ Drucker_2: Erfolgreich ausgeschaltet

3. Abschluss-Zusammenfassung

============================================================
🎯 STECKDOSEN-INITIALISIERUNG ABGESCHLOSSEN
📊 Gesamt: 5 Steckdosen
✅ Erfolgreich: 3
📡 Nicht erreichbar: 1
❌ Fehlgeschlagen: 1
⚡ 3/5 Steckdosen erfolgreich initialisiert
============================================================
[STARTUP] ⚡ 3/5 Steckdosen erfolgreich initialisiert

Technische Details

Netzwerk-Erreichbarkeitsprüfung

def ping_address(self, ip: str, timeout: int = 5) -> bool:
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        result = sock.connect_ex((ip, 80))
        sock.close()
        return (result == 0)
    except Exception as e:
        return False
  • Methode: Socket-basierte Verbindungsprüfung auf Port 80
  • Timeout: Standardmäßig 5 Sekunden (für Startup angepasst auf 3 Sekunden)
  • Zuverlässigkeit: Erkennt sowohl Netzwerk- als auch Geräteverfügbarkeit

Tapo-Steckdosen-Steuerung

def turn_off(self, ip: str, username: str = None, password: str = None, printer_id: int = None) -> bool:
    try:
        p100 = PyP100(ip, self.tapo_username, self.tapo_password)
        p100.handshake()
        p100.login()
        p100.turnOff()
        return True
    except Exception as e:
        return False
  • Protokoll: Native TP-Link Tapo P100/P110 API
  • Authentifizierung: Standard admin/admin Credentials
  • Fehlerbehandlung: Robuste Exception-Behandlung mit detailliertem Logging

Fehlerbehandlung

1. Netzwerk-Fehler

  • Nicht erreichbare Steckdosen werden übersprungen
  • Timeout-Schutz verhindert hängende Operationen
  • Detailliertes Logging für Netzwerk-Diagnose

2. Hardware-Fehler

  • Tapo-Verbindungsfehler werden protokolliert aber nicht kritisch behandelt
  • Simulation-Modus wenn PyP100-Bibliothek nicht verfügbar
  • Graceful Degradation bei partiellen Fehlern

3. Datenbank-Fehler

  • Rollback-Mechanismus bei Datenbank-Fehlern
  • Transaktionale Sicherheit durch Context Manager
  • Fehler-Recovery ohne System-Crash

Monitoring und Logging

Log-Kategorien

  1. Debug-Level: Detaillierte Netzwerk- und Hardware-Operationen
  2. Info-Level: Erfolgreiche Aktionen und Zusammenfassungen
  3. Warning-Level: Nicht-kritische Fehler (nicht erreichbare Geräte)
  4. Error-Level: Kritische Fehler die Intervention erfordern

Log-Dateien

  • Scheduler-Log: logs/scheduler/scheduler.log
  • Hardware-Log: logs/hardware_integration/hardware_integration.log
  • App-Startup-Log: logs/startup/startup.log

Konfiguration

Datenbank-Schema

Die Initialisierung basiert auf der Printer Tabelle:

SELECT * FROM printers 
WHERE active = 1 
  AND plug_ip IS NOT NULL;

Erforderliche Felder:

  • id: Drucker-ID
  • name: Drucker-Name
  • plug_ip: IP-Adresse der Tapo-Steckdose
  • active: Aktiv-Status (muss TRUE sein)

Tapo-Credentials

# Standard-Zugangsdaten in hardware_integration.py
self.tapo_username = "admin"
self.tapo_password = "admin"

Sicherheit

1. Einmalige Ausführung

  • Flag-basierte Kontrolle: _outlets_initialized verhindert mehrfache Ausführung
  • Race-Condition-Schutz: Thread-sichere Implementierung

2. Netzwerk-Sicherheit

  • Timeout-Schutz: Verhindert hängende Verbindungen
  • Local-Network-Only: Funktioniert nur in lokalen Netzwerken
  • Keine externe Kommunikation

3. Fehler-Isolation

  • Non-Critical-Errors: Einzelne Fehler stoppen nicht das System
  • Graceful-Degradation: System funktioniert auch bei partiellen Fehlern

Implementiert von: Till Tomczak - Mercedes-Benz TBA Marienfelde
Datum: 2025-06-19
Version: 1.0.0