🎉 Feature: Enhanced Admin Guest Requests API & Startup Initialization Documentation 📚

This commit is contained in:
Till Tomczak
2025-06-20 08:36:07 +02:00
parent 939f14199d
commit cbea4cb765
27 changed files with 1653 additions and 52 deletions

View File

@ -39,6 +39,7 @@ class BackgroundTaskScheduler:
self._running = False
self._start_time: Optional[datetime] = None
self.logger = get_scheduler_logger()
self._outlets_initialized = False # Flag für einmalige Initialisierung
def register_task(self,
task_id: str,
@ -713,6 +714,188 @@ class BackgroundTaskScheduler:
db_session.rollback()
db_session.close()
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
"""
if self._outlets_initialized:
self.logger.info("🔄 Steckdosen bereits initialisiert - überspringe")
return {}
self.logger.info("🚀 Starte Steckdosen-Initialisierung beim Systemstart...")
results = {}
success_count = 0
total_count = 0
unreachable_count = 0
try:
db_session = get_db_session()
# Alle aktiven Drucker mit Steckdosen-Konfiguration laden
printers = db_session.query(Printer).filter(
Printer.active == True,
Printer.plug_ip.isnot(None)
).all()
if not printers:
self.logger.warning("⚠️ Keine aktiven Drucker mit Steckdosen-Konfiguration gefunden")
db_session.close()
return results
total_count = len(printers)
self.logger.info(f"🔍 Prüfe {total_count} konfigurierte Steckdosen...")
# Tapo-Controller für die Operationen verwenden
tapo_controller = get_tapo_controller()
# Jede Steckdose einzeln verarbeiten
for printer in printers:
printer_name = printer.name
plug_ip = printer.plug_ip
try:
self.logger.debug(f"🔌 Verarbeite {printer_name} ({plug_ip})...")
# 1. Netzwerk-Erreichbarkeit prüfen
is_reachable = tapo_controller.ping_address(plug_ip, timeout=3)
if not is_reachable:
self.logger.warning(f"📡 {printer_name}: Steckdose {plug_ip} nicht erreichbar")
results[printer_name] = {
'success': False,
'reason': 'nicht_erreichbar',
'ip': plug_ip
}
unreachable_count += 1
continue
# 2. Aktuellen Status prüfen
reachable, current_status = tapo_controller.check_outlet_status(
plug_ip,
printer_id=printer.id,
debug=True
)
if not reachable:
self.logger.warning(f"🔗 {printer_name}: Tapo-Verbindung fehlgeschlagen")
results[printer_name] = {
'success': False,
'reason': 'verbindung_fehlgeschlagen',
'ip': plug_ip
}
unreachable_count += 1
continue
# 3. Steckdose ausschalten (nur wenn nötig)
if current_status == "on":
self.logger.info(f"🔄 {printer_name}: Schalte Steckdose von 'an' auf 'aus' um...")
success = tapo_controller.turn_off(
plug_ip,
printer_id=printer.id
)
if success:
self.logger.info(f"{printer_name}: Erfolgreich ausgeschaltet")
# Drucker-Status in Datenbank aktualisieren
printer.status = "offline"
printer.last_checked = datetime.now()
results[printer_name] = {
'success': True,
'action': 'ausgeschaltet',
'previous_status': 'an',
'ip': plug_ip
}
success_count += 1
else:
self.logger.error(f"{printer_name}: Ausschalten fehlgeschlagen")
results[printer_name] = {
'success': False,
'reason': 'ausschalten_fehlgeschlagen',
'ip': plug_ip
}
elif current_status == "off":
self.logger.info(f"{printer_name}: Bereits ausgeschaltet - keine Aktion nötig")
# Status in Datenbank aktualisieren
printer.status = "offline"
printer.last_checked = datetime.now()
results[printer_name] = {
'success': True,
'action': 'bereits_aus',
'previous_status': 'aus',
'ip': plug_ip
}
success_count += 1
else:
self.logger.warning(f"⚠️ {printer_name}: Unbekannter Status '{current_status}'")
results[printer_name] = {
'success': False,
'reason': 'unbekannter_status',
'status': current_status,
'ip': plug_ip
}
except Exception as e:
self.logger.error(f"{printer_name}: Fehler bei Initialisierung - {str(e)}")
results[printer_name] = {
'success': False,
'reason': 'ausnahme',
'error': str(e),
'ip': plug_ip
}
# Änderungen in der Datenbank speichern
try:
db_session.commit()
self.logger.debug("💾 Datenbank-Änderungen gespeichert")
except Exception as e:
self.logger.error(f"❌ Fehler beim Speichern der Datenbank-Änderungen: {str(e)}")
db_session.rollback()
db_session.close()
# Zusammenfassung loggen
self.logger.info("=" * 60)
self.logger.info("🎯 STECKDOSEN-INITIALISIERUNG ABGESCHLOSSEN")
self.logger.info(f"📊 Gesamt: {total_count} Steckdosen")
self.logger.info(f"✅ Erfolgreich: {success_count}")
self.logger.info(f"📡 Nicht erreichbar: {unreachable_count}")
self.logger.info(f"❌ Fehlgeschlagen: {total_count - success_count - unreachable_count}")
if success_count == total_count:
self.logger.info("🌟 ALLE Steckdosen erfolgreich initialisiert!")
elif success_count > 0:
self.logger.info(f"{success_count}/{total_count} Steckdosen erfolgreich initialisiert")
else:
self.logger.warning("⚠️ KEINE Steckdose konnte initialisiert werden!")
self.logger.info("=" * 60)
# Flag setzen um Mehrfach-Initialisierung zu verhindern
self._outlets_initialized = True
except Exception as e:
self.logger.error(f"❌ Kritischer Fehler bei Steckdosen-Initialisierung: {str(e)}")
try:
db_session.rollback()
db_session.close()
except:
pass
return results
# Scheduler-Instanz erzeugen
scheduler = BackgroundTaskScheduler()