8.3 KiB
8.3 KiB
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
:
# 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
:
@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
:
@admin_api_blueprint.route('/printers/<int:printer_id>/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
:
@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):
# 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
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
- Testen der Fixes in Production-Umgebung
- Monitoring der Logs auf weitere Datenbankfehler
- 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