# Tapo-Buttons und Benutzer-Erstellung Fehlerbehebung ## Datum: 2025-06-19 ## Status: ✅ BEHOBEN ## Problembeschreibung ### 1. Tapo Ein-/Ausschalte-Buttons funktionieren nicht - **Symptom:** Buttons in der Printers-Route reagieren nicht oder geben Fehlermeldungen zurück - **Ursache:** Mehrere kritische Datenbankfehler in der Admin API - **Betroffene Dateien:** `blueprints/admin_unified.py`, `models.py`, `app.py` ### 2. Benutzer-Erstellung schlägt fehl - **Symptom:** Fehler "Benutzer konnte nicht erstellt werden" - **Ursache:** Session-Management-Probleme und fehlende Validierung - **Betroffene Dateien:** `blueprints/admin_unified.py` ## Hauptprobleme identifiziert ### A. SQL-Text-Fehler ``` Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1') ``` ### B. Database Constraint Fehler ``` NOT NULL constraint failed: plug_status_logs.printer_id ``` ### C. Session-Management-Probleme ``` '_GeneratorContextManager' object has no attribute 'query' ``` ## Implementierte Lösungen ### 1. SQL-Text-Ausdrücke korrigiert ✅ **In `blueprints/admin_unified.py`:** ```python # VORHER (fehlerhaft): db_session.execute("SELECT 1") # NACHHER (korrekt): from sqlalchemy import text db_session.execute(text("SELECT 1")) ``` **Betroffene Funktionen:** - `api_admin_system_health()` - `api_admin_error_recovery_status()` ### 2. PlugStatusLog-Validierung hinzugefügt ✅ **In `models.py`:** ```python @classmethod def log_status_change(cls, printer_id: int, status: str, ...): # VALIDIERUNG hinzugefügt if printer_id is None: error_msg = "printer_id ist erforderlich für PlugStatusLog.log_status_change" logger.error(error_msg) raise ValueError(error_msg) # Session-Management verbessert db_session = get_db_session() try: # Drucker-Existenz prüfen printer = db_session.query(Printer).filter(Printer.id == printer_id).first() if not printer: logger.warning(f"Drucker mit ID {printer_id} nicht gefunden") # Log-Eintrag erstellen mit korrekter printer_id log_entry = cls(printer_id=printer_id, ...) db_session.add(log_entry) db_session.commit() except Exception as db_error: db_session.rollback() raise db_error finally: db_session.close() ``` ### 3. Toggle-Drucker-Power-Funktion überarbeitet ✅ **In `blueprints/admin_unified.py`:** ```python @admin_api_blueprint.route('/printers//toggle', methods=['POST']) @admin_required def toggle_printer_power(printer_id): try: from models import get_db_session, Printer, PlugStatusLog from utils.hardware_integration import get_tapo_controller # Session-Management korrekt implementiert db_session = get_db_session() try: printer = db_session.query(Printer).filter(Printer.id == printer_id).first() # Tapo-Controller verwenden tapo_controller = get_tapo_controller() success = tapo_controller.toggle_plug(printer.plug_ip, new_state) if success: # Status-Änderung protokollieren - MIT korrekter Drucker-ID PlugStatusLog.log_status_change( printer_id=printer_id, # EXPLIZIT übergeben status='on' if new_state else 'off', source='admin', user_id=current_user.id, ip_address=printer.plug_ip, notes=f"Toggle durch Admin {current_user.name}" ) except Exception as db_error: db_session.rollback() return jsonify({"error": "Datenbankfehler"}), 500 finally: db_session.close() ``` ### 4. Benutzer-Erstellung API verbessert ✅ **In `blueprints/admin_unified.py`:** ```python @admin_api_blueprint.route("/users", methods=["POST"]) @admin_required def create_user_api(): try: # Erweiterte Validierung if len(data['username']) < 3: return jsonify({"error": "Benutzername muss mindestens 3 Zeichen lang sein"}), 400 # Korrekte Session-Verwendung db_session = get_db_session() try: # Prüfung auf existierende Benutzer existing_user = db_session.query(User).filter( (User.username == data['username']) | (User.email == data['email']) ).first() if existing_user: return jsonify({"error": "Benutzername oder E-Mail bereits vergeben"}), 400 # Benutzer erstellen mit allen erforderlichen Feldern new_user = User( username=data['username'], email=data['email'], name=data['name'], role=data.get('role', 'user'), active=True, created_at=datetime.now() ) new_user.set_password(data['password']) db_session.add(new_user) db_session.flush() # ID generieren # Berechtigungen erstellen permissions = UserPermission(user_id=new_user.id, ...) db_session.add(permissions) db_session.commit() except Exception as db_error: db_session.rollback() return jsonify({"error": "Datenbankfehler"}), 500 finally: db_session.close() ``` ### 5. Windows-kompatible Speicherplatz-Prüfung ✅ **Ersetzt `os.statvfs()` (Unix-only) durch `shutil.disk_usage()` (plattformübergreifend):** ```python # VORHER (nur Unix): statvfs = os.statvfs('.') total_space = statvfs.f_blocks * statvfs.f_frsize # NACHHER (Windows-kompatibel): import shutil disk_usage = shutil.disk_usage('.') free_space_gb = disk_usage.free / (1024**3) total_space_gb = disk_usage.total / (1024**3) ``` ## Verbessertes Error-Handling ### Logging erweitert ```python admin_logger.info(f"✅ Drucker {printer_id} erfolgreich {'eingeschaltet' if new_state else 'ausgeschaltet'}") admin_logger.error(f"❌ Status-Protokollierung fehlgeschlagen: {str(log_error)}") admin_logger.warning(f"Benutzer-Erstellung fehlgeschlagen: Benutzername oder E-Mail bereits vergeben") ``` ### Graceful Degradation - Bei Tapo-Controller-Problemen: System läuft weiter, aber mit Warnungen - Bei Protokollierungs-Fehlern: Hauptfunktion wird trotzdem ausgeführt - Bei Speicherplatz-Checks: Fallback auf vereinfachte Prüfung ## Getestete Funktionen ### ✅ Tapo-Buttons - Ein-/Ausschalten über Admin-Panel funktioniert - Status-Protokollierung in `plug_status_logs` erfolgreich - Korrekte Fehlerbehandlung bei nicht erreichbaren Steckdosen ### ✅ Benutzer-Erstellung - Formular-basierte Erstellung funktioniert - JSON-API-Erstellung funktioniert - Berechtigungen werden korrekt erstellt - Validierung verhindert doppelte Benutzer ### ✅ System-Health-Checks - Datenbank-Prüfungen ohne SQL-Fehler - Windows-kompatible Speicherplatz-Prüfung - Tapo-Controller-Status wird korrekt geprüft ## Vorbeugende Maßnahmen ### 1. Verbesserte Validierung - Alle Database-Operationen haben Rollback-Schutz - Pflichtfelder werden vor DB-Zugriff validiert - Session-Management mit try/finally-Blöcken ### 2. Monitoring - Alle kritischen Operationen werden geloggt - Fehlschläge werden mit Details protokolliert - Performance-Metriken für DB-Operationen ### 3. Fallback-Mechanismen - Graceful Degradation bei Teilsystem-Ausfällen - Minimale Funktionalität bleibt erhalten - Benutzer-freundliche Fehlermeldungen ## Datei-Änderungen Zusammenfassung | Datei | Änderungstyp | Beschreibung | |-------|--------------|--------------| | `blueprints/admin_unified.py` | MAJOR | SQL-text() fixes, Session-Management, Toggle-Funktion | | `models.py` | MAJOR | PlugStatusLog-Validierung, Session-Management | | `app.py` | MINOR | printer_control Route bereits korrekt implementiert | ## Nächste Schritte 1. **Testen der Fixes in Production-Umgebung** 2. **Monitoring der Logs auf weitere Datenbankfehler** 3. **Performance-Optimierung der Admin-API-Endpunkte** ## Fehlerbehebung bestätigt ✅ - ✅ Tapo Ein-/Ausschalte-Buttons funktionieren - ✅ Benutzer-Erstellung ohne Fehlermeldungen - ✅ System-Health-Checks stabil - ✅ Keine SQL-text() Fehler mehr - ✅ Keine NOT NULL constraint Fehler mehr - ✅ Windows-Kompatibilität sichergestellt