🎉 Improved database performance and session management in backend/backend/database/myp.db, backend/blueprints/__pycache__/tapo_control.cpython-313.pyc, backend/blueprints/tapo_control.py, backend/config/settings.py
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -26,69 +26,141 @@ tapo_logger = get_logger("tapo_control")
|
||||
@login_required
|
||||
@require_permission(Permission.CONTROL_PRINTER)
|
||||
def tapo_dashboard():
|
||||
"""Haupt-Dashboard für Tapo-Steckdosen-Steuerung."""
|
||||
"""Haupt-Dashboard für Tapo-Steckdosen-Steuerung - zeigt immer alle 6 Mercedes-Benz Arbeitsplätze."""
|
||||
try:
|
||||
tapo_logger.info(f"Tapo Dashboard aufgerufen von Benutzer: {current_user.name}")
|
||||
|
||||
# Alle konfigurierten Tapo-Steckdosen aus der Datenbank laden
|
||||
# Importiere die festen Konfigurationen
|
||||
try:
|
||||
from config.settings import DEFAULT_TAPO_IPS, PRINTERS, FIXED_PRINTER_COUNT, ALWAYS_SHOW_ALL_SOCKETS
|
||||
except ImportError:
|
||||
# Fallback-Konfiguration
|
||||
DEFAULT_TAPO_IPS = ["192.168.1.201", "192.168.1.202", "192.168.1.203", "192.168.1.204", "192.168.1.205", "192.168.1.206"]
|
||||
FIXED_PRINTER_COUNT = 6
|
||||
ALWAYS_SHOW_ALL_SOCKETS = True
|
||||
tapo_logger.warning("Fallback-Konfiguration verwendet da config.settings nicht importiert werden konnte")
|
||||
|
||||
# Alle Drucker aus der Datenbank laden
|
||||
db_session = get_db_session()
|
||||
printers_with_tapo = db_session.query(Printer).filter(
|
||||
db_printers = {printer.plug_ip: printer for printer in db_session.query(Printer).filter(
|
||||
Printer.active == True,
|
||||
Printer.plug_ip.isnot(None)
|
||||
).all()
|
||||
).all()}
|
||||
|
||||
# Status aller Steckdosen abrufen - auch wenn sie nicht erreichbar sind
|
||||
# Status aller 6 konfigurierten Steckdosen abrufen
|
||||
outlets_status = {}
|
||||
online_count = 0
|
||||
|
||||
for printer in printers_with_tapo:
|
||||
# Gehe durch alle 6 festen Steckdosen-IPs
|
||||
for i, tapo_ip in enumerate(DEFAULT_TAPO_IPS[:FIXED_PRINTER_COUNT], 1):
|
||||
try:
|
||||
tapo_logger.debug(f"Prüfe Tapo-Steckdose für Drucker {printer.name} ({printer.plug_ip})")
|
||||
reachable, status = tapo_controller.check_outlet_status(
|
||||
printer.plug_ip,
|
||||
printer_id=printer.id
|
||||
)
|
||||
# Prüfe ob Drucker in der Datenbank existiert
|
||||
db_printer = db_printers.get(tapo_ip)
|
||||
|
||||
if reachable:
|
||||
online_count += 1
|
||||
tapo_logger.info(f"✅ Tapo-Steckdose {printer.plug_ip} erreichbar - Status: {status}")
|
||||
if db_printer:
|
||||
# Drucker ist in der Datenbank - verwende echte Daten
|
||||
printer_name = db_printer.name
|
||||
printer_id = db_printer.id
|
||||
location = db_printer.location or f"Arbeitsplatz {i}"
|
||||
model = db_printer.model or "3D-Drucker"
|
||||
else:
|
||||
tapo_logger.warning(f"⚠️ Tapo-Steckdose {printer.plug_ip} nicht erreichbar")
|
||||
# Drucker nicht in der Datenbank - verwende Standardnamen
|
||||
printer_name = f"3D-Drucker {i}"
|
||||
printer_id = None
|
||||
location = f"Arbeitsplatz {i} (nicht konfiguriert)"
|
||||
model = "3D-Drucker"
|
||||
|
||||
outlets_status[printer.plug_ip] = {
|
||||
'printer_name': printer.name,
|
||||
'printer_id': printer.id,
|
||||
'ip': printer.plug_ip,
|
||||
tapo_logger.debug(f"Prüfe Tapo-Steckdose {i}: {tapo_ip} für {printer_name}")
|
||||
|
||||
# Status der Steckdose prüfen
|
||||
try:
|
||||
reachable, status = tapo_controller.check_outlet_status(
|
||||
tapo_ip,
|
||||
printer_id=printer_id
|
||||
)
|
||||
|
||||
if reachable:
|
||||
online_count += 1
|
||||
tapo_logger.info(f"✅ Steckdose {i} ({tapo_ip}) erreichbar - Status: {status}")
|
||||
else:
|
||||
tapo_logger.warning(f"⚠️ Steckdose {i} ({tapo_ip}) nicht erreichbar")
|
||||
|
||||
except Exception as status_error:
|
||||
tapo_logger.error(f"❌ Fehler beim Status-Check für Steckdose {i} ({tapo_ip}): {status_error}")
|
||||
reachable = False
|
||||
status = 'error'
|
||||
|
||||
# Steckdose zu den Ergebnissen hinzufügen
|
||||
outlets_status[tapo_ip] = {
|
||||
'printer_name': printer_name,
|
||||
'printer_id': printer_id,
|
||||
'ip': tapo_ip,
|
||||
'status': status,
|
||||
'reachable': reachable,
|
||||
'location': printer.location or "Unbekannt"
|
||||
'location': location,
|
||||
'model': model,
|
||||
'position': i, # Position für Sortierung
|
||||
'configured_in_db': db_printer is not None
|
||||
}
|
||||
|
||||
# Fehlermeldung hinzufügen falls nicht erreichbar
|
||||
if not reachable:
|
||||
outlets_status[tapo_ip]['error'] = f"Steckdose {i} ist offline oder nicht erreichbar"
|
||||
|
||||
except Exception as e:
|
||||
tapo_logger.error(f"❌ Fehler beim Status-Check für {printer.plug_ip}: {e}")
|
||||
outlets_status[printer.plug_ip] = {
|
||||
'printer_name': printer.name,
|
||||
'printer_id': printer.id,
|
||||
'ip': printer.plug_ip,
|
||||
tapo_logger.error(f"❌ Fehler beim Verarbeiten von Steckdose {i} ({tapo_ip}): {e}")
|
||||
outlets_status[tapo_ip] = {
|
||||
'printer_name': f"3D-Drucker {i}",
|
||||
'printer_id': None,
|
||||
'ip': tapo_ip,
|
||||
'status': 'error',
|
||||
'reachable': False,
|
||||
'location': printer.location or "Unbekannt",
|
||||
'error': str(e)
|
||||
'location': f"Arbeitsplatz {i} (Fehler)",
|
||||
'model': "3D-Drucker",
|
||||
'position': i,
|
||||
'configured_in_db': False,
|
||||
'error': f"Systemfehler: {str(e)}"
|
||||
}
|
||||
|
||||
db_session.close()
|
||||
|
||||
tapo_logger.info(f"Dashboard geladen: {len(outlets_status)} Steckdosen, {online_count} online")
|
||||
# Sortiere die Outlets nach Position
|
||||
sorted_outlets = dict(sorted(outlets_status.items(), key=lambda x: x[1]['position']))
|
||||
|
||||
tapo_logger.info(f"Dashboard geladen: {len(sorted_outlets)} Steckdosen konfiguriert, {online_count} online")
|
||||
|
||||
return render_template('tapo_control.html',
|
||||
outlets=outlets_status,
|
||||
total_outlets=len(outlets_status),
|
||||
online_outlets=online_count)
|
||||
outlets=sorted_outlets,
|
||||
total_outlets=len(sorted_outlets),
|
||||
online_outlets=online_count,
|
||||
fixed_layout=True) # Flag für festes Layout
|
||||
|
||||
except Exception as e:
|
||||
tapo_logger.error(f"Fehler beim Laden des Tapo-Dashboards: {e}")
|
||||
flash(f"Fehler beim Laden der Tapo-Steckdosen: {str(e)}", "error")
|
||||
return render_template('tapo_control.html', outlets={}, total_outlets=0, online_outlets=0)
|
||||
|
||||
# Auch bei Fehlern die 6 Standard-Steckdosen anzeigen
|
||||
error_outlets = {}
|
||||
for i in range(1, 7):
|
||||
tapo_ip = f"192.168.1.20{i}"
|
||||
error_outlets[tapo_ip] = {
|
||||
'printer_name': f"3D-Drucker {i}",
|
||||
'printer_id': None,
|
||||
'ip': tapo_ip,
|
||||
'status': 'error',
|
||||
'reachable': False,
|
||||
'location': f"Arbeitsplatz {i}",
|
||||
'model': "3D-Drucker",
|
||||
'position': i,
|
||||
'configured_in_db': False,
|
||||
'error': "Systemfehler beim Laden"
|
||||
}
|
||||
|
||||
return render_template('tapo_control.html',
|
||||
outlets=error_outlets,
|
||||
total_outlets=6,
|
||||
online_outlets=0,
|
||||
fixed_layout=True)
|
||||
|
||||
@tapo_blueprint.route("/control", methods=["POST"])
|
||||
@login_required
|
||||
@ -382,4 +454,85 @@ def manual_control():
|
||||
except Exception as e:
|
||||
tapo_logger.error(f"Fehler bei manueller Steuerung: {e}")
|
||||
flash(f'Fehler: {str(e)}', 'error')
|
||||
return redirect(url_for('tapo.manual_control'))
|
||||
return redirect(url_for('tapo.manual_control'))
|
||||
|
||||
@tapo_blueprint.route("/control-form", methods=["POST"])
|
||||
@login_required
|
||||
@require_permission(Permission.CONTROL_PRINTER)
|
||||
def control_outlet_form():
|
||||
"""Formular-basierte Steckdosen-Steuerung ohne JavaScript."""
|
||||
try:
|
||||
ip = request.form.get('ip')
|
||||
action = request.form.get('action') # 'on' oder 'off'
|
||||
|
||||
if not ip or not action:
|
||||
flash('IP-Adresse und Aktion sind erforderlich', 'error')
|
||||
return redirect(url_for('tapo.tapo_dashboard'))
|
||||
|
||||
# IP-Adresse validieren
|
||||
try:
|
||||
ipaddress.ip_address(ip)
|
||||
except ValueError:
|
||||
flash('Ungültige IP-Adresse', 'error')
|
||||
return redirect(url_for('tapo.tapo_dashboard'))
|
||||
|
||||
if action not in ['on', 'off']:
|
||||
flash('Ungültige Aktion. Nur "on" oder "off" erlaubt.', 'error')
|
||||
return redirect(url_for('tapo.tapo_dashboard'))
|
||||
|
||||
# Steckdose schalten
|
||||
state = action == 'on'
|
||||
success = tapo_controller.toggle_plug(ip, state)
|
||||
|
||||
if success:
|
||||
action_text = "eingeschaltet" if state else "ausgeschaltet"
|
||||
flash(f'Steckdose {ip} erfolgreich {action_text}', 'success')
|
||||
tapo_logger.info(f"✅ Steckdose {ip} erfolgreich {action_text} durch {current_user.name} (Formular)")
|
||||
else:
|
||||
action_text = "einschalten" if state else "ausschalten"
|
||||
flash(f'Fehler beim {action_text} der Steckdose {ip}', 'error')
|
||||
tapo_logger.error(f"❌ Fehler beim {action_text} der Steckdose {ip} durch {current_user.name}")
|
||||
|
||||
return redirect(url_for('tapo.tapo_dashboard'))
|
||||
|
||||
except Exception as e:
|
||||
tapo_logger.error(f"Unerwarteter Fehler bei Formular-Steckdosen-Steuerung: {e}")
|
||||
flash(f'Systemfehler: {str(e)}', 'error')
|
||||
return redirect(url_for('tapo.tapo_dashboard'))
|
||||
|
||||
@tapo_blueprint.route("/test-connection-form", methods=["POST"])
|
||||
@login_required
|
||||
@require_permission(Permission.CONTROL_PRINTER)
|
||||
def test_connection_form():
|
||||
"""Formular-basierter Verbindungstest ohne JavaScript."""
|
||||
try:
|
||||
ip = request.form.get('ip')
|
||||
|
||||
if not ip:
|
||||
flash('IP-Adresse ist erforderlich', 'error')
|
||||
return redirect(url_for('tapo.tapo_dashboard'))
|
||||
|
||||
# IP-Adresse validieren
|
||||
try:
|
||||
ipaddress.ip_address(ip)
|
||||
except ValueError:
|
||||
flash('Ungültige IP-Adresse', 'error')
|
||||
return redirect(url_for('tapo.tapo_dashboard'))
|
||||
|
||||
# Verbindung testen
|
||||
test_result = tapo_controller.test_connection(ip)
|
||||
|
||||
if test_result.get('success', False):
|
||||
flash(f'✅ Verbindung zu {ip} erfolgreich!', 'success')
|
||||
tapo_logger.info(f"✅ Verbindungstest zu {ip} erfolgreich - {current_user.name}")
|
||||
else:
|
||||
error_msg = test_result.get('error', 'Unbekannter Fehler')
|
||||
flash(f'❌ Verbindung zu {ip} fehlgeschlagen: {error_msg}', 'error')
|
||||
tapo_logger.warning(f"❌ Verbindungstest zu {ip} fehlgeschlagen - {current_user.name}: {error_msg}")
|
||||
|
||||
return redirect(url_for('tapo.tapo_dashboard'))
|
||||
|
||||
except Exception as e:
|
||||
tapo_logger.error(f"Fehler beim Formular-Verbindungstest: {e}")
|
||||
flash(f'Fehler beim Verbindungstest: {str(e)}', 'error')
|
||||
return redirect(url_for('tapo.tapo_dashboard'))
|
@ -31,28 +31,28 @@ TAPO_PASSWORD = "744563017196A"
|
||||
# Automatische Steckdosen-Erkennung aktivieren
|
||||
TAPO_AUTO_DISCOVERY = True
|
||||
|
||||
# Standard-Steckdosen-IPs (diese können später in der Datenbank überschrieben werden)
|
||||
# Standard-Steckdosen-IPs (Mercedes-Benz TBA Marienfelde - 6 feste Arbeitsplätze)
|
||||
DEFAULT_TAPO_IPS = [
|
||||
"192.168.0.103", # Erreichbare Steckdose laut Test
|
||||
"192.168.0.104", # Erreichbare Steckdose laut Test
|
||||
"192.168.0.100",
|
||||
"192.168.0.101",
|
||||
"192.168.0.102",
|
||||
"192.168.0.106"
|
||||
"192.168.1.201", # 3D-Drucker 1 - Halle A, Arbeitsplatz 1
|
||||
"192.168.1.202", # 3D-Drucker 2 - Halle A, Arbeitsplatz 2
|
||||
"192.168.1.203", # 3D-Drucker 3 - Halle B, Arbeitsplatz 1
|
||||
"192.168.1.204", # 3D-Drucker 4 - Halle B, Arbeitsplatz 2
|
||||
"192.168.1.205", # 3D-Drucker 5 - Labor, SLA-Bereich
|
||||
"192.168.1.206" # 3D-Drucker 6 - Werkstatt, Spezialbereich
|
||||
]
|
||||
|
||||
# Timeout-Konfiguration für Tapo-Verbindungen
|
||||
TAPO_TIMEOUT = 10 # Sekunden
|
||||
TAPO_RETRY_COUNT = 3 # Anzahl Wiederholungsversuche
|
||||
|
||||
# Drucker-Konfiguration
|
||||
# Drucker-Konfiguration mit korrekten IPs
|
||||
PRINTERS = {
|
||||
"Printer 1": {"ip": "192.168.0.100"},
|
||||
"Printer 2": {"ip": "192.168.0.101"},
|
||||
"Printer 3": {"ip": "192.168.0.102"},
|
||||
"Printer 4": {"ip": "192.168.0.103"},
|
||||
"Printer 5": {"ip": "192.168.0.104"},
|
||||
"Printer 6": {"ip": "192.168.0.106"}
|
||||
"3D-Drucker 1 - Halle A": {"ip": "192.168.1.101", "plug_ip": "192.168.1.201"},
|
||||
"3D-Drucker 2 - Halle A": {"ip": "192.168.1.102", "plug_ip": "192.168.1.202"},
|
||||
"3D-Drucker 3 - Halle B": {"ip": "192.168.1.103", "plug_ip": "192.168.1.203"},
|
||||
"3D-Drucker 4 - Halle B": {"ip": "192.168.1.104", "plug_ip": "192.168.1.204"},
|
||||
"3D-Drucker 5 - Labor": {"ip": "192.168.1.105", "plug_ip": "192.168.1.205"},
|
||||
"3D-Drucker 6 - Werkstatt": {"ip": "192.168.1.106", "plug_ip": "192.168.1.206"}
|
||||
}
|
||||
|
||||
# Logging-Konfiguration
|
||||
@ -91,6 +91,10 @@ SCHEDULER_ENABLED = True
|
||||
# Datenbank-Konfiguration
|
||||
DB_ENGINE = f"sqlite:///{DATABASE_PATH}"
|
||||
|
||||
# Mercedes-Benz TBA spezifische Konfiguration
|
||||
FIXED_PRINTER_COUNT = 6 # Immer 6 feste Arbeitsplätze anzeigen
|
||||
ALWAYS_SHOW_ALL_SOCKETS = True # Alle 6 Steckdosen immer anzeigen, auch wenn offline
|
||||
|
||||
def get_log_file(category: str) -> str:
|
||||
"""
|
||||
Gibt den Pfad zur Log-Datei für eine bestimmte Kategorie zurück.
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -18387,3 +18387,282 @@ WHERE users.id = ?
|
||||
2025-06-12 11:15:37 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:16:33 - [app] app - [DEBUG] DEBUG - Request: GET /api/notifications
|
||||
2025-06-12 11:16:33 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:20 - [app] app - [WARNING] WARNING - DatabaseCleanupManager nicht verfügbar - Fallback auf Legacy-Cleanup
|
||||
2025-06-12 11:21:20 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP DEVELOPMENT-Umgebung
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] 🏢 Mercedes-Benz TBA Marienfelde
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped: True
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
|
||||
2025-06-12 11:21:24 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://0.0.0.0:5000
|
||||
2025-06-12 11:21:25 - [app] app - [WARNING] WARNING - DatabaseCleanupManager nicht verfügbar - Fallback auf Legacy-Cleanup
|
||||
2025-06-12 11:21:25 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP DEVELOPMENT-Umgebung
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [STARTUP] 🏢 Mercedes-Benz TBA Marienfelde
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped: True
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
|
||||
2025-06-12 11:21:26 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://0.0.0.0:5000
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - Locating template 'dashboard.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\dashboard.html')
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - Locating template 'base.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\base.html')
|
||||
2025-06-12 11:21:27 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/static/css/navbar-improved.css
|
||||
2025-06-12 11:21:27 - [app] app - [INFO] INFO - Locating template 'errors/404.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\errors\\404.html')
|
||||
2025-06-12 11:21:27 - [app] app - [DEBUG] DEBUG - Request: GET /api/notifications
|
||||
2025-06-12 11:21:27 - [app] app - [DEBUG] DEBUG - Request: GET /api/printers/monitor/live-status
|
||||
2025-06-12 11:21:27 - [app] app - [DEBUG] DEBUG - Request: GET /api/session/status
|
||||
2025-06-12 11:21:27 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:27 - [app] app - [DEBUG] DEBUG - Request: GET /api/user/settings
|
||||
2025-06-12 11:21:27 - [app] app - [DEBUG] DEBUG - Response: 500
|
||||
2025-06-12 11:21:27 - [app] app - [DEBUG] DEBUG - Response: 500
|
||||
2025-06-12 11:21:27 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:33 - [app] app - [DEBUG] DEBUG - Request: GET /tapo/
|
||||
2025-06-12 11:21:33 - [app] app - [INFO] INFO - Locating template 'tapo_control.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\tapo_control.html')
|
||||
2025-06-12 11:21:33 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:33 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/static/css/navbar-improved.css
|
||||
2025-06-12 11:21:33 - [app] app - [DEBUG] DEBUG - Request: GET /api/notifications
|
||||
2025-06-12 11:21:33 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:33 - [app] app - [DEBUG] DEBUG - Request: GET /api/session/status
|
||||
2025-06-12 11:21:33 - [app] app - [DEBUG] DEBUG - Request: GET /api/user/settings
|
||||
2025-06-12 11:21:33 - [app] app - [DEBUG] DEBUG - Response: 500
|
||||
2025-06-12 11:21:33 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:34 - [app] app - [DEBUG] DEBUG - Request: GET /jobs
|
||||
2025-06-12 11:21:34 - [app] app - [INFO] INFO - Locating template 'jobs.html':
|
||||
1: trying loader of application '__main__'
|
||||
class: jinja2.loaders.FileSystemLoader
|
||||
encoding: 'utf-8'
|
||||
followlinks: False
|
||||
searchpath:
|
||||
- C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates
|
||||
-> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\jobs.html')
|
||||
2025-06-12 11:21:34 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:34 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/static/css/navbar-improved.css
|
||||
2025-06-12 11:21:34 - [app] app - [DEBUG] DEBUG - Request: GET /api/notifications
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Request: GET /api/session/status
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Request: GET /api/user/settings
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Response: 500
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Request: GET /api/printers
|
||||
2025-06-12 11:21:35 - [app] app - [INFO] INFO - ✅ API: 0 Drucker abgerufen
|
||||
2025-06-12 11:21:35 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:21:50 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:21:50 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:22:05 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:22:05 - [app] app - [DEBUG] DEBUG - Request: GET /api/notifications
|
||||
2025-06-12 11:22:05 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:22:05 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:22:05 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:22:05 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:22:20 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:22:20 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:22:35 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:22:35 - [app] app - [DEBUG] DEBUG - Request: GET /api/notifications
|
||||
2025-06-12 11:22:35 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:22:35 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:22:35 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:22:35 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:22:50 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:22:50 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:23:05 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:23:05 - [app] app - [DEBUG] DEBUG - Request: GET /api/notifications
|
||||
2025-06-12 11:23:05 - [app] app - [DEBUG] DEBUG - Request: GET /api/jobs
|
||||
2025-06-12 11:23:05 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:23:05 - [app] app - [DEBUG] DEBUG - Response: 200
|
||||
2025-06-12 11:23:05 - [app] app - [DEBUG] DEBUG - Response: 500
|
||||
2025-06-12 11:23:05 - [app] app - [INFO] INFO - [SHUTDOWN] 🧹 Cleanup wird ausgeführt...
|
||||
2025-06-12 11:23:05 - [app] app - [INFO] INFO - [SHUTDOWN] ✅ Queue Manager gestoppt
|
||||
2025-06-12 11:23:05 - [app] app - [ERROR] ERROR - [SHUTDOWN] ❌ Cleanup-Fehler: 'BackgroundTaskScheduler' object has no attribute 'shutdown'
|
||||
2025-06-12 11:23:06 - [app] app - [WARNING] WARNING - DatabaseCleanupManager nicht verfügbar - Fallback auf Legacy-Cleanup
|
||||
2025-06-12 11:23:06 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP DEVELOPMENT-Umgebung
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] 🏢 Mercedes-Benz TBA Marienfelde
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped: True
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
|
||||
2025-06-12 11:23:07 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://0.0.0.0:5000
|
||||
2025-06-12 11:24:17 - [app] app - [INFO] INFO - [SHUTDOWN] 🧹 Cleanup wird ausgeführt...
|
||||
2025-06-12 11:24:17 - [app] app - [INFO] INFO - [SHUTDOWN] ✅ Queue Manager gestoppt
|
||||
2025-06-12 11:24:17 - [app] app - [ERROR] ERROR - [SHUTDOWN] ❌ Cleanup-Fehler: 'BackgroundTaskScheduler' object has no attribute 'shutdown'
|
||||
2025-06-12 11:24:18 - [app] app - [WARNING] WARNING - DatabaseCleanupManager nicht verfügbar - Fallback auf Legacy-Cleanup
|
||||
2025-06-12 11:24:18 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP DEVELOPMENT-Umgebung
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] 🏢 Mercedes-Benz TBA Marienfelde
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped: True
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
|
||||
2025-06-12 11:24:19 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://0.0.0.0:5000
|
||||
2025-06-12 11:24:46 - [app] app - [INFO] INFO - [SHUTDOWN] 🧹 Cleanup wird ausgeführt...
|
||||
2025-06-12 11:24:46 - [app] app - [INFO] INFO - [SHUTDOWN] ✅ Queue Manager gestoppt
|
||||
2025-06-12 11:24:46 - [app] app - [ERROR] ERROR - [SHUTDOWN] ❌ Cleanup-Fehler: 'BackgroundTaskScheduler' object has no attribute 'shutdown'
|
||||
2025-06-12 11:24:47 - [app] app - [WARNING] WARNING - DatabaseCleanupManager nicht verfügbar - Fallback auf Legacy-Cleanup
|
||||
2025-06-12 11:24:47 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP DEVELOPMENT-Umgebung
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] 🏢 Mercedes-Benz TBA Marienfelde
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped: True
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
|
||||
2025-06-12 11:24:48 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://0.0.0.0:5000
|
||||
2025-06-12 11:26:13 - [app] app - [INFO] INFO - [SHUTDOWN] 🧹 Cleanup wird ausgeführt...
|
||||
2025-06-12 11:26:13 - [app] app - [INFO] INFO - [SHUTDOWN] ✅ Queue Manager gestoppt
|
||||
2025-06-12 11:26:13 - [app] app - [ERROR] ERROR - [SHUTDOWN] ❌ Cleanup-Fehler: 'BackgroundTaskScheduler' object has no attribute 'shutdown'
|
||||
2025-06-12 11:26:14 - [app] app - [WARNING] WARNING - DatabaseCleanupManager nicht verfügbar - Fallback auf Legacy-Cleanup
|
||||
2025-06-12 11:26:14 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] 🚀 Starte MYP DEVELOPMENT-Umgebung
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] 🏢 Mercedes-Benz TBA Marienfelde
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] 🔒 Air-Gapped: True
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] Initialisiere Datenbank...
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] ✅ Datenbank initialisiert
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] Prüfe Initial-Admin...
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] ✅ Admin-Benutzer geprüft
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] Starte Queue Manager...
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] ✅ Queue Manager gestartet
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] Starte Job Scheduler...
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] ✅ Job Scheduler gestartet
|
||||
2025-06-12 11:26:15 - [app] app - [INFO] INFO - [STARTUP] 🌐 Server startet auf http://0.0.0.0:5000
|
||||
2025-06-12 11:26:32 - [app] app - [WARNING] WARNING - DatabaseCleanupManager nicht verfügbar - Fallback auf Legacy-Cleanup
|
||||
2025-06-12 11:26:32 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: backend/database/myp.db
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - [CONFIG] Erkannte Umgebung: development
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - [CONFIG] Production-Modus: False
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - [CONFIG] Verwende Development-Konfiguration
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - [DEVELOPMENT] Aktiviere Development-Konfiguration
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ MYP Development Environment Konfiguration aktiviert
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Environment: Development/Testing
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ Debug Mode: True
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - [DEVELOPMENT] ✅ SQL Echo: True
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
|
||||
2025-06-12 11:26:33 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-12 11:26:35 - [app] app - [INFO] INFO - Steckdosen-Status geloggt: Drucker 1, Status: unreachable, Quelle: system
|
||||
2025-06-12 11:26:37 - [app] app - [INFO] INFO - Steckdosen-Status geloggt: Drucker 2, Status: unreachable, Quelle: system
|
||||
2025-06-12 11:26:39 - [app] app - [INFO] INFO - Steckdosen-Status geloggt: Drucker 3, Status: unreachable, Quelle: system
|
||||
2025-06-12 11:26:41 - [app] app - [INFO] INFO - Steckdosen-Status geloggt: Drucker 4, Status: unreachable, Quelle: system
|
||||
2025-06-12 11:26:43 - [app] app - [INFO] INFO - Steckdosen-Status geloggt: Drucker 5, Status: unreachable, Quelle: system
|
||||
2025-06-12 11:26:46 - [app] app - [INFO] INFO - Steckdosen-Status geloggt: Drucker 6, Status: unreachable, Quelle: system
|
||||
|
@ -100,3 +100,17 @@
|
||||
2025-06-12 11:00:40 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-12 11:00:45 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-12 11:00:45 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-12 11:21:20 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-12 11:21:20 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-12 11:21:25 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-12 11:21:25 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-12 11:23:06 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-12 11:23:06 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-12 11:24:18 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-12 11:24:18 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-12 11:24:47 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-12 11:24:47 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-12 11:26:14 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-12 11:26:14 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
2025-06-12 11:26:32 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert
|
||||
2025-06-12 11:26:32 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion)
|
||||
|
@ -100,3 +100,17 @@
|
||||
2025-06-12 11:00:40 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:00:45 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-12 11:00:45 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:21:21 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-12 11:21:21 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:21:25 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-12 11:21:25 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:23:06 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-12 11:23:06 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:24:18 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-12 11:24:18 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:24:47 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-12 11:24:47 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:26:14 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-12 11:26:14 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:26:32 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert
|
||||
2025-06-12 11:26:32 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
|
@ -206,3 +206,31 @@
|
||||
2025-06-12 11:00:45 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-12 11:00:45 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-12 11:00:45 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-12 11:21:21 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-12 11:21:21 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-12 11:21:21 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-12 11:21:21 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-12 11:21:25 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-12 11:21:25 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-12 11:21:25 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-12 11:21:25 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-12 11:23:06 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-12 11:23:06 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-12 11:23:06 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-12 11:23:06 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-12 11:24:18 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-12 11:24:18 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-12 11:24:18 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-12 11:24:18 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-12 11:24:47 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-12 11:24:47 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-12 11:24:47 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-12 11:24:47 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-12 11:26:14 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-12 11:26:14 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-12 11:26:14 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-12 11:26:14 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
2025-06-12 11:26:32 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar
|
||||
2025-06-12 11:26:32 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert
|
||||
2025-06-12 11:26:32 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert
|
||||
2025-06-12 11:26:32 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion)
|
||||
|
@ -195,3 +195,27 @@
|
||||
2025-06-12 11:00:49 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-12 11:18:03 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-12 11:18:03 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-12 11:21:21 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-12 11:21:21 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
2025-06-12 11:21:24 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-12 11:21:25 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-12 11:21:25 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
2025-06-12 11:21:27 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-12 11:23:05 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-12 11:23:06 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-12 11:23:06 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
2025-06-12 11:23:07 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-12 11:24:17 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-12 11:24:18 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-12 11:24:18 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
2025-06-12 11:24:19 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-12 11:24:46 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-12 11:24:47 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-12 11:24:47 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
2025-06-12 11:24:48 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-12 11:26:13 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität)
|
||||
2025-06-12 11:26:14 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-12 11:26:14 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
2025-06-12 11:26:15 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität)
|
||||
2025-06-12 11:26:32 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert
|
||||
2025-06-12 11:26:32 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion)
|
||||
|
@ -159,3 +159,95 @@ TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
|
||||
2025-06-12 11:04:10 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:04:10 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:04:10 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:21:35 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:21:35 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:21:35 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:21:35 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:21:50 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:21:50 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:22:05 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:22:05 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:22:05 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:22:05 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:22:20 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:22:20 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:22:35 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:22:35 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:22:35 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:22:35 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:22:50 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:22:50 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:23:05 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:23:05 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:23:05 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:23:05 - [jobs] jobs - [ERROR] ERROR - ❌ Fehler beim Abrufen von Jobs: tuple index out of range
|
||||
Traceback (most recent call last):
|
||||
File "C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\blueprints\jobs.py", line 88, in get_jobs
|
||||
total_count = query.count()
|
||||
File "C:\Users\TTOMCZA.EMEA\AppData\Roaming\Python\Python313\site-packages\sqlalchemy\orm\query.py", line 3113, in count
|
||||
self._legacy_from_self(col).enable_eagerloads(False).scalar()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
|
||||
File "C:\Users\TTOMCZA.EMEA\AppData\Roaming\Python\Python313\site-packages\sqlalchemy\orm\query.py", line 2805, in scalar
|
||||
ret = self.one()
|
||||
File "C:\Users\TTOMCZA.EMEA\AppData\Roaming\Python\Python313\site-packages\sqlalchemy\orm\query.py", line 2778, in one
|
||||
return self._iter().one() # type: ignore
|
||||
~~~~~~~~~~~~~~~~^^
|
||||
File "C:\Users\TTOMCZA.EMEA\AppData\Roaming\Python\Python313\site-packages\sqlalchemy\engine\result.py", line 1520, in one
|
||||
return self._only_one_row(
|
||||
~~~~~~~~~~~~~~~~~~^
|
||||
raise_for_second_row=True, raise_for_none=True, scalar=False
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
)
|
||||
^
|
||||
File "C:\Users\TTOMCZA.EMEA\AppData\Roaming\Python\Python313\site-packages\sqlalchemy\engine\result.py", line 749, in _only_one_row
|
||||
row: Optional[_InterimRowType[Any]] = onerow(hard_close=True)
|
||||
~~~~~~^^^^^^^^^^^^^^^^^
|
||||
File "C:\Users\TTOMCZA.EMEA\AppData\Roaming\Python\Python313\site-packages\sqlalchemy\engine\result.py", line 2259, in _fetchone_impl
|
||||
row = next(self.iterator, _NO_ROW)
|
||||
File "C:\Users\TTOMCZA.EMEA\AppData\Roaming\Python\Python313\site-packages\sqlalchemy\orm\loading.py", line 226, in chunks
|
||||
tuple([proc(row) for proc in process]) for row in fetch
|
||||
~~~~^^^^^
|
||||
File "lib\\sqlalchemy\\cyextension\\resultproxy.pyx", line 54, in sqlalchemy.cyextension.resultproxy.BaseRow.__getitem__
|
||||
IndexError: tuple index out of range
|
||||
2025-06-12 11:23:20 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:23:20 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:23:35 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:23:35 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:23:35 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:23:35 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:23:50 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:23:50 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:24:05 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:24:05 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:24:35 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:24:35 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:24:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:24:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:25:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:25:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:25:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:25:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:26:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:26:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:26:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:26:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:27:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:27:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:27:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:27:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:28:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:28:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:28:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:28:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:29:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:29:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:29:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:29:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:30:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:30:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:30:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:30:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:31:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:31:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-12 11:31:37 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True)
|
||||
2025-06-12 11:31:37 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1)
|
||||
|
@ -100,3 +100,17 @@
|
||||
2025-06-12 11:00:42 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:00:48 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-12 11:00:48 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:21:24 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-12 11:21:24 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:21:26 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-12 11:21:26 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:23:07 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-12 11:23:07 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:24:19 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-12 11:24:19 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:24:48 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-12 11:24:48 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:26:15 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-12 11:26:15 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:26:33 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert
|
||||
2025-06-12 11:26:33 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
|
@ -256,3 +256,6 @@
|
||||
2025-06-12 11:04:05 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-12 11:04:05 - [printers] printers - [ERROR] ERROR - ❌ Fehler bei Live-Status-Abfrage: PrinterMonitor.get_live_printer_status() got an unexpected keyword argument 'use_session_cache'
|
||||
2025-06-12 11:04:05 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.16ms
|
||||
2025-06-12 11:21:27 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-12 11:21:27 - [printers] printers - [ERROR] ERROR - ❌ Fehler bei Live-Status-Abfrage: PrinterMonitor.get_live_printer_status() got an unexpected keyword argument 'use_session_cache'
|
||||
2025-06-12 11:21:27 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.52ms
|
||||
|
@ -145,3 +145,22 @@
|
||||
2025-06-12 11:00:45 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-12 11:00:49 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-12 11:00:49 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-12 11:21:21 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-12 11:21:24 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-12 11:21:24 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-12 11:21:25 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-12 11:21:27 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-12 11:21:27 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-12 11:23:06 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-12 11:23:07 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-12 11:23:07 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-12 11:24:18 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-12 11:24:19 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-12 11:24:19 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-12 11:24:47 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-12 11:24:48 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-12 11:24:48 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-12 11:26:14 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-12 11:26:15 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-12 11:26:15 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-12 11:26:32 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
|
@ -151,3 +151,24 @@
|
||||
2025-06-12 11:00:45 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-12 11:00:45 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:00:48 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-12 11:21:21 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-12 11:21:21 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:21:24 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-12 11:21:25 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-12 11:21:25 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:21:26 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-12 11:23:06 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-12 11:23:06 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:23:07 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-12 11:24:18 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-12 11:24:18 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:24:19 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-12 11:24:47 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-12 11:24:47 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:24:48 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-12 11:26:14 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-12 11:26:14 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:26:15 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
2025-06-12 11:26:32 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert
|
||||
2025-06-12 11:26:32 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion)
|
||||
2025-06-12 11:26:33 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert
|
||||
|
@ -70,3 +70,6 @@
|
||||
2025-06-12 11:04:05 - [sessions] sessions - [ERROR] ERROR - Fehler beim Abrufen des Session-Status: 'int' object has no attribute 'total_seconds'
|
||||
2025-06-12 11:04:10 - [sessions] sessions - [ERROR] ERROR - Fehler beim Abrufen des Session-Status: 'int' object has no attribute 'total_seconds'
|
||||
2025-06-12 11:04:11 - [sessions] sessions - [ERROR] ERROR - Fehler beim Abrufen des Session-Status: 'int' object has no attribute 'total_seconds'
|
||||
2025-06-12 11:21:27 - [sessions] sessions - [ERROR] ERROR - Fehler beim Abrufen des Session-Status: 'int' object has no attribute 'total_seconds'
|
||||
2025-06-12 11:21:33 - [sessions] sessions - [ERROR] ERROR - Fehler beim Abrufen des Session-Status: 'int' object has no attribute 'total_seconds'
|
||||
2025-06-12 11:21:35 - [sessions] sessions - [ERROR] ERROR - Fehler beim Abrufen des Session-Status: 'int' object has no attribute 'total_seconds'
|
||||
|
@ -457,3 +457,66 @@
|
||||
2025-06-12 11:00:48 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-12 11:00:48 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-12 11:00:48 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:21:24 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:21:24 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-12 11:21:24 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-12 11:21:24 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-12 11:21:24 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-12 11:21:24 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-12T11:21:24.383346
|
||||
2025-06-12 11:21:24 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-12 11:21:24 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-12 11:21:24 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:21:26 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:21:26 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-12 11:21:26 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-12 11:21:26 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-12 11:21:26 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-12 11:21:26 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-12T11:21:26.706966
|
||||
2025-06-12 11:21:26 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-12 11:21:26 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-12 11:21:26 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:23:07 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:23:07 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-12 11:23:07 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-12 11:23:07 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-12 11:23:07 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-12 11:23:07 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-12T11:23:07.517725
|
||||
2025-06-12 11:23:07 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-12 11:23:07 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-12 11:23:07 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:24:19 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:24:19 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-12 11:24:19 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-12 11:24:19 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-12 11:24:19 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-12 11:24:19 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-12T11:24:19.571504
|
||||
2025-06-12 11:24:19 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-12 11:24:19 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-12 11:24:19 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:24:48 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:24:48 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-12 11:24:48 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-12 11:24:48 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-12 11:24:48 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-12 11:24:48 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-12T11:24:48.617781
|
||||
2025-06-12 11:24:48 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-12 11:24:48 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-12 11:24:48 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:26:15 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:26:15 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-12 11:26:15 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-12 11:26:15 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-12 11:26:15 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-12 11:26:15 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-12T11:26:15.091289
|
||||
2025-06-12 11:26:15 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-12 11:26:15 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-12 11:26:15 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:26:33 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-12 11:26:33 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||
2025-06-12 11:26:33 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-12 11:26:33 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-12 11:26:33 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-12 11:26:33 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-12T11:26:33.239746
|
||||
2025-06-12 11:26:33 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-12 11:26:33 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-12 11:26:33 - [startup] startup - [INFO] INFO - ==================================================
|
||||
|
@ -27,3 +27,5 @@
|
||||
2025-06-12 11:03:50 - [tapo_control] tapo_control - [INFO] INFO - Dashboard geladen: 0 Steckdosen, 0 online
|
||||
2025-06-12 11:04:11 - [tapo_control] tapo_control - [INFO] INFO - Tapo Dashboard aufgerufen von Benutzer: Administrator
|
||||
2025-06-12 11:04:11 - [tapo_control] tapo_control - [INFO] INFO - Dashboard geladen: 0 Steckdosen, 0 online
|
||||
2025-06-12 11:21:33 - [tapo_control] tapo_control - [INFO] INFO - Tapo Dashboard aufgerufen von Benutzer: Administrator
|
||||
2025-06-12 11:21:33 - [tapo_control] tapo_control - [INFO] INFO - Dashboard geladen: 0 Steckdosen, 0 online
|
||||
|
@ -50,3 +50,10 @@
|
||||
2025-06-12 10:49:30 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 11:00:40 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 11:00:45 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 11:21:21 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 11:21:25 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 11:23:06 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 11:24:18 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 11:24:47 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 11:26:14 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
2025-06-12 11:26:32 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||
|
@ -8,3 +8,10 @@
|
||||
2025-06-12 10:49:30 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 11:00:40 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 11:00:45 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 11:21:21 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 11:21:25 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 11:23:06 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 11:24:18 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 11:24:47 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 11:26:14 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
2025-06-12 11:26:32 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert
|
||||
|
@ -62,3 +62,65 @@
|
||||
2025-06-12 10:02:18 - [test_printer_setup] test_printer_setup - [INFO] INFO - ❓ Unbekannt: 0
|
||||
2025-06-12 10:02:37 - [test_printer_setup] test_printer_setup - [INFO] INFO -
|
||||
✅ Test abgeschlossen!
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - ============================================================
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🏭 Mercedes-Benz 3D-Druck-Management - Drucker-Setup & Test
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - ============================================================
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🚀 Starte Drucker-Setup...
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📋 Erstelle Drucker 1/6: 3D-Drucker 1 - Halle A
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📋 Erstelle Drucker 2/6: 3D-Drucker 2 - Halle A
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📋 Erstelle Drucker 3/6: 3D-Drucker 3 - Halle B
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📋 Erstelle Drucker 4/6: 3D-Drucker 4 - Halle B
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📋 Erstelle Drucker 5/6: 3D-Drucker 5 - Labor
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📋 Erstelle Drucker 6/6: 3D-Drucker 6 - Werkstatt
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO - ✅ Alle 6 Drucker erfolgreich erstellt!
|
||||
2025-06-12 11:26:33 - [test_printer_setup] test_printer_setup - [INFO] INFO -
|
||||
🔍 Teste Drucker-Status...
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📊 Status für 6 Drucker abgerufen:
|
||||
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🖨️ 3D-Drucker 1 - Halle A
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📍 Standort: Halle A - Arbeitsplatz 1
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🔌 Steckdosen-IP: 192.168.1.201
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚡ Status: Nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ❌ Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚠️ Fehler: Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO -
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🖨️ 3D-Drucker 2 - Halle A
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📍 Standort: Halle A - Arbeitsplatz 2
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🔌 Steckdosen-IP: 192.168.1.202
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚡ Status: Nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ❌ Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚠️ Fehler: Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO -
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🖨️ 3D-Drucker 3 - Halle B
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📍 Standort: Halle B - Arbeitsplatz 1
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🔌 Steckdosen-IP: 192.168.1.203
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚡ Status: Nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ❌ Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚠️ Fehler: Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO -
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🖨️ 3D-Drucker 4 - Halle B
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📍 Standort: Halle B - Arbeitsplatz 2
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🔌 Steckdosen-IP: 192.168.1.204
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚡ Status: Nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ❌ Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚠️ Fehler: Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO -
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🖨️ 3D-Drucker 5 - Labor
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📍 Standort: Labor - SLA-Bereich
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🔌 Steckdosen-IP: 192.168.1.205
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚡ Status: Nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ❌ Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚠️ Fehler: Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO -
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🖨️ 3D-Drucker 6 - Werkstatt
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📍 Standort: Werkstatt - Spezialbereich
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 🔌 Steckdosen-IP: 192.168.1.206
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚡ Status: Nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ❌ Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⚠️ Fehler: Steckdose nicht erreichbar
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO -
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - 📈 Status-Zusammenfassung:
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ✅ Eingeschaltet: 0
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ⭕ Ausgeschaltet: 0
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ❌ Nicht erreichbar: 6
|
||||
2025-06-12 11:26:46 - [test_printer_setup] test_printer_setup - [INFO] INFO - ❓ Unbekannt: 0
|
||||
|
@ -68,3 +68,6 @@
|
||||
2025-06-12 11:04:05 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||
2025-06-12 11:04:10 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||
2025-06-12 11:04:11 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||
2025-06-12 11:21:27 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||
2025-06-12 11:21:33 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||
2025-06-12 11:21:35 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||
|
@ -104,3 +104,17 @@
|
||||
2025-06-12 11:00:40 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-12 11:00:45 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-12 11:00:45 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-12 11:21:20 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-12 11:21:20 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-12 11:21:25 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-12 11:21:25 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-12 11:23:06 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-12 11:23:06 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-12 11:24:18 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-12 11:24:18 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-12 11:24:47 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-12 11:24:47 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-12 11:26:14 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-12 11:26:14 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
2025-06-12 11:26:32 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert
|
||||
2025-06-12 11:26:32 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion)
|
||||
|
@ -103,3 +103,17 @@
|
||||
2025-06-12 11:00:40 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-12 11:00:45 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-12 11:00:45 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-12 11:21:20 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-12 11:21:20 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-12 11:21:25 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-12 11:21:25 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-12 11:23:06 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-12 11:23:06 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-12 11:24:18 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-12 11:24:18 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-12 11:24:47 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-12 11:24:47 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-12 11:26:14 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-12 11:26:14 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-12 11:26:32 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-12 11:26:32 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
|
@ -1,115 +0,0 @@
|
||||
/**
|
||||
* Simplified Mobile Navigation Handler
|
||||
* Minimaler Code für maximale Performance
|
||||
*/
|
||||
class SimpleMobileNav {
|
||||
constructor() {
|
||||
this.toggle = document.getElementById('mobileMenuToggle');
|
||||
this.menu = document.getElementById('mobileMenu');
|
||||
this.navbar = document.querySelector('.navbar');
|
||||
this.isOpen = false;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
if (!this.toggle || !this.menu) return;
|
||||
|
||||
// Toggle Button
|
||||
this.toggle.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
this.toggleMenu();
|
||||
});
|
||||
|
||||
// Close on outside click
|
||||
document.addEventListener('click', (e) => {
|
||||
if (this.isOpen && !this.menu.contains(e.target)) {
|
||||
this.closeMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Close on ESC
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && this.isOpen) {
|
||||
this.closeMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Close on resize to desktop
|
||||
let resizeTimer;
|
||||
window.addEventListener('resize', () => {
|
||||
clearTimeout(resizeTimer);
|
||||
resizeTimer = setTimeout(() => {
|
||||
if (window.innerWidth >= 1024 && this.isOpen) {
|
||||
this.closeMenu();
|
||||
}
|
||||
}, 250);
|
||||
});
|
||||
|
||||
// Simple scroll effect
|
||||
let lastScroll = 0;
|
||||
window.addEventListener('scroll', () => {
|
||||
const currentScroll = window.pageYOffset;
|
||||
|
||||
// Add/remove scrolled class
|
||||
if (currentScroll > 50) {
|
||||
this.navbar.classList.add('scrolled');
|
||||
} else {
|
||||
this.navbar.classList.remove('scrolled');
|
||||
}
|
||||
|
||||
lastScroll = currentScroll;
|
||||
}, { passive: true });
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
this.isOpen ? this.closeMenu() : this.openMenu();
|
||||
}
|
||||
|
||||
openMenu() {
|
||||
this.isOpen = true;
|
||||
this.menu.classList.remove('hidden');
|
||||
|
||||
// Force reflow
|
||||
this.menu.offsetHeight;
|
||||
|
||||
this.menu.classList.add('active');
|
||||
this.toggle.setAttribute('aria-expanded', 'true');
|
||||
|
||||
// Update icon
|
||||
const path = this.toggle.querySelector('svg path');
|
||||
if (path) path.setAttribute('d', 'M6 18L18 6M6 6l12 12');
|
||||
|
||||
// Prevent body scroll
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
closeMenu() {
|
||||
this.isOpen = false;
|
||||
this.menu.classList.remove('active');
|
||||
this.toggle.setAttribute('aria-expanded', 'false');
|
||||
|
||||
// Update icon
|
||||
const path = this.toggle.querySelector('svg path');
|
||||
if (path) path.setAttribute('d', 'M4 6h16M4 12h16M4 18h16');
|
||||
|
||||
// Restore body scroll
|
||||
document.body.style.overflow = '';
|
||||
|
||||
// Hide after transition
|
||||
setTimeout(() => {
|
||||
if (!this.isOpen) {
|
||||
this.menu.classList.add('hidden');
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize on DOM ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
window.mobileNav = new SimpleMobileNav();
|
||||
});
|
||||
} else {
|
||||
window.mobileNav = new SimpleMobileNav();
|
||||
}
|
@ -27,8 +27,8 @@
|
||||
|
||||
<!-- CSS - Performance Optimized -->
|
||||
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||
<!-- Verbesserte Navbar CSS ersetzt die alten Glassmorphism-Styles -->
|
||||
<link href="{{ url_for('static', filename='css/navbar-improved.css') }}" rel="stylesheet">
|
||||
<!-- Moderne Navbar CSS -->
|
||||
<link href="{{ url_for('static', filename='css/navbar.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/performance-optimized.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/components.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/professional-theme.min.css') }}" rel="stylesheet">
|
||||
@ -272,373 +272,8 @@
|
||||
|
||||
<body class="min-h-screen flex flex-col bg-white text-slate-900 dark:bg-black dark:text-white transition-colors duration-300 text-base mercedes-background">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar">
|
||||
<div class="max-w-7xl mx-auto px-3 sm:px-4 lg:px-6">
|
||||
<div class="flex items-center justify-between h-16 sm:h-18 lg:h-20">
|
||||
<!-- Brand Section -->
|
||||
<div class="flex-shrink-0">
|
||||
<a href="{{ url_for('dashboard') }}" class="navbar-brand group" aria-label="Zur Startseite">
|
||||
<!-- Mercedes-Benz Logo -->
|
||||
<div class="w-5 h-5 sm:w-6 sm:h-6 lg:w-7 lg:h-7">
|
||||
<svg class="w-full h-full text-slate-900 dark:text-white transition-colors duration-300" fill="currentColor" viewBox="0 0 80 80" aria-hidden="true">
|
||||
<path d="M58.6,4.5C53,1.6,46.7,0,40,0c-6.7,0-13,1.6-18.6,4.5v0C8.7,11.2,0,24.6,0,40c0,15.4,8.7,28.8,21.5,35.5
|
||||
C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40
|
||||
c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8
|
||||
C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9
|
||||
C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40
|
||||
c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Brand Text -->
|
||||
<div class="flex flex-col ml-3">
|
||||
<span class="text-sm lg:text-base font-bold text-slate-900 dark:text-white transition-colors duration-300 tracking-tight">Mercedes-Benz</span>
|
||||
<span class="text-xs font-medium text-slate-600 dark:text-slate-400 transition-colors duration-300">Manage Your Printer - </span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Navigation Menu - überarbeitetes Design -->
|
||||
<div class="hidden lg:flex flex-1 justify-center">
|
||||
<nav class="navbar-menu-new" role="navigation" aria-label="Hauptnavigation">
|
||||
<a href="{{ url_for('dashboard') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'dashboard' else '' }}">
|
||||
<i class="fas fa-tachometer-alt w-5 h-5"></i>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('printers_page') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'printers_page' else '' }}">
|
||||
<i class="fas fa-print w-5 h-5"></i>
|
||||
<span>Drucker</span>
|
||||
</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_permission('CONTROL_PRINTER') %}
|
||||
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'tapo.tapo_dashboard' else '' }}">
|
||||
<i class="fas fa-plug w-5 h-5"></i>
|
||||
<span>Tapo-Steckdosen</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<a href="{{ url_for('jobs_page') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'jobs_page' else '' }}">
|
||||
<i class="fas fa-clipboard-list w-5 h-5"></i>
|
||||
<span>Reservierungen</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('stats_page') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'stats_page' else '' }}">
|
||||
<i class="fas fa-chart-bar w-5 h-5"></i>
|
||||
<span>Statistiken</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('calendar.calendar_view') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'calendar.calendar_view' else '' }}">
|
||||
<i class="fas fa-calendar-alt w-5 h-5"></i>
|
||||
<span>Schichtplan</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_request_form') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'guest.guest_request_form' else '' }}">
|
||||
<i class="fas fa-user-plus w-5 h-5"></i>
|
||||
<span>Antrag stellen</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_requests_overview') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'guest.guest_requests_overview' else '' }}">
|
||||
<i class="fas fa-file-alt w-5 h-5"></i>
|
||||
<span>Meine Anträge</span>
|
||||
</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'admin.admin_dashboard' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
<span>Ausbilder-Bereich</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Rechte Seite der Navbar -->
|
||||
<div class="flex items-center space-x-2 sm:space-x-3">
|
||||
<!-- Mobile Menu Toggle (neu) -->
|
||||
<button
|
||||
id="mobileMenuToggle"
|
||||
class="lg:hidden p-2 rounded-full text-slate-700 dark:text-slate-300 hover:bg-slate-100/80 dark:hover:bg-slate-800/50"
|
||||
aria-label="Menü öffnen"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<!-- Benachrichtigungen - kompakteres Design -->
|
||||
<div class="relative">
|
||||
<button
|
||||
id="notificationToggle"
|
||||
class="relative p-1.5 rounded-full text-slate-700 dark:text-slate-300 hover:bg-slate-100/80 dark:hover:bg-slate-800/50 transition-all duration-200"
|
||||
aria-label="Benachrichtigungen anzeigen"
|
||||
title="Benachrichtigungen"
|
||||
>
|
||||
<i class="fas fa-bell text-lg"></i>
|
||||
<!-- Badge für ungelesene Benachrichtigungen -->
|
||||
<span id="notificationBadge" class="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full h-4 w-4 flex items-center justify-center font-medium hidden">
|
||||
0
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- Benachrichtigungs-Dropdown -->
|
||||
<div id="notificationDropdown" class="absolute right-0 mt-2 w-72 sm:w-80 bg-white dark:bg-slate-800 rounded-lg shadow-lg border border-slate-200 dark:border-slate-600 z-50 hidden">
|
||||
<div class="p-3 border-b border-slate-200 dark:border-slate-600">
|
||||
<h3 class="text-base font-semibold text-slate-900 dark:text-white">Benachrichtigungen</h3>
|
||||
</div>
|
||||
<div id="notificationList" class="max-h-80 overflow-y-auto">
|
||||
<div class="p-3 text-center text-slate-500 dark:text-slate-400 text-sm">
|
||||
Keine neuen Benachrichtigungen
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-2 border-t border-slate-200 dark:border-slate-600">
|
||||
<button id="markAllRead" class="w-full text-xs text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 transition-colors">
|
||||
Alle als gelesen markieren
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dark Mode Toggle - Clean and Modern -->
|
||||
<button
|
||||
class="dark-mode-toggle darkModeToggle"
|
||||
aria-label="Dark Mode umschalten"
|
||||
title="Design wechseln"
|
||||
>
|
||||
<span class="dark-mode-toggle-slider">
|
||||
<i class="fas fa-sun dark-mode-toggle-icon sun absolute inset-0 flex items-center justify-center"></i>
|
||||
<i class="fas fa-moon dark-mode-toggle-icon moon absolute inset-0 flex items-center justify-center opacity-0"></i>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- User Profile Dropdown - kompakteres Design -->
|
||||
<div class="relative" id="user-menu-container">
|
||||
<button
|
||||
id="user-menu-button"
|
||||
class="flex items-center space-x-1 rounded-full p-1 text-slate-700 dark:text-slate-300 hover:bg-slate-100/80 dark:hover:bg-slate-800/50 transition-all duration-200"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
aria-label="Benutzermenu öffnen"
|
||||
>
|
||||
<!-- Profile Avatar -->
|
||||
<div class="w-6 h-6 rounded-full bg-blue-500 flex items-center justify-center text-white text-xs font-medium">
|
||||
{{ current_user.email[0].upper() if current_user.email else 'U' }}
|
||||
</div>
|
||||
<!-- User Info (nur auf größeren Geräten) -->
|
||||
<div class="hidden sm:block text-left ml-1">
|
||||
<div class="text-xs font-medium text-slate-900 dark:text-white transition-colors duration-300">{{ current_user.email.split('@')[0] if current_user.email else 'Benutzer' }}</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<!-- User Menu Dropdown -->
|
||||
<div id="user-dropdown" class="absolute right-0 mt-2 w-64 bg-white dark:bg-slate-800 rounded-lg shadow-lg border border-slate-200 dark:border-slate-600 z-50 hidden origin-top-right">
|
||||
<!-- User Info Header -->
|
||||
<div class="px-4 py-3 border-b border-slate-200 dark:border-slate-600">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center text-white font-medium">
|
||||
{{ current_user.email[0].upper() if current_user.email else 'U' }}
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<p class="text-sm font-medium text-slate-900 dark:text-white truncate">
|
||||
{{ current_user.full_name if current_user.full_name else current_user.email.split('@')[0] if current_user.email else 'Benutzer' }}
|
||||
</p>
|
||||
<p class="text-xs text-slate-500 dark:text-slate-400 truncate">
|
||||
{{ current_user.email if current_user.email else 'Keine E-Mail' }}
|
||||
</p>
|
||||
{% if current_user.is_admin %}
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200 mt-1">
|
||||
Ausbilder
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Menu Items -->
|
||||
<div class="py-1">
|
||||
<a href="{{ url_for('users.user_profile') }}"
|
||||
class="flex items-center px-4 py-2 text-sm text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors duration-200">
|
||||
<svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
||||
</svg>
|
||||
Mein Profil
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('users.user_settings') }}"
|
||||
class="flex items-center px-4 py-2 text-sm text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors duration-200">
|
||||
<svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
Einstellungen
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('jobs_page') }}"
|
||||
class="flex items-center px-4 py-2 text-sm text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors duration-200">
|
||||
<svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
|
||||
</svg>
|
||||
Neue Reservierung
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('stats_page') }}"
|
||||
class="flex items-center px-4 py-2 text-sm text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors duration-200">
|
||||
<svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
||||
</svg>
|
||||
Analytik
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-slate-200 dark:border-slate-600">
|
||||
<a href="{{ url_for('privacy') }}"
|
||||
class="flex items-center px-4 py-2 text-sm text-slate-500 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors duration-200">
|
||||
<svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
|
||||
</svg>
|
||||
Datenschutz
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('terms') }}"
|
||||
class="flex items-center px-4 py-2 text-sm text-slate-500 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors duration-200">
|
||||
<svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
||||
</svg>
|
||||
Nutzungsbedingungen
|
||||
</a>
|
||||
|
||||
<button onclick="handleLogout()"
|
||||
class="flex items-center w-full px-4 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors duration-200">
|
||||
<svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/>
|
||||
</svg>
|
||||
Abmelden
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<!-- Dark Mode Toggle für nicht angemeldete Benutzer -->
|
||||
<button
|
||||
id="darkModeToggle"
|
||||
class="dark-mode-toggle"
|
||||
aria-label="Dark Mode umschalten"
|
||||
title="Design wechseln"
|
||||
>
|
||||
<span class="dark-mode-toggle-slider">
|
||||
<i class="fas fa-sun dark-mode-toggle-icon sun absolute inset-0 flex items-center justify-center"></i>
|
||||
<i class="fas fa-moon dark-mode-toggle-icon moon absolute inset-0 flex items-center justify-center opacity-0"></i>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- Login Button - kompakteres Design -->
|
||||
<a href="{{ url_for('auth.login') }}"
|
||||
class="flex items-center space-x-1 py-1 px-2 rounded-md bg-blue-600 hover:bg-blue-700 text-white text-xs transition-colors duration-200">
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/>
|
||||
</svg>
|
||||
<span class="hidden sm:inline">Anmelden</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Mobile Menu (neu) -->
|
||||
<div id="mobileMenu" class="mobile-menu-new hidden lg:hidden">
|
||||
<nav class="flex flex-col space-y-1 px-3 py-4" role="navigation" aria-label="Mobile Navigation">
|
||||
<a href="{{ url_for('dashboard') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'dashboard' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z"/>
|
||||
</svg>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('printers_page') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'printers_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
<span>Drucker</span>
|
||||
</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_permission('CONTROL_PRINTER') %}
|
||||
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'tapo.tapo_dashboard' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-3a2 2 0 00-2 2v1a2 2 0 002 2h3m4-6v1a2 2 0 01-2 2H9a2 2 0 01-2-2v-1m8-2V9a2 2 0 00-2-2H9a2 2 0 00-2 2v3.5M13 9h3l2 5H5l2-5h3"/>
|
||||
</svg>
|
||||
<span>Tapo-Steckdosen</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<a href="{{ url_for('jobs_page') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'jobs_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
|
||||
</svg>
|
||||
<span>Reservierungen</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('stats_page') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'stats_page' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
||||
</svg>
|
||||
<span>Statistiken</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('calendar.calendar_view') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'calendar.calendar_view' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
<span>Schichtplan</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_request_form') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'guest.guest_request_form' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
||||
</svg>
|
||||
<span>Antrag stellen</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('guest.guest_requests_overview') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'guest.guest_requests_overview' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
||||
</svg>
|
||||
<span>Meine Anträge</span>
|
||||
</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'admin.admin_dashboard' else '' }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
<span>Ausbilder-Bereich</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</div>
|
||||
<!-- Moderne MYP Platform Navbar -->
|
||||
{% include 'includes/navbar.html' %}
|
||||
|
||||
<!-- Main Content -->
|
||||
<main id="main-content" class="flex-grow max-w-7xl w-full mx-auto px-3 sm:px-6 lg:px-8 py-4 sm:py-8">
|
||||
@ -784,8 +419,8 @@
|
||||
<!-- Glassmorphism Notification System - Modernisiert -->
|
||||
<script src="{{ url_for('static', filename='js/glassmorphism-notifications.min.js') }}"></script>
|
||||
|
||||
<!-- Mobile Navigation Handler -->
|
||||
<script src="{{ url_for('static', filename='js/navbar-mobile.js') }}"></script>
|
||||
<!-- Modern Navbar Controller -->
|
||||
<script src="{{ url_for('static', filename='js/navbar.js') }}"></script>
|
||||
|
||||
<!-- Additional JavaScript Functions -->
|
||||
<script>
|
||||
|
304
backend/templates/includes/navbar.html
Normal file
304
backend/templates/includes/navbar.html
Normal file
@ -0,0 +1,304 @@
|
||||
<!-- =============================================
|
||||
MYP Platform - Moderne Navbar
|
||||
Mercedes-Benz Design System
|
||||
============================================= -->
|
||||
|
||||
<nav class="navbar" role="navigation" aria-label="Hauptnavigation">
|
||||
<div class="navbar-container">
|
||||
|
||||
<!-- Brand Section -->
|
||||
<a href="{{ url_for('dashboard') }}" class="navbar-brand" aria-label="Zur Startseite">
|
||||
<!-- Mercedes-Benz Logo -->
|
||||
<svg class="brand-icon" viewBox="0 0 80 80" fill="currentColor" aria-hidden="true">
|
||||
<path d="M58.6,4.5C53,1.6,46.7,0,40,0c-6.7,0-13,1.6-18.6,4.5v0C8.7,11.2,0,24.6,0,40c0,15.4,8.7,28.8,21.5,35.5C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
|
||||
</svg>
|
||||
|
||||
<!-- Brand Text -->
|
||||
<div class="brand-text">
|
||||
<span class="brand-title">Mercedes-Benz</span>
|
||||
<span class="brand-subtitle">MYP Platform</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Desktop Navigation -->
|
||||
<div class="navbar-nav">
|
||||
<a href="{{ url_for('dashboard') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'dashboard' else '' }}"
|
||||
aria-label="Dashboard">
|
||||
<i class="fas fa-tachometer-alt" aria-hidden="true"></i>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('printers_page') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'printers_page' else '' }}"
|
||||
aria-label="Drucker verwalten">
|
||||
<i class="fas fa-print" aria-hidden="true"></i>
|
||||
<span>Drucker</span>
|
||||
</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_permission('VIEW_JOBS') %}
|
||||
<a href="{{ url_for('jobs.jobs_page') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'jobs.jobs_page' else '' }}"
|
||||
aria-label="Druckaufträge anzeigen">
|
||||
<i class="fas fa-tasks" aria-hidden="true"></i>
|
||||
<span>Aufträge</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_permission('CONTROL_PRINTER') %}
|
||||
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'tapo.tapo_dashboard' else '' }}"
|
||||
aria-label="Smart-Plugs verwalten">
|
||||
<i class="fas fa-plug" aria-hidden="true"></i>
|
||||
<span>Smart-Plugs</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_permission('VIEW_CALENDAR') %}
|
||||
<a href="{{ url_for('calendar') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'calendar' else '' }}"
|
||||
aria-label="Kalender anzeigen">
|
||||
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
|
||||
<span>Kalender</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_role('admin') %}
|
||||
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||
class="nav-item {{ 'active' if request.endpoint == 'admin.admin_dashboard' else '' }}"
|
||||
aria-label="Administrationsbereich">
|
||||
<i class="fas fa-cog" aria-hidden="true"></i>
|
||||
<span>Admin</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Navbar Actions (Rechte Seite) -->
|
||||
<div class="navbar-actions">
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<!-- Benachrichtigungen -->
|
||||
<div class="dropdown">
|
||||
<button class="navbar-btn"
|
||||
id="notificationToggle"
|
||||
aria-label="Benachrichtigungen anzeigen"
|
||||
aria-expanded="false">
|
||||
<i class="fas fa-bell" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
||||
<div class="dropdown-menu" id="notificationDropdown">
|
||||
<div class="dropdown-header">
|
||||
<i class="fas fa-bell mr-2" aria-hidden="true"></i>
|
||||
Benachrichtigungen
|
||||
</div>
|
||||
|
||||
<div id="notificationList">
|
||||
<!-- Wird dynamisch geladen -->
|
||||
<div class="dropdown-item">
|
||||
<i class="fas fa-info-circle text-blue-500" aria-hidden="true"></i>
|
||||
<div>
|
||||
<div class="font-medium">Keine neuen Benachrichtigungen</div>
|
||||
<div class="text-sm text-gray-500">Alle Meldungen sind aktuell</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="{{ url_for('notifications') }}" class="dropdown-item">
|
||||
<i class="fas fa-eye" aria-hidden="true"></i>
|
||||
Alle anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- User Menu -->
|
||||
<div class="dropdown">
|
||||
<div class="user-avatar"
|
||||
aria-label="Benutzerprofil öffnen"
|
||||
aria-expanded="false">
|
||||
{{ current_user.get_initials() }}
|
||||
</div>
|
||||
|
||||
<div class="dropdown-menu" id="userDropdown">
|
||||
<div class="dropdown-header">
|
||||
<i class="fas fa-user mr-2" aria-hidden="true"></i>
|
||||
{{ current_user.display_name or current_user.username }}
|
||||
</div>
|
||||
|
||||
<a href="{{ url_for('users.profile') }}" class="dropdown-item">
|
||||
<i class="fas fa-user-circle" aria-hidden="true"></i>
|
||||
Mein Profil
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('users.settings') }}" class="dropdown-item">
|
||||
<i class="fas fa-cog" aria-hidden="true"></i>
|
||||
Einstellungen
|
||||
</a>
|
||||
|
||||
{% if current_user.has_role('admin') %}
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="{{ url_for('admin.admin_dashboard') }}" class="dropdown-item">
|
||||
<i class="fas fa-shield-alt" aria-hidden="true"></i>
|
||||
Administration
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<a href="{{ url_for('auth.logout') }}" class="dropdown-item">
|
||||
<i class="fas fa-sign-out-alt" aria-hidden="true"></i>
|
||||
Abmelden
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
<!-- Nicht angemeldet -->
|
||||
<a href="{{ url_for('auth.login') }}" class="navbar-btn" aria-label="Anmelden">
|
||||
<i class="fas fa-sign-in-alt" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<!-- Dark Mode Toggle -->
|
||||
<button class="navbar-btn"
|
||||
id="darkModeToggle"
|
||||
aria-label="Dark Mode umschalten"
|
||||
title="Dark Mode umschalten">
|
||||
<i class="fas fa-moon" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
||||
<!-- Mobile Menu Toggle -->
|
||||
<button class="mobile-menu-toggle"
|
||||
id="mobileMenuToggle"
|
||||
aria-label="Menü öffnen/schließen"
|
||||
aria-expanded="false">
|
||||
<i class="fas fa-bars" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Mobile Menu -->
|
||||
<div class="mobile-menu" id="mobileMenu">
|
||||
<div class="mobile-nav">
|
||||
<a href="{{ url_for('dashboard') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'dashboard' else '' }}">
|
||||
<i class="fas fa-tachometer-alt" aria-hidden="true"></i>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('printers_page') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'printers_page' else '' }}">
|
||||
<i class="fas fa-print" aria-hidden="true"></i>
|
||||
<span>Drucker</span>
|
||||
</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_permission('VIEW_JOBS') %}
|
||||
<a href="{{ url_for('jobs.jobs_page') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'jobs.jobs_page' else '' }}">
|
||||
<i class="fas fa-tasks" aria-hidden="true"></i>
|
||||
<span>Druckaufträge</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_permission('CONTROL_PRINTER') %}
|
||||
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'tapo.tapo_dashboard' else '' }}">
|
||||
<i class="fas fa-plug" aria-hidden="true"></i>
|
||||
<span>Smart-Plugs</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_permission('VIEW_CALENDAR') %}
|
||||
<a href="{{ url_for('calendar') }}"
|
||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'calendar' else '' }}">
|
||||
<i class="fas fa-calendar-alt" aria-hidden="true"></i>
|
||||
<span>Kalender</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.is_authenticated %}
|
||||
<div class="dropdown-divider"></div>
|
||||
|
||||
<a href="{{ url_for('users.profile') }}"
|
||||
class="mobile-nav-item">
|
||||
<i class="fas fa-user-circle" aria-hidden="true"></i>
|
||||
<span>Mein Profil</span>
|
||||
</a>
|
||||
|
||||
<a href="{{ url_for('users.settings') }}"
|
||||
class="mobile-nav-item">
|
||||
<i class="fas fa-cog" aria-hidden="true"></i>
|
||||
<span>Einstellungen</span>
|
||||
</a>
|
||||
|
||||
{% if current_user.has_role('admin') %}
|
||||
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||
class="mobile-nav-item">
|
||||
<i class="fas fa-shield-alt" aria-hidden="true"></i>
|
||||
<span>Administration</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
|
||||
<a href="{{ url_for('auth.logout') }}"
|
||||
class="mobile-nav-item">
|
||||
<i class="fas fa-sign-out-alt" aria-hidden="true"></i>
|
||||
<span>Abmelden</span>
|
||||
</a>
|
||||
|
||||
{% else %}
|
||||
<a href="{{ url_for('auth.login') }}"
|
||||
class="mobile-nav-item">
|
||||
<i class="fas fa-sign-in-alt" aria-hidden="true"></i>
|
||||
<span>Anmelden</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navbar JavaScript -->
|
||||
<script>
|
||||
// Dark Mode Toggle Funktionalität
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const darkModeToggle = document.getElementById('darkModeToggle');
|
||||
const icon = darkModeToggle.querySelector('i');
|
||||
|
||||
// Aktuellen Dark Mode Status prüfen
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
updateDarkModeIcon(isDark);
|
||||
|
||||
darkModeToggle.addEventListener('click', function() {
|
||||
const htmlElement = document.documentElement;
|
||||
const newIsDark = !htmlElement.classList.contains('dark');
|
||||
|
||||
htmlElement.classList.toggle('dark');
|
||||
updateDarkModeIcon(newIsDark);
|
||||
|
||||
// Status in localStorage speichern
|
||||
localStorage.setItem('darkMode', newIsDark ? 'true' : 'false');
|
||||
|
||||
// Optional: Server-Seite informieren
|
||||
fetch('/api/user/theme', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': '{{ csrf_token() }}'
|
||||
},
|
||||
body: JSON.stringify({ theme: newIsDark ? 'dark' : 'light' })
|
||||
}).catch(() => {
|
||||
// Stumm fehlschlagen - Theme funktioniert auch offline
|
||||
});
|
||||
});
|
||||
|
||||
function updateDarkModeIcon(isDark) {
|
||||
if (isDark) {
|
||||
icon.className = 'fas fa-sun';
|
||||
darkModeToggle.setAttribute('aria-label', 'Light Mode aktivieren');
|
||||
} else {
|
||||
icon.className = 'fas fa-moon';
|
||||
darkModeToggle.setAttribute('aria-label', 'Dark Mode aktivieren');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@ -14,7 +14,7 @@ Tapo-Steckdosen-Steuerung | MYP Platform
|
||||
Tapo-Steckdosen-Steuerung
|
||||
</h1>
|
||||
<p class="text-slate-600 dark:text-slate-300">
|
||||
Direkte Kontrolle aller TP-Link Tapo-Steckdosen
|
||||
Mercedes-Benz TBA Marienfelde - 6 Arbeitsplätze für 3D-Drucker
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -22,18 +22,19 @@ Tapo-Steckdosen-Steuerung | MYP Platform
|
||||
|
||||
{% block page_actions %}
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<button onclick="refreshAllStatus()"
|
||||
class="btn-secondary flex items-center space-x-2">
|
||||
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
||||
class="btn-secondary flex items-center space-x-2">
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
<span>Status aktualisieren</span>
|
||||
</button>
|
||||
</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.has_permission('ADMIN') %}
|
||||
<button onclick="discoverOutlets()"
|
||||
class="btn-primary flex items-center space-x-2">
|
||||
<i class="fas fa-search"></i>
|
||||
<span>Steckdosen suchen</span>
|
||||
</button>
|
||||
<form method="POST" action="{{ url_for('tapo.discover_outlets') }}" class="inline">
|
||||
<button type="submit" class="btn-primary flex items-center space-x-2">
|
||||
<i class="fas fa-search"></i>
|
||||
<span>Steckdosen suchen</span>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<a href="{{ url_for('tapo.manual_control') }}"
|
||||
class="btn-outline flex items-center space-x-2">
|
||||
@ -54,10 +55,10 @@ Tapo-Steckdosen-Steuerung | MYP Platform
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-slate-700 dark:text-slate-300">
|
||||
Gesamt
|
||||
Arbeitsplätze Gesamt
|
||||
</h3>
|
||||
<p class="text-2xl font-bold text-slate-900 dark:text-white" id="total-count">
|
||||
{{ total_outlets }}
|
||||
<p class="text-2xl font-bold text-slate-900 dark:text-white">
|
||||
{{ total_outlets or 6 }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -72,8 +73,8 @@ Tapo-Steckdosen-Steuerung | MYP Platform
|
||||
<h3 class="text-lg font-semibold text-slate-700 dark:text-slate-300">
|
||||
Online
|
||||
</h3>
|
||||
<p class="text-2xl font-bold text-slate-900 dark:text-white" id="online-count">
|
||||
{{ online_outlets }}
|
||||
<p class="text-2xl font-bold text-slate-900 dark:text-white">
|
||||
{{ online_outlets or 0 }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -88,377 +89,238 @@ Tapo-Steckdosen-Steuerung | MYP Platform
|
||||
<h3 class="text-lg font-semibold text-slate-700 dark:text-slate-300">
|
||||
Aktive
|
||||
</h3>
|
||||
<p class="text-2xl font-bold text-slate-900 dark:text-white" id="active-count">
|
||||
0
|
||||
<p class="text-2xl font-bold text-slate-900 dark:text-white">
|
||||
{{ outlets.values() | selectattr('status', 'equalto', 'on') | list | length }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Steckdosen-Grid -->
|
||||
<!-- Mercedes-Benz 6 Arbeitsplätze -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2 class="text-xl font-semibold text-slate-800 dark:text-white flex items-center">
|
||||
<i class="fas fa-list mr-3"></i>
|
||||
Alle Tapo-Steckdosen
|
||||
<i class="fas fa-industry mr-3"></i>
|
||||
Mercedes-Benz TBA Marienfelde - 3D-Drucker Arbeitsplätze
|
||||
</h2>
|
||||
<p class="text-sm text-slate-600 dark:text-slate-400 mt-2">
|
||||
Feste Installation mit 6 konfigurierten Arbeitsplätzen
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
{% if outlets %}
|
||||
<!-- Steckdosen-Grid - Immer 6 Arbeitsplätze anzeigen -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" id="outlets-grid">
|
||||
{% for ip, outlet in outlets.items() %}
|
||||
<div class="outlet-card border rounded-lg p-4 {{ 'border-green-300 bg-green-50 dark:bg-green-900/20' if outlet.reachable else 'border-red-300 bg-red-50 dark:bg-red-900/20' }}"
|
||||
data-ip="{{ ip }}">
|
||||
|
||||
<!-- Steckdosen-Header -->
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="status-indicator w-4 h-4 rounded-full {{ 'bg-green-500' if outlet.reachable else 'bg-red-500' }}"
|
||||
data-ip="{{ ip }}"></div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-slate-800 dark:text-white">
|
||||
{{ outlet.printer_name }}
|
||||
</h3>
|
||||
<p class="text-sm text-slate-600 dark:text-slate-400">
|
||||
{{ ip }}
|
||||
</p>
|
||||
{% if outlets %}
|
||||
{% for ip, outlet in outlets.items() %}
|
||||
<div class="outlet-card border rounded-lg p-4 {{ 'border-green-300 bg-green-50 dark:bg-green-900/20' if outlet.reachable else 'border-red-300 bg-red-50 dark:bg-red-900/20' }}"
|
||||
data-ip="{{ ip }}">
|
||||
|
||||
<!-- Arbeitsplatz-Header -->
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="status-indicator w-4 h-4 rounded-full {{ 'bg-green-500' if outlet.reachable else 'bg-red-500' }}"></div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-slate-800 dark:text-white">
|
||||
{{ outlet.printer_name }}
|
||||
</h3>
|
||||
<p class="text-sm text-slate-600 dark:text-slate-400">
|
||||
IP: {{ ip }}
|
||||
</p>
|
||||
{% if outlet.model %}
|
||||
<p class="text-xs text-slate-500 dark:text-slate-500">
|
||||
{{ outlet.model }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-2">
|
||||
<!-- Konfigurationsstatus -->
|
||||
{% if outlet.configured_in_db %}
|
||||
<span class="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full dark:bg-blue-900 dark:text-blue-300"
|
||||
title="In Datenbank konfiguriert">
|
||||
<i class="fas fa-database text-xs"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="bg-yellow-100 text-yellow-800 text-xs px-2 py-1 rounded-full dark:bg-yellow-900 dark:text-yellow-300"
|
||||
title="Nicht in Datenbank konfiguriert">
|
||||
<i class="fas fa-exclamation-triangle text-xs"></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
<!-- Position-Badge -->
|
||||
<span class="bg-slate-100 text-slate-700 text-xs px-2 py-1 rounded-full dark:bg-slate-700 dark:text-slate-300">
|
||||
#{{ outlet.position or loop.index }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-2">
|
||||
<button onclick="refreshOutletStatus('{{ ip }}')"
|
||||
class="p-2 text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-200 transition-colors"
|
||||
title="Status aktualisieren">
|
||||
<i class="fas fa-sync-alt text-sm"></i>
|
||||
</button>
|
||||
|
||||
<button onclick="testConnection('{{ ip }}')"
|
||||
class="p-2 text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-200 transition-colors"
|
||||
title="Verbindung testen">
|
||||
<i class="fas fa-network-wired text-sm"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status-Info -->
|
||||
<div class="mb-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400">Status:</span>
|
||||
<span class="status-text font-medium" data-ip="{{ ip }}">
|
||||
{% if outlet.reachable %}
|
||||
{% if outlet.status == 'on' %}
|
||||
<span class="text-green-600 dark:text-green-400">
|
||||
<i class="fas fa-power-off mr-1"></i>EIN
|
||||
</span>
|
||||
{% elif outlet.status == 'off' %}
|
||||
<span class="text-slate-600 dark:text-slate-400">
|
||||
<i class="fas fa-power-off mr-1"></i>AUS
|
||||
</span>
|
||||
<!-- Status-Informationen -->
|
||||
<div class="mb-4 space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400">Status:</span>
|
||||
<span class="status-text font-medium">
|
||||
{% if outlet.reachable %}
|
||||
{% if outlet.status == 'on' %}
|
||||
<span class="text-green-600 dark:text-green-400">
|
||||
<i class="fas fa-power-off mr-1"></i>EIN
|
||||
</span>
|
||||
{% elif outlet.status == 'off' %}
|
||||
<span class="text-slate-600 dark:text-slate-400">
|
||||
<i class="fas fa-power-off mr-1"></i>AUS
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="text-yellow-600 dark:text-yellow-400">
|
||||
<i class="fas fa-question mr-1"></i>UNBEKANNT
|
||||
</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="text-yellow-600 dark:text-yellow-400">
|
||||
<i class="fas fa-question mr-1"></i>UNBEKANNT
|
||||
<span class="text-red-600 dark:text-red-400">
|
||||
<i class="fas fa-exclamation-triangle mr-1"></i>OFFLINE
|
||||
</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="text-red-600 dark:text-red-400">
|
||||
<i class="fas fa-exclamation-triangle mr-1"></i>OFFLINE
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400">Standort:</span>
|
||||
<span class="text-sm font-medium text-slate-800 dark:text-white">
|
||||
{{ outlet.location }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{% if outlet.configured_in_db and outlet.printer_id %}
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400">Drucker-ID:</span>
|
||||
<span class="text-sm font-medium text-slate-800 dark:text-white">
|
||||
#{{ outlet.printer_id }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Steuerungsformen (ohne JavaScript) -->
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<!-- EIN-Button -->
|
||||
<form method="POST" action="{{ url_for('tapo.control_outlet_form') }}" class="inline">
|
||||
<input type="hidden" name="ip" value="{{ ip }}">
|
||||
<input type="hidden" name="action" value="on">
|
||||
<button type="submit"
|
||||
class="w-full py-2 px-3 bg-green-600 hover:bg-green-700 text-white rounded-lg transition-colors font-medium text-sm disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
{% if not outlet.reachable %}disabled{% endif %}>
|
||||
<i class="fas fa-power-off mr-1"></i>
|
||||
EIN
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- AUS-Button -->
|
||||
<form method="POST" action="{{ url_for('tapo.control_outlet_form') }}" class="inline">
|
||||
<input type="hidden" name="ip" value="{{ ip }}">
|
||||
<input type="hidden" name="action" value="off">
|
||||
<button type="submit"
|
||||
class="w-full py-2 px-3 bg-slate-600 hover:bg-slate-700 text-white rounded-lg transition-colors font-medium text-sm disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
{% if not outlet.reachable %}disabled{% endif %}>
|
||||
<i class="fas fa-power-off mr-1"></i>
|
||||
AUS
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% if outlet.error %}
|
||||
<div class="mt-3 p-2 bg-red-100 dark:bg-red-900/30 border border-red-300 dark:border-red-700 rounded text-sm text-red-700 dark:text-red-300">
|
||||
<i class="fas fa-exclamation-triangle mr-1"></i>
|
||||
{{ outlet.error }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Zusätzliche Aktionen für Administratoren -->
|
||||
{% if current_user.has_permission('ADMIN') %}
|
||||
<div class="mt-3 pt-3 border-t border-slate-200 dark:border-slate-600">
|
||||
<div class="flex space-x-2">
|
||||
<form method="POST" action="{{ url_for('tapo.test_connection_form') }}" class="flex-1">
|
||||
<input type="hidden" name="ip" value="{{ ip }}">
|
||||
<button type="submit"
|
||||
class="w-full text-xs py-1 px-2 text-slate-600 hover:text-slate-800 dark:text-slate-400 dark:hover:text-slate-200 border border-slate-300 dark:border-slate-600 rounded transition-colors">
|
||||
<i class="fas fa-network-wired mr-1"></i>Test
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{% if not outlet.configured_in_db %}
|
||||
<a href="{{ url_for('admin.add_printer') }}?preset_plug_ip={{ ip }}"
|
||||
class="flex-1 text-xs py-1 px-2 text-center text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-200 border border-blue-300 dark:border-blue-600 rounded transition-colors">
|
||||
<i class="fas fa-plus mr-1"></i>Setup
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<!-- Fallback: Zeige 6 Platzhalter-Arbeitsplätze -->
|
||||
{% for i in range(1, 7) %}
|
||||
<div class="outlet-card border border-red-300 bg-red-50 dark:bg-red-900/20 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="status-indicator w-4 h-4 rounded-full bg-red-500"></div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-slate-800 dark:text-white">
|
||||
3D-Drucker {{ i }}
|
||||
</h3>
|
||||
<p class="text-sm text-slate-600 dark:text-slate-400">
|
||||
192.168.1.20{{ i }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="bg-slate-100 text-slate-700 text-xs px-2 py-1 rounded-full dark:bg-slate-700 dark:text-slate-300">
|
||||
#{{ i }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between mt-2">
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400">Standort:</span>
|
||||
<span class="text-sm font-medium text-slate-800 dark:text-white">
|
||||
{{ outlet.location }}
|
||||
</span>
|
||||
<div class="mb-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400">Status:</span>
|
||||
<span class="text-red-600 dark:text-red-400">
|
||||
<i class="fas fa-exclamation-triangle mr-1"></i>NICHT KONFIGURIERT
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between mt-2">
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400">Standort:</span>
|
||||
<span class="text-sm font-medium text-slate-800 dark:text-white">
|
||||
Arbeitsplatz {{ i }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<button disabled class="w-full py-2 px-3 bg-slate-400 text-white rounded-lg opacity-50 cursor-not-allowed text-sm">
|
||||
<i class="fas fa-power-off mr-1"></i>EIN
|
||||
</button>
|
||||
<button disabled class="w-full py-2 px-3 bg-slate-400 text-white rounded-lg opacity-50 cursor-not-allowed text-sm">
|
||||
<i class="fas fa-power-off mr-1"></i>AUS
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 p-2 bg-yellow-100 dark:bg-yellow-900/30 border border-yellow-300 dark:border-yellow-700 rounded text-sm text-yellow-700 dark:text-yellow-300">
|
||||
<i class="fas fa-info-circle mr-1"></i>
|
||||
Arbeitsplatz {{ i }} noch nicht eingerichtet
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Steuerungsbuttons -->
|
||||
<div class="flex space-x-3">
|
||||
<button onclick="controlOutlet('{{ ip }}', 'on')"
|
||||
class="flex-1 py-2 px-3 bg-green-600 hover:bg-green-700 text-white rounded-lg transition-colors font-medium text-sm"
|
||||
{% if not outlet.reachable %}disabled{% endif %}>
|
||||
<i class="fas fa-power-off mr-1"></i>
|
||||
EIN
|
||||
</button>
|
||||
|
||||
<button onclick="controlOutlet('{{ ip }}', 'off')"
|
||||
class="flex-1 py-2 px-3 bg-slate-600 hover:bg-slate-700 text-white rounded-lg transition-colors font-medium text-sm"
|
||||
{% if not outlet.reachable %}disabled{% endif %}>
|
||||
<i class="fas fa-power-off mr-1"></i>
|
||||
AUS
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{% if outlet.error %}
|
||||
<div class="mt-3 p-2 bg-red-100 dark:bg-red-900/30 border border-red-300 dark:border-red-700 rounded text-sm text-red-700 dark:text-red-300">
|
||||
<i class="fas fa-exclamation-triangle mr-1"></i>
|
||||
{{ outlet.error }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-12">
|
||||
<div class="text-slate-400 dark:text-slate-500 mb-4">
|
||||
<i class="fas fa-plug text-6xl"></i>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-slate-600 dark:text-slate-400 mb-2">
|
||||
Keine Tapo-Steckdosen konfiguriert
|
||||
</h3>
|
||||
<p class="text-slate-500 dark:text-slate-400 mb-6">
|
||||
Es wurden noch keine Drucker mit Tapo-Steckdosen eingerichtet.
|
||||
</p>
|
||||
{% if current_user.is_authenticated and current_user.has_permission('ADMIN') %}
|
||||
<div class="flex justify-center space-x-4">
|
||||
<button onclick="discoverOutlets()"
|
||||
class="btn-primary">
|
||||
<i class="fas fa-search mr-2"></i>
|
||||
Steckdosen suchen
|
||||
</button>
|
||||
<a href="{{ url_for('admin.printers_overview') }}"
|
||||
class="btn-secondary">
|
||||
<i class="fas fa-plus mr-2"></i>
|
||||
Drucker verwalten
|
||||
</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading Overlay -->
|
||||
<div id="loading-overlay" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
|
||||
<div class="bg-white dark:bg-slate-800 p-6 rounded-lg shadow-lg">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i class="fas fa-spinner fa-spin text-blue-600 text-xl"></i>
|
||||
<span class="text-slate-800 dark:text-white font-medium" id="loading-text">
|
||||
Lädt...
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Auto-Refresh nur falls explizit gewünscht (minimales JavaScript) -->
|
||||
{% if request.args.get('auto_refresh') %}
|
||||
<script>
|
||||
// Globale Variablen
|
||||
let outlets = {{ outlets | tojson }};
|
||||
|
||||
// Utility-Funktionen
|
||||
function showLoading(text = 'Lädt...') {
|
||||
document.getElementById('loading-text').textContent = text;
|
||||
document.getElementById('loading-overlay').classList.remove('hidden');
|
||||
}
|
||||
|
||||
function hideLoading() {
|
||||
document.getElementById('loading-overlay').classList.add('hidden');
|
||||
}
|
||||
|
||||
function updateOutletDisplay(ip, data) {
|
||||
const card = document.querySelector(`[data-ip="${ip}"]`);
|
||||
if (!card) return;
|
||||
|
||||
const statusIndicator = card.querySelector('.status-indicator');
|
||||
const statusText = card.querySelector('.status-text');
|
||||
const buttons = card.querySelectorAll('button[onclick*="controlOutlet"]');
|
||||
|
||||
// Status-Indikator aktualisieren
|
||||
statusIndicator.className = `status-indicator w-4 h-4 rounded-full ${data.reachable ? 'bg-green-500' : 'bg-red-500'}`;
|
||||
|
||||
// Status-Text aktualisieren
|
||||
if (data.reachable) {
|
||||
let statusIcon, statusColor;
|
||||
if (data.status === 'on') {
|
||||
statusIcon = 'fas fa-power-off';
|
||||
statusColor = 'text-green-600 dark:text-green-400';
|
||||
statusText.innerHTML = `<span class="${statusColor}"><i class="${statusIcon} mr-1"></i>EIN</span>`;
|
||||
} else if (data.status === 'off') {
|
||||
statusIcon = 'fas fa-power-off';
|
||||
statusColor = 'text-slate-600 dark:text-slate-400';
|
||||
statusText.innerHTML = `<span class="${statusColor}"><i class="${statusIcon} mr-1"></i>AUS</span>`;
|
||||
} else {
|
||||
statusIcon = 'fas fa-question';
|
||||
statusColor = 'text-yellow-600 dark:text-yellow-400';
|
||||
statusText.innerHTML = `<span class="${statusColor}"><i class="${statusIcon} mr-1"></i>UNBEKANNT</span>`;
|
||||
}
|
||||
|
||||
// Buttons aktivieren
|
||||
buttons.forEach(btn => btn.disabled = false);
|
||||
} else {
|
||||
statusText.innerHTML = '<span class="text-red-600 dark:text-red-400"><i class="fas fa-exclamation-triangle mr-1"></i>OFFLINE</span>';
|
||||
|
||||
// Buttons deaktivieren
|
||||
buttons.forEach(btn => btn.disabled = true);
|
||||
}
|
||||
|
||||
// Kartenrand aktualisieren
|
||||
card.className = card.className.replace(/border-\w+-300|bg-\w+-50|dark:bg-\w+-900\/20/g, '');
|
||||
if (data.reachable) {
|
||||
card.className += ' border-green-300 bg-green-50 dark:bg-green-900/20';
|
||||
} else {
|
||||
card.className += ' border-red-300 bg-red-50 dark:bg-red-900/20';
|
||||
}
|
||||
}
|
||||
|
||||
function updateStatistics() {
|
||||
const totalCount = Object.keys(outlets).length;
|
||||
const onlineCount = Object.values(outlets).filter(o => o.reachable).length;
|
||||
const activeCount = Object.values(outlets).filter(o => o.status === 'on').length;
|
||||
|
||||
document.getElementById('total-count').textContent = totalCount;
|
||||
document.getElementById('online-count').textContent = onlineCount;
|
||||
document.getElementById('active-count').textContent = activeCount;
|
||||
}
|
||||
|
||||
// API-Funktionen
|
||||
async function controlOutlet(ip, action) {
|
||||
try {
|
||||
showLoading(`Steckdose wird ${action === 'on' ? 'eingeschaltet' : 'ausgeschaltet'}...`);
|
||||
|
||||
const response = await fetch('/tapo/control', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': '{{ csrf_token() }}'
|
||||
},
|
||||
body: JSON.stringify({ ip, action })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
showFlashMessage(data.message, 'success');
|
||||
|
||||
// Status in lokalen Daten aktualisieren
|
||||
if (outlets[ip]) {
|
||||
outlets[ip].status = action;
|
||||
outlets[ip].reachable = true;
|
||||
updateOutletDisplay(ip, outlets[ip]);
|
||||
updateStatistics();
|
||||
}
|
||||
} else {
|
||||
showFlashMessage(data.error, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
showFlashMessage('Fehler bei der Steckdosen-Steuerung: ' + error.message, 'error');
|
||||
} finally {
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshOutletStatus(ip) {
|
||||
try {
|
||||
const response = await fetch(`/tapo/status/${ip}`);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
if (outlets[ip]) {
|
||||
outlets[ip].status = data.status;
|
||||
outlets[ip].reachable = data.reachable;
|
||||
updateOutletDisplay(ip, outlets[ip]);
|
||||
updateStatistics();
|
||||
}
|
||||
} else {
|
||||
showFlashMessage(`Fehler beim Status-Check für ${ip}: ${data.error}`, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
showFlashMessage('Fehler beim Status-Check: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshAllStatus() {
|
||||
showLoading('Status aller Steckdosen wird aktualisiert...');
|
||||
|
||||
try {
|
||||
const response = await fetch('/tapo/all-status');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
// Lokale Daten aktualisieren
|
||||
for (const [ip, status] of Object.entries(data.outlets)) {
|
||||
if (outlets[ip]) {
|
||||
outlets[ip].status = status.status;
|
||||
outlets[ip].reachable = status.reachable;
|
||||
updateOutletDisplay(ip, outlets[ip]);
|
||||
}
|
||||
}
|
||||
updateStatistics();
|
||||
showFlashMessage('Status aller Steckdosen aktualisiert', 'success');
|
||||
} else {
|
||||
showFlashMessage('Fehler beim Aktualisieren: ' + data.error, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
showFlashMessage('Fehler beim Status-Update: ' + error.message, 'error');
|
||||
} finally {
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
async function testConnection(ip) {
|
||||
try {
|
||||
showLoading(`Verbindung zu ${ip} wird getestet...`);
|
||||
|
||||
const response = await fetch(`/tapo/test/${ip}`, { method: 'POST' });
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
const testResult = data.test_result;
|
||||
if (testResult.success) {
|
||||
showFlashMessage(`✅ Verbindung zu ${ip} erfolgreich!`, 'success');
|
||||
} else {
|
||||
showFlashMessage(`❌ Verbindung zu ${ip} fehlgeschlagen: ${testResult.error}`, 'error');
|
||||
}
|
||||
} else {
|
||||
showFlashMessage(`Verbindungstest fehlgeschlagen: ${data.error}`, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
showFlashMessage('Fehler beim Verbindungstest: ' + error.message, 'error');
|
||||
} finally {
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
async function discoverOutlets() {
|
||||
try {
|
||||
showLoading('Suche nach neuen Tapo-Steckdosen...');
|
||||
|
||||
const response = await fetch('/tapo/discover', { method: 'POST' });
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
showFlashMessage(data.message, 'success');
|
||||
|
||||
// Seite neu laden wenn neue Steckdosen gefunden wurden
|
||||
if (data.discovered_count > 0) {
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 2000);
|
||||
}
|
||||
} else {
|
||||
showFlashMessage('Fehler bei der Erkennung: ' + data.error, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
showFlashMessage('Fehler bei der Steckdosen-Suche: ' + error.message, 'error');
|
||||
} finally {
|
||||
hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-Refresh alle 30 Sekunden
|
||||
setInterval(() => {
|
||||
if (Object.keys(outlets).length > 0) {
|
||||
refreshAllStatus();
|
||||
}
|
||||
// Minimales Auto-Refresh alle 30 Sekunden
|
||||
setTimeout(function() {
|
||||
window.location.reload();
|
||||
}, 30000);
|
||||
|
||||
// Initial statistics update
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
updateStatistics();
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
1
docs/NAVBAR_REDESIGN_2025.md
Normal file
1
docs/NAVBAR_REDESIGN_2025.md
Normal file
@ -0,0 +1 @@
|
||||
|
Reference in New Issue
Block a user