🎉 Refactored backend structure: Removed unused files including app_cleaned.py, admin_api.py, admin.py, user.py, and others. Updated settings.local.json to include additional Bash commands. Enhanced admin templates for better navigation and functionality. Improved logging and error handling across various modules.
This commit is contained in:
@ -8,7 +8,11 @@
|
|||||||
"Bash(python3:*)",
|
"Bash(python3:*)",
|
||||||
"Bash(ls:*)",
|
"Bash(ls:*)",
|
||||||
"Bash(grep:*)",
|
"Bash(grep:*)",
|
||||||
"Bash(python:*)"
|
"Bash(python:*)",
|
||||||
|
"Bash(diff:*)",
|
||||||
|
"Bash(mv:*)",
|
||||||
|
"Bash(rm:*)",
|
||||||
|
"Bash(rg:*)"
|
||||||
],
|
],
|
||||||
"deny": []
|
"deny": []
|
||||||
}
|
}
|
||||||
|
@ -336,3 +336,80 @@ When adding new features:
|
|||||||
- Database locked errors: Check for WAL files (`*.db-wal`, `*.db-shm`)
|
- Database locked errors: Check for WAL files (`*.db-wal`, `*.db-shm`)
|
||||||
- SSL issues: Regenerate certificates with `utils/ssl_config.py`
|
- SSL issues: Regenerate certificates with `utils/ssl_config.py`
|
||||||
- Performance issues: Check `/api/stats` endpoint for metrics
|
- Performance issues: Check `/api/stats` endpoint for metrics
|
||||||
|
|
||||||
|
# Admin Panel Tab-Probleme behoben
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
Die Tabs "Logs", "System" und "Benutzer" im Admin Panel funktionierten nicht korrekt.
|
||||||
|
|
||||||
|
## Ursachen
|
||||||
|
1. **Fehlende Template-Variablen**: Die Routes übergaben nicht die erwarteten Variablen (`active_tab`, `users`, `printers`, `logs`)
|
||||||
|
2. **Fehlende API-Endpunkte**: Keine API-Endpunkte für Logs-Funktionalität
|
||||||
|
3. **JavaScript-Initialisierung**: Logs wurden nicht automatisch geladen
|
||||||
|
4. **Template-Pfade**: Falsche Template-Pfade in einigen Routes
|
||||||
|
|
||||||
|
## Behobene Probleme
|
||||||
|
|
||||||
|
### 1. Admin Routes korrigiert (`backend/blueprints/admin_unified.py`)
|
||||||
|
- ✅ **users_overview()**: Lädt jetzt alle Benutzer und übergibt `active_tab='users'`
|
||||||
|
- ✅ **printers_overview()**: Lädt jetzt alle Drucker und übergibt `active_tab='printers'`
|
||||||
|
- ✅ **logs_overview()**: Lädt jetzt Logs und übergibt `active_tab='logs'`
|
||||||
|
- ✅ **system_health()**: Übergibt jetzt `active_tab='system'`
|
||||||
|
- ✅ **maintenance()**: Übergibt jetzt `active_tab='maintenance'`
|
||||||
|
|
||||||
|
### 2. Neue API-Endpunkte hinzugefügt
|
||||||
|
- ✅ **GET /admin/api/logs**: Logs abrufen mit Level-Filter
|
||||||
|
- ✅ **POST /admin/api/logs/export**: Logs exportieren (CSV, JSON, TXT)
|
||||||
|
- ✅ **GET /admin/api/system/status**: System-Status mit CPU, RAM, Disk
|
||||||
|
- ✅ **POST /admin/api/test/create-sample-logs**: Test-Logs erstellen
|
||||||
|
|
||||||
|
### 3. JavaScript-Funktionalität erweitert (`backend/static/js/admin-unified.js`)
|
||||||
|
- ✅ **Event-Listener für Logs**: Refresh, Export, Level-Filter
|
||||||
|
- ✅ **Automatisches Laden**: Logs werden automatisch geladen wenn Tab aktiv
|
||||||
|
- ✅ **API-URLs korrigiert**: Richtige Pfade für Admin-API
|
||||||
|
- ✅ **Export-Funktionalität**: Download von Logs als Datei
|
||||||
|
|
||||||
|
### 4. Template-Integration
|
||||||
|
- ✅ **Einheitliches Template**: Alle Tabs verwenden `admin.html`
|
||||||
|
- ✅ **Korrekte Variablen**: `active_tab`, `users`, `printers`, `logs`, `stats`
|
||||||
|
- ✅ **Tab-Navigation**: Links zeigen aktiven Tab korrekt an
|
||||||
|
|
||||||
|
## Funktionalität
|
||||||
|
|
||||||
|
### Benutzer-Tab
|
||||||
|
- Zeigt alle registrierten Benutzer
|
||||||
|
- Bearbeiten/Löschen von Benutzern
|
||||||
|
- Benutzer hinzufügen
|
||||||
|
|
||||||
|
### Drucker-Tab
|
||||||
|
- Zeigt alle konfigurierten Drucker
|
||||||
|
- Status-Anzeige (Online/Offline)
|
||||||
|
- Drucker-Verwaltung
|
||||||
|
|
||||||
|
### Logs-Tab
|
||||||
|
- System-Logs mit verschiedenen Leveln (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
||||||
|
- Filter nach Log-Level
|
||||||
|
- Export-Funktionalität (CSV, JSON, TXT)
|
||||||
|
- Automatisches Refresh
|
||||||
|
|
||||||
|
### System-Tab
|
||||||
|
- System-Informationen (CPU, RAM, Disk)
|
||||||
|
- Erweiterte Einstellungen
|
||||||
|
- Wartungsfunktionen
|
||||||
|
|
||||||
|
## Test-Funktionalität
|
||||||
|
```bash
|
||||||
|
# Test-Logs erstellen
|
||||||
|
curl -X POST http://localhost:5000/admin/api/test/create-sample-logs \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "X-CSRFToken: <token>"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Nächste Schritte
|
||||||
|
1. Server neu starten um Änderungen zu laden
|
||||||
|
2. Als Admin einloggen
|
||||||
|
3. Admin Panel aufrufen: `/admin`
|
||||||
|
4. Tabs testen: Benutzer, Drucker, Logs, System
|
||||||
|
5. Test-Logs erstellen und Logs-Funktionalität testen
|
||||||
|
|
||||||
|
Alle Admin Panel Tabs sollten jetzt korrekt funktionieren!
|
||||||
|
Binary file not shown.
BIN
backend/__pycache__/app.cpython-36.pyc
Normal file
BIN
backend/__pycache__/app.cpython-36.pyc
Normal file
Binary file not shown.
Binary file not shown.
9683
backend/app.py
9683
backend/app.py
File diff suppressed because it is too large
Load Diff
@ -1,485 +0,0 @@
|
|||||||
"""
|
|
||||||
Hauptanwendung für das 3D-Druck-Management-System
|
|
||||||
|
|
||||||
Diese Datei initialisiert die Flask-Anwendung und registriert alle Blueprints.
|
|
||||||
Die eigentlichen Routen sind in den jeweiligen Blueprint-Modulen definiert.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import logging
|
|
||||||
import atexit
|
|
||||||
import signal
|
|
||||||
from datetime import datetime
|
|
||||||
from flask import Flask, render_template, request, jsonify, redirect, url_for, session, abort
|
|
||||||
from flask_login import LoginManager, current_user, logout_user, login_required
|
|
||||||
from flask_wtf import CSRFProtect
|
|
||||||
from flask_wtf.csrf import CSRFError
|
|
||||||
from sqlalchemy import event
|
|
||||||
from contextlib import contextmanager
|
|
||||||
import threading
|
|
||||||
|
|
||||||
# ===== OPTIMIERTE KONFIGURATION FÜR RASPBERRY PI =====
|
|
||||||
class OptimizedConfig:
|
|
||||||
"""Konfiguration für performance-optimierte Bereitstellung auf Raspberry Pi"""
|
|
||||||
|
|
||||||
# Performance-Optimierungs-Flags
|
|
||||||
OPTIMIZED_MODE = True
|
|
||||||
USE_MINIFIED_ASSETS = True
|
|
||||||
DISABLE_ANIMATIONS = True
|
|
||||||
LIMIT_GLASSMORPHISM = True
|
|
||||||
|
|
||||||
# Flask-Performance-Einstellungen
|
|
||||||
DEBUG = False
|
|
||||||
TESTING = False
|
|
||||||
SEND_FILE_MAX_AGE_DEFAULT = 31536000 # 1 Jahr Cache für statische Dateien
|
|
||||||
|
|
||||||
# Template-Einstellungen
|
|
||||||
TEMPLATES_AUTO_RELOAD = False
|
|
||||||
EXPLAIN_TEMPLATE_LOADING = False
|
|
||||||
|
|
||||||
# Session-Konfiguration
|
|
||||||
SESSION_COOKIE_SECURE = True
|
|
||||||
SESSION_COOKIE_HTTPONLY = True
|
|
||||||
SESSION_COOKIE_SAMESITE = 'Lax'
|
|
||||||
|
|
||||||
# Performance-Optimierungen
|
|
||||||
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB max Upload
|
|
||||||
JSON_SORT_KEYS = False
|
|
||||||
JSONIFY_PRETTYPRINT_REGULAR = False
|
|
||||||
|
|
||||||
def detect_raspberry_pi():
|
|
||||||
"""Erkennt ob das System auf einem Raspberry Pi läuft"""
|
|
||||||
try:
|
|
||||||
with open('/proc/cpuinfo', 'r') as f:
|
|
||||||
cpuinfo = f.read()
|
|
||||||
if 'Raspberry Pi' in cpuinfo or 'BCM' in cpuinfo:
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
import platform
|
|
||||||
machine = platform.machine().lower()
|
|
||||||
if 'arm' in machine or 'aarch64' in machine:
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return os.getenv('FORCE_OPTIMIZED_MODE', '').lower() in ['true', '1', 'yes']
|
|
||||||
|
|
||||||
def should_use_optimized_config():
|
|
||||||
"""Bestimmt ob die optimierte Konfiguration verwendet werden soll"""
|
|
||||||
if '--optimized' in sys.argv:
|
|
||||||
return True
|
|
||||||
|
|
||||||
if detect_raspberry_pi():
|
|
||||||
return True
|
|
||||||
|
|
||||||
if os.getenv('USE_OPTIMIZED_CONFIG', '').lower() in ['true', '1', 'yes']:
|
|
||||||
return True
|
|
||||||
|
|
||||||
try:
|
|
||||||
import psutil
|
|
||||||
memory_gb = psutil.virtual_memory().total / (1024**3)
|
|
||||||
if memory_gb < 2.0:
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Windows-spezifische Fixes
|
|
||||||
if os.name == 'nt':
|
|
||||||
try:
|
|
||||||
from utils.windows_fixes import get_windows_thread_manager
|
|
||||||
print("[OK] Windows-Fixes (sichere Version) geladen")
|
|
||||||
except ImportError as e:
|
|
||||||
get_windows_thread_manager = None
|
|
||||||
print(f"[WARN] Windows-Fixes nicht verfügbar: {str(e)}")
|
|
||||||
else:
|
|
||||||
get_windows_thread_manager = None
|
|
||||||
|
|
||||||
# Lokale Imports
|
|
||||||
from models import init_database, create_initial_admin, User, get_db_session
|
|
||||||
from utils.logging_config import setup_logging, get_logger, log_startup_info
|
|
||||||
from utils.job_scheduler import JobScheduler, get_job_scheduler
|
|
||||||
from utils.queue_manager import start_queue_manager, stop_queue_manager
|
|
||||||
from utils.settings import SECRET_KEY, SESSION_LIFETIME
|
|
||||||
|
|
||||||
# ===== OFFLINE-MODUS KONFIGURATION =====
|
|
||||||
OFFLINE_MODE = True # Produktionseinstellung für Offline-Betrieb
|
|
||||||
|
|
||||||
# Blueprints importieren
|
|
||||||
from blueprints.auth import auth_blueprint
|
|
||||||
from blueprints.user import user_blueprint
|
|
||||||
from blueprints.admin import admin_blueprint
|
|
||||||
from blueprints.admin_api import admin_api_blueprint
|
|
||||||
from blueprints.guest import guest_blueprint
|
|
||||||
from blueprints.calendar import calendar_blueprint
|
|
||||||
from blueprints.users import users_blueprint
|
|
||||||
from blueprints.printers import printers_blueprint
|
|
||||||
from blueprints.jobs import jobs_blueprint
|
|
||||||
from blueprints.kiosk import kiosk_blueprint
|
|
||||||
from blueprints.uploads import uploads_blueprint
|
|
||||||
from blueprints.sessions import sessions_blueprint
|
|
||||||
|
|
||||||
# Import der Sicherheits- und Hilfssysteme
|
|
||||||
from utils.rate_limiter import cleanup_rate_limiter
|
|
||||||
from utils.security import init_security
|
|
||||||
from utils.permissions import init_permission_helpers
|
|
||||||
|
|
||||||
# Logging initialisieren
|
|
||||||
setup_logging()
|
|
||||||
log_startup_info()
|
|
||||||
|
|
||||||
# Logger für verschiedene Komponenten
|
|
||||||
app_logger = get_logger("app")
|
|
||||||
|
|
||||||
# Thread-sichere Caches
|
|
||||||
_user_cache = {}
|
|
||||||
_user_cache_lock = threading.RLock()
|
|
||||||
_printer_status_cache = {}
|
|
||||||
_printer_status_cache_lock = threading.RLock()
|
|
||||||
|
|
||||||
# Cache-Konfiguration
|
|
||||||
USER_CACHE_TTL = 300 # 5 Minuten
|
|
||||||
PRINTER_STATUS_CACHE_TTL = 30 # 30 Sekunden
|
|
||||||
|
|
||||||
def clear_user_cache(user_id=None):
|
|
||||||
"""Löscht User-Cache"""
|
|
||||||
with _user_cache_lock:
|
|
||||||
if user_id:
|
|
||||||
_user_cache.pop(user_id, None)
|
|
||||||
else:
|
|
||||||
_user_cache.clear()
|
|
||||||
|
|
||||||
def clear_printer_status_cache():
|
|
||||||
"""Löscht Drucker-Status-Cache"""
|
|
||||||
with _printer_status_cache_lock:
|
|
||||||
_printer_status_cache.clear()
|
|
||||||
|
|
||||||
# ===== AGGRESSIVE SHUTDOWN HANDLER =====
|
|
||||||
def aggressive_shutdown_handler(sig, frame):
|
|
||||||
"""Aggressiver Signal-Handler für sofortiges Herunterfahren bei Strg+C"""
|
|
||||||
print("\n[ALERT] STRG+C ERKANNT - SOFORTIGES SHUTDOWN!")
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Caches leeren
|
|
||||||
clear_user_cache()
|
|
||||||
clear_printer_status_cache()
|
|
||||||
|
|
||||||
# Queue Manager stoppen
|
|
||||||
try:
|
|
||||||
stop_queue_manager()
|
|
||||||
print("[OK] Queue Manager gestoppt")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[WARN] Queue Manager Stop fehlgeschlagen: {e}")
|
|
||||||
|
|
||||||
# Datenbank-Cleanup
|
|
||||||
try:
|
|
||||||
from models import _engine, _scoped_session
|
|
||||||
if _scoped_session:
|
|
||||||
_scoped_session.remove()
|
|
||||||
if _engine:
|
|
||||||
_engine.dispose()
|
|
||||||
print("[OK] Datenbank geschlossen")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[WARN] Datenbank-Cleanup fehlgeschlagen: {e}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[ERROR] Fehler beim Cleanup: {e}")
|
|
||||||
|
|
||||||
print("[STOP] SOFORTIGES PROGRAMM-ENDE")
|
|
||||||
os._exit(0)
|
|
||||||
|
|
||||||
def register_aggressive_shutdown():
|
|
||||||
"""Registriert den aggressiven Shutdown-Handler"""
|
|
||||||
signal.signal(signal.SIGINT, aggressive_shutdown_handler)
|
|
||||||
signal.signal(signal.SIGTERM, aggressive_shutdown_handler)
|
|
||||||
|
|
||||||
if os.name == 'nt':
|
|
||||||
try:
|
|
||||||
signal.signal(signal.SIGBREAK, aggressive_shutdown_handler)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
signal.signal(signal.SIGHUP, aggressive_shutdown_handler)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
atexit.register(lambda: print("[RESTART] Atexit-Handler ausgeführt"))
|
|
||||||
print("[ALERT] AGGRESSIVER STRG+C SHUTDOWN-HANDLER AKTIVIERT")
|
|
||||||
|
|
||||||
# Shutdown-Handler registrieren
|
|
||||||
register_aggressive_shutdown()
|
|
||||||
|
|
||||||
# Flask-App initialisieren
|
|
||||||
app = Flask(__name__)
|
|
||||||
app.secret_key = SECRET_KEY
|
|
||||||
|
|
||||||
# ===== KONFIGURATION ANWENDEN =====
|
|
||||||
USE_OPTIMIZED_CONFIG = should_use_optimized_config()
|
|
||||||
|
|
||||||
if USE_OPTIMIZED_CONFIG:
|
|
||||||
app_logger.info("[START] Aktiviere optimierte Konfiguration")
|
|
||||||
|
|
||||||
app.config.update({
|
|
||||||
"DEBUG": OptimizedConfig.DEBUG,
|
|
||||||
"TESTING": OptimizedConfig.TESTING,
|
|
||||||
"SEND_FILE_MAX_AGE_DEFAULT": OptimizedConfig.SEND_FILE_MAX_AGE_DEFAULT,
|
|
||||||
"TEMPLATES_AUTO_RELOAD": OptimizedConfig.TEMPLATES_AUTO_RELOAD,
|
|
||||||
"EXPLAIN_TEMPLATE_LOADING": OptimizedConfig.EXPLAIN_TEMPLATE_LOADING,
|
|
||||||
"SESSION_COOKIE_SECURE": OptimizedConfig.SESSION_COOKIE_SECURE,
|
|
||||||
"SESSION_COOKIE_HTTPONLY": OptimizedConfig.SESSION_COOKIE_HTTPONLY,
|
|
||||||
"SESSION_COOKIE_SAMESITE": OptimizedConfig.SESSION_COOKIE_SAMESITE,
|
|
||||||
"MAX_CONTENT_LENGTH": OptimizedConfig.MAX_CONTENT_LENGTH,
|
|
||||||
"JSON_SORT_KEYS": OptimizedConfig.JSON_SORT_KEYS,
|
|
||||||
"JSONIFY_PRETTYPRINT_REGULAR": OptimizedConfig.JSONIFY_PRETTYPRINT_REGULAR
|
|
||||||
})
|
|
||||||
|
|
||||||
app.jinja_env.globals.update({
|
|
||||||
'optimized_mode': True,
|
|
||||||
'use_minified_assets': OptimizedConfig.USE_MINIFIED_ASSETS,
|
|
||||||
'disable_animations': OptimizedConfig.DISABLE_ANIMATIONS,
|
|
||||||
'limit_glassmorphism': OptimizedConfig.LIMIT_GLASSMORPHISM,
|
|
||||||
'base_template': 'base-optimized.html'
|
|
||||||
})
|
|
||||||
|
|
||||||
@app.after_request
|
|
||||||
def add_optimized_cache_headers(response):
|
|
||||||
"""Fügt optimierte Cache-Header hinzu"""
|
|
||||||
if request.endpoint == 'static' or '/static/' in request.path:
|
|
||||||
response.headers['Cache-Control'] = 'public, max-age=31536000'
|
|
||||||
response.headers['Vary'] = 'Accept-Encoding'
|
|
||||||
return response
|
|
||||||
|
|
||||||
else:
|
|
||||||
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
|
||||||
app.jinja_env.globals.update({
|
|
||||||
'optimized_mode': False,
|
|
||||||
'use_minified_assets': False,
|
|
||||||
'disable_animations': False,
|
|
||||||
'limit_glassmorphism': False,
|
|
||||||
'base_template': 'base.html'
|
|
||||||
})
|
|
||||||
|
|
||||||
# Session-Konfiguration
|
|
||||||
app.config["PERMANENT_SESSION_LIFETIME"] = SESSION_LIFETIME
|
|
||||||
app.config["WTF_CSRF_ENABLED"] = True
|
|
||||||
|
|
||||||
# CSRF-Schutz initialisieren
|
|
||||||
csrf = CSRFProtect(app)
|
|
||||||
|
|
||||||
@app.errorhandler(CSRFError)
|
|
||||||
def csrf_error(error):
|
|
||||||
"""Behandelt CSRF-Fehler"""
|
|
||||||
app_logger.warning(f"CSRF-Fehler: {error.description}")
|
|
||||||
return jsonify({"error": "CSRF-Token ungültig oder fehlt"}), 400
|
|
||||||
|
|
||||||
# Login-Manager initialisieren
|
|
||||||
login_manager = LoginManager()
|
|
||||||
login_manager.init_app(app)
|
|
||||||
login_manager.login_view = "auth.login"
|
|
||||||
login_manager.login_message = "Bitte melden Sie sich an, um auf diese Seite zuzugreifen."
|
|
||||||
|
|
||||||
@login_manager.user_loader
|
|
||||||
def load_user(user_id):
|
|
||||||
"""Lädt einen Benutzer für Flask-Login"""
|
|
||||||
try:
|
|
||||||
with get_db_session() as db_session:
|
|
||||||
user = db_session.query(User).filter_by(id=int(user_id)).first()
|
|
||||||
if user:
|
|
||||||
db_session.expunge(user)
|
|
||||||
return user
|
|
||||||
except Exception as e:
|
|
||||||
app_logger.error(f"Fehler beim Laden des Benutzers {user_id}: {str(e)}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
# ===== BLUEPRINTS REGISTRIEREN =====
|
|
||||||
app.register_blueprint(auth_blueprint)
|
|
||||||
app.register_blueprint(user_blueprint)
|
|
||||||
app.register_blueprint(admin_blueprint)
|
|
||||||
app.register_blueprint(admin_api_blueprint)
|
|
||||||
app.register_blueprint(guest_blueprint)
|
|
||||||
app.register_blueprint(calendar_blueprint)
|
|
||||||
app.register_blueprint(users_blueprint)
|
|
||||||
app.register_blueprint(printers_blueprint)
|
|
||||||
app.register_blueprint(jobs_blueprint)
|
|
||||||
app.register_blueprint(kiosk_blueprint)
|
|
||||||
app.register_blueprint(uploads_blueprint)
|
|
||||||
app.register_blueprint(sessions_blueprint)
|
|
||||||
|
|
||||||
# ===== HILFSSYSTEME INITIALISIEREN =====
|
|
||||||
init_security(app)
|
|
||||||
init_permission_helpers(app)
|
|
||||||
|
|
||||||
# ===== KONTEXT-PROZESSOREN =====
|
|
||||||
@app.context_processor
|
|
||||||
def inject_now():
|
|
||||||
"""Injiziert die aktuelle Zeit in alle Templates"""
|
|
||||||
return {'now': datetime.now}
|
|
||||||
|
|
||||||
@app.template_filter('format_datetime')
|
|
||||||
def format_datetime_filter(value, format='%d.%m.%Y %H:%M'):
|
|
||||||
"""Template-Filter für Datums-Formatierung"""
|
|
||||||
if value is None:
|
|
||||||
return ""
|
|
||||||
if isinstance(value, str):
|
|
||||||
try:
|
|
||||||
value = datetime.fromisoformat(value)
|
|
||||||
except:
|
|
||||||
return value
|
|
||||||
return value.strftime(format)
|
|
||||||
|
|
||||||
@app.template_global()
|
|
||||||
def is_optimized_mode():
|
|
||||||
"""Prüft ob der optimierte Modus aktiv ist"""
|
|
||||||
return USE_OPTIMIZED_CONFIG
|
|
||||||
|
|
||||||
# ===== REQUEST HOOKS =====
|
|
||||||
@app.before_request
|
|
||||||
def log_request_info():
|
|
||||||
"""Loggt Request-Informationen"""
|
|
||||||
if request.endpoint != 'static':
|
|
||||||
app_logger.debug(f"Request: {request.method} {request.path}")
|
|
||||||
|
|
||||||
@app.after_request
|
|
||||||
def log_response_info(response):
|
|
||||||
"""Loggt Response-Informationen"""
|
|
||||||
if request.endpoint != 'static':
|
|
||||||
app_logger.debug(f"Response: {response.status_code}")
|
|
||||||
return response
|
|
||||||
|
|
||||||
@app.before_request
|
|
||||||
def check_session_activity():
|
|
||||||
"""Prüft Session-Aktivität und meldet inaktive Benutzer ab"""
|
|
||||||
if current_user.is_authenticated:
|
|
||||||
last_activity = session.get('last_activity')
|
|
||||||
if last_activity:
|
|
||||||
try:
|
|
||||||
last_activity_time = datetime.fromisoformat(last_activity)
|
|
||||||
if (datetime.now() - last_activity_time).total_seconds() > SESSION_LIFETIME.total_seconds():
|
|
||||||
app_logger.info(f"Session abgelaufen für Benutzer {current_user.id}")
|
|
||||||
logout_user()
|
|
||||||
return redirect(url_for('auth.login'))
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Aktivität aktualisieren
|
|
||||||
session['last_activity'] = datetime.now().isoformat()
|
|
||||||
session.permanent = True
|
|
||||||
|
|
||||||
# ===== HAUPTROUTEN =====
|
|
||||||
@app.route("/")
|
|
||||||
def index():
|
|
||||||
"""Startseite - leitet zur Login-Seite oder zum Dashboard"""
|
|
||||||
if current_user.is_authenticated:
|
|
||||||
return redirect(url_for("dashboard"))
|
|
||||||
return redirect(url_for("auth.login"))
|
|
||||||
|
|
||||||
@app.route("/dashboard")
|
|
||||||
@login_required
|
|
||||||
def dashboard():
|
|
||||||
"""Haupt-Dashboard"""
|
|
||||||
return render_template("dashboard.html")
|
|
||||||
|
|
||||||
@app.route("/admin")
|
|
||||||
@login_required
|
|
||||||
def admin():
|
|
||||||
"""Admin-Dashboard"""
|
|
||||||
if not current_user.is_admin:
|
|
||||||
abort(403)
|
|
||||||
return redirect(url_for("admin.dashboard"))
|
|
||||||
|
|
||||||
# Statische Seiten
|
|
||||||
@app.route("/privacy")
|
|
||||||
def privacy():
|
|
||||||
"""Datenschutzerklärung"""
|
|
||||||
return render_template("privacy.html")
|
|
||||||
|
|
||||||
@app.route("/terms")
|
|
||||||
def terms():
|
|
||||||
"""Nutzungsbedingungen"""
|
|
||||||
return render_template("terms.html")
|
|
||||||
|
|
||||||
@app.route("/imprint")
|
|
||||||
def imprint():
|
|
||||||
"""Impressum"""
|
|
||||||
return render_template("imprint.html")
|
|
||||||
|
|
||||||
@app.route("/legal")
|
|
||||||
def legal():
|
|
||||||
"""Rechtliche Hinweise - Weiterleitung zum Impressum"""
|
|
||||||
return redirect(url_for("imprint"))
|
|
||||||
|
|
||||||
# ===== FEHLERBEHANDLUNG =====
|
|
||||||
@app.errorhandler(404)
|
|
||||||
def not_found_error(error):
|
|
||||||
"""404-Fehlerseite"""
|
|
||||||
return render_template('errors/404.html'), 404
|
|
||||||
|
|
||||||
@app.errorhandler(403)
|
|
||||||
def forbidden_error(error):
|
|
||||||
"""403-Fehlerseite"""
|
|
||||||
return render_template('errors/403.html'), 403
|
|
||||||
|
|
||||||
@app.errorhandler(500)
|
|
||||||
def internal_error(error):
|
|
||||||
"""500-Fehlerseite"""
|
|
||||||
app_logger.error(f"Interner Serverfehler: {str(error)}")
|
|
||||||
return render_template('errors/500.html'), 500
|
|
||||||
|
|
||||||
# ===== HAUPTFUNKTION =====
|
|
||||||
def main():
|
|
||||||
"""Hauptfunktion zum Starten der Anwendung"""
|
|
||||||
try:
|
|
||||||
# Datenbank initialisieren
|
|
||||||
init_database()
|
|
||||||
|
|
||||||
# Initial-Admin erstellen falls nicht vorhanden
|
|
||||||
create_initial_admin()
|
|
||||||
|
|
||||||
# Queue Manager starten
|
|
||||||
start_queue_manager()
|
|
||||||
|
|
||||||
# Job Scheduler starten
|
|
||||||
scheduler = get_job_scheduler()
|
|
||||||
if scheduler:
|
|
||||||
scheduler.start()
|
|
||||||
|
|
||||||
# SSL-Kontext
|
|
||||||
ssl_context = None
|
|
||||||
try:
|
|
||||||
from utils.ssl_config import get_ssl_context
|
|
||||||
ssl_context = get_ssl_context()
|
|
||||||
except ImportError:
|
|
||||||
app_logger.warning("SSL-Konfiguration nicht verfügbar")
|
|
||||||
|
|
||||||
# Server starten
|
|
||||||
host = os.getenv('FLASK_HOST', '0.0.0.0')
|
|
||||||
port = int(os.getenv('FLASK_PORT', 5000))
|
|
||||||
|
|
||||||
app_logger.info(f"[START] Server startet auf {host}:{port}")
|
|
||||||
|
|
||||||
if ssl_context:
|
|
||||||
app.run(host=host, port=port, ssl_context=ssl_context, threaded=True)
|
|
||||||
else:
|
|
||||||
app.run(host=host, port=port, threaded=True)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
app_logger.error(f"Fehler beim Starten der Anwendung: {str(e)}")
|
|
||||||
raise
|
|
||||||
finally:
|
|
||||||
# Cleanup
|
|
||||||
try:
|
|
||||||
stop_queue_manager()
|
|
||||||
if scheduler:
|
|
||||||
scheduler.shutdown()
|
|
||||||
cleanup_rate_limiter()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
BIN
backend/blueprints/__pycache__/admin_unified.cpython-311.pyc
Normal file
BIN
backend/blueprints/__pycache__/admin_unified.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/blueprints/__pycache__/api_simple.cpython-311.pyc
Normal file
BIN
backend/blueprints/__pycache__/api_simple.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/blueprints/__pycache__/auth.cpython-311.pyc
Normal file
BIN
backend/blueprints/__pycache__/auth.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
backend/blueprints/__pycache__/kiosk.cpython-311.pyc
Normal file
BIN
backend/blueprints/__pycache__/kiosk.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
backend/blueprints/__pycache__/sessions.cpython-311.pyc
Normal file
BIN
backend/blueprints/__pycache__/sessions.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/blueprints/__pycache__/tapo_control.cpython-311.pyc
Normal file
BIN
backend/blueprints/__pycache__/tapo_control.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/blueprints/__pycache__/uploads.cpython-311.pyc
Normal file
BIN
backend/blueprints/__pycache__/uploads.cpython-311.pyc
Normal file
Binary file not shown.
BIN
backend/blueprints/__pycache__/user_management.cpython-311.pyc
Normal file
BIN
backend/blueprints/__pycache__/user_management.cpython-311.pyc
Normal file
Binary file not shown.
1738
backend/blueprints/admin_unified.py
Normal file
1738
backend/blueprints/admin_unified.py
Normal file
File diff suppressed because it is too large
Load Diff
225
backend/blueprints/api_simple.py
Normal file
225
backend/blueprints/api_simple.py
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
"""
|
||||||
|
Einfache API-Endpunkte für Tapo-Steckdosen-Steuerung
|
||||||
|
Minimale REST-API für externe Zugriffe
|
||||||
|
"""
|
||||||
|
|
||||||
|
from flask import Blueprint, jsonify, request
|
||||||
|
from flask_login import login_required, current_user
|
||||||
|
import ipaddress
|
||||||
|
import time
|
||||||
|
|
||||||
|
from utils.tapo_controller import tapo_controller
|
||||||
|
from utils.logging_config import get_logger
|
||||||
|
from utils.permissions import require_permission, Permission
|
||||||
|
from models import get_db_session, Printer
|
||||||
|
|
||||||
|
# Blueprint initialisieren
|
||||||
|
api_blueprint = Blueprint('api', __name__, url_prefix='/api/v1')
|
||||||
|
|
||||||
|
# Logger konfigurieren
|
||||||
|
api_logger = get_logger("api_simple")
|
||||||
|
|
||||||
|
@api_blueprint.route("/tapo/outlets", methods=["GET"])
|
||||||
|
@login_required
|
||||||
|
@require_permission(Permission.CONTROL_PRINTER)
|
||||||
|
def list_outlets():
|
||||||
|
"""Listet alle verfügbaren Tapo-Steckdosen auf."""
|
||||||
|
try:
|
||||||
|
db_session = get_db_session()
|
||||||
|
printers_with_tapo = db_session.query(Printer).filter(
|
||||||
|
Printer.active == True,
|
||||||
|
Printer.plug_ip.isnot(None)
|
||||||
|
).all()
|
||||||
|
|
||||||
|
outlets = []
|
||||||
|
for printer in printers_with_tapo:
|
||||||
|
outlets.append({
|
||||||
|
'id': printer.id,
|
||||||
|
'name': printer.name,
|
||||||
|
'ip': printer.plug_ip,
|
||||||
|
'location': printer.location or "Unbekannt",
|
||||||
|
'model': printer.model or "P110"
|
||||||
|
})
|
||||||
|
|
||||||
|
db_session.close()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'outlets': outlets,
|
||||||
|
'count': len(outlets),
|
||||||
|
'timestamp': time.time()
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
api_logger.error(f"Fehler beim Auflisten der Outlets: {e}")
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': str(e)
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
@api_blueprint.route("/tapo/outlet/<ip>/status", methods=["GET"])
|
||||||
|
@login_required
|
||||||
|
@require_permission(Permission.CONTROL_PRINTER)
|
||||||
|
def get_outlet_status_api(ip):
|
||||||
|
"""Holt den Status einer spezifischen Steckdose."""
|
||||||
|
try:
|
||||||
|
# IP validieren
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(ip)
|
||||||
|
except ValueError:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': 'Ungültige IP-Adresse'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Status prüfen
|
||||||
|
reachable, status = tapo_controller.check_outlet_status(ip)
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'ip': ip,
|
||||||
|
'status': status,
|
||||||
|
'reachable': reachable,
|
||||||
|
'timestamp': time.time()
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
api_logger.error(f"API Fehler beim Status-Check für {ip}: {e}")
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': str(e)
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
@api_blueprint.route("/tapo/outlet/<ip>/control", methods=["POST"])
|
||||||
|
@login_required
|
||||||
|
@require_permission(Permission.CONTROL_PRINTER)
|
||||||
|
def control_outlet_api(ip):
|
||||||
|
"""Schaltet eine Steckdose ein oder aus."""
|
||||||
|
try:
|
||||||
|
# IP validieren
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(ip)
|
||||||
|
except ValueError:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': 'Ungültige IP-Adresse'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Aktion aus Request Body
|
||||||
|
data = request.get_json()
|
||||||
|
if not data or 'action' not in data:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': 'Aktion erforderlich (on/off)'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
action = data['action']
|
||||||
|
if action not in ['on', 'off']:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': 'Ungültige Aktion. Nur "on" oder "off" erlaubt.'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Steckdose schalten
|
||||||
|
state = action == 'on'
|
||||||
|
success = tapo_controller.toggle_plug(ip, state)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
action_text = "eingeschaltet" if state else "ausgeschaltet"
|
||||||
|
api_logger.info(f"✅ API: Steckdose {ip} {action_text} durch {current_user.name}")
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'ip': ip,
|
||||||
|
'action': action,
|
||||||
|
'message': f'Steckdose {action_text}',
|
||||||
|
'timestamp': time.time()
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': f'Fehler beim Schalten der Steckdose'
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
api_logger.error(f"API Fehler beim Schalten von {ip}: {e}")
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': str(e)
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
@api_blueprint.route("/tapo/status/all", methods=["GET"])
|
||||||
|
@login_required
|
||||||
|
@require_permission(Permission.CONTROL_PRINTER)
|
||||||
|
def get_all_status_api():
|
||||||
|
"""Holt den Status aller Steckdosen."""
|
||||||
|
try:
|
||||||
|
db_session = get_db_session()
|
||||||
|
printers_with_tapo = db_session.query(Printer).filter(
|
||||||
|
Printer.active == True,
|
||||||
|
Printer.plug_ip.isnot(None)
|
||||||
|
).all()
|
||||||
|
|
||||||
|
outlets = []
|
||||||
|
online_count = 0
|
||||||
|
|
||||||
|
for printer in printers_with_tapo:
|
||||||
|
try:
|
||||||
|
reachable, status = tapo_controller.check_outlet_status(
|
||||||
|
printer.plug_ip,
|
||||||
|
printer_id=printer.id
|
||||||
|
)
|
||||||
|
|
||||||
|
if reachable:
|
||||||
|
online_count += 1
|
||||||
|
|
||||||
|
outlets.append({
|
||||||
|
'id': printer.id,
|
||||||
|
'name': printer.name,
|
||||||
|
'ip': printer.plug_ip,
|
||||||
|
'location': printer.location or "Unbekannt",
|
||||||
|
'status': status,
|
||||||
|
'reachable': reachable
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
api_logger.warning(f"API Status-Check für {printer.plug_ip} fehlgeschlagen: {e}")
|
||||||
|
outlets.append({
|
||||||
|
'id': printer.id,
|
||||||
|
'name': printer.name,
|
||||||
|
'ip': printer.plug_ip,
|
||||||
|
'location': printer.location or "Unbekannt",
|
||||||
|
'status': 'error',
|
||||||
|
'reachable': False,
|
||||||
|
'error': str(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
db_session.close()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'outlets': outlets,
|
||||||
|
'summary': {
|
||||||
|
'total': len(outlets),
|
||||||
|
'online': online_count,
|
||||||
|
'offline': len(outlets) - online_count
|
||||||
|
},
|
||||||
|
'timestamp': time.time()
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
api_logger.error(f"API Fehler beim Abrufen aller Status: {e}")
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': str(e)
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
@api_blueprint.route("/health", methods=["GET"])
|
||||||
|
def health_check():
|
||||||
|
"""API Gesundheitscheck."""
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'service': 'MYP Platform Tapo API',
|
||||||
|
'version': '1.0',
|
||||||
|
'timestamp': time.time()
|
||||||
|
})
|
387
backend/blueprints/tapo_control.py
Normal file
387
backend/blueprints/tapo_control.py
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
"""
|
||||||
|
Tapo-Steckdosen-Steuerung Blueprint
|
||||||
|
Eigenständige Web-Interface für direkte Tapo-Steckdosen-Kontrolle
|
||||||
|
"""
|
||||||
|
|
||||||
|
from flask import Blueprint, render_template, request, jsonify, flash, redirect, url_for
|
||||||
|
from flask_login import login_required, current_user
|
||||||
|
from datetime import datetime
|
||||||
|
import ipaddress
|
||||||
|
import time
|
||||||
|
|
||||||
|
from blueprints.admin_unified import admin_required
|
||||||
|
from utils.tapo_controller import tapo_controller
|
||||||
|
from utils.logging_config import get_logger
|
||||||
|
from utils.performance_tracker import measure_execution_time
|
||||||
|
from utils.permissions import require_permission, Permission
|
||||||
|
from models import get_db_session, Printer
|
||||||
|
|
||||||
|
# Blueprint initialisieren
|
||||||
|
tapo_blueprint = Blueprint('tapo', __name__, url_prefix='/tapo')
|
||||||
|
|
||||||
|
# Logger konfigurieren
|
||||||
|
tapo_logger = get_logger("tapo_control")
|
||||||
|
|
||||||
|
@tapo_blueprint.route("/")
|
||||||
|
@login_required
|
||||||
|
@require_permission(Permission.CONTROL_PRINTER)
|
||||||
|
def tapo_dashboard():
|
||||||
|
"""Haupt-Dashboard für Tapo-Steckdosen-Steuerung."""
|
||||||
|
try:
|
||||||
|
tapo_logger.info(f"Tapo Dashboard aufgerufen von Benutzer: {current_user.name}")
|
||||||
|
|
||||||
|
# Alle konfigurierten Tapo-Steckdosen aus der Datenbank laden
|
||||||
|
db_session = get_db_session()
|
||||||
|
printers_with_tapo = db_session.query(Printer).filter(
|
||||||
|
Printer.active == True,
|
||||||
|
Printer.plug_ip.isnot(None)
|
||||||
|
).all()
|
||||||
|
|
||||||
|
# Status aller Steckdosen abrufen - auch wenn sie nicht erreichbar sind
|
||||||
|
outlets_status = {}
|
||||||
|
online_count = 0
|
||||||
|
|
||||||
|
for printer in printers_with_tapo:
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
|
if reachable:
|
||||||
|
online_count += 1
|
||||||
|
tapo_logger.info(f"✅ Tapo-Steckdose {printer.plug_ip} erreichbar - Status: {status}")
|
||||||
|
else:
|
||||||
|
tapo_logger.warning(f"⚠️ Tapo-Steckdose {printer.plug_ip} nicht erreichbar")
|
||||||
|
|
||||||
|
outlets_status[printer.plug_ip] = {
|
||||||
|
'printer_name': printer.name,
|
||||||
|
'printer_id': printer.id,
|
||||||
|
'ip': printer.plug_ip,
|
||||||
|
'status': status,
|
||||||
|
'reachable': reachable,
|
||||||
|
'location': printer.location or "Unbekannt"
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
'status': 'error',
|
||||||
|
'reachable': False,
|
||||||
|
'location': printer.location or "Unbekannt",
|
||||||
|
'error': str(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
db_session.close()
|
||||||
|
|
||||||
|
tapo_logger.info(f"Dashboard geladen: {len(outlets_status)} Steckdosen, {online_count} online")
|
||||||
|
|
||||||
|
return render_template('tapo_control.html',
|
||||||
|
outlets=outlets_status,
|
||||||
|
total_outlets=len(outlets_status),
|
||||||
|
online_outlets=online_count)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
@tapo_blueprint.route("/control", methods=["POST"])
|
||||||
|
@login_required
|
||||||
|
@require_permission(Permission.CONTROL_PRINTER)
|
||||||
|
@measure_execution_time(logger=tapo_logger, task_name="Tapo-Steckdosen-Steuerung")
|
||||||
|
def control_outlet():
|
||||||
|
"""Schaltet eine Tapo-Steckdose direkt ein oder aus."""
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
ip = data.get('ip')
|
||||||
|
action = data.get('action') # 'on' oder 'off'
|
||||||
|
|
||||||
|
if not ip or not action:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': 'IP-Adresse und Aktion sind erforderlich'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# IP-Adresse validieren
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(ip)
|
||||||
|
except ValueError:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': 'Ungültige IP-Adresse'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
if action not in ['on', 'off']:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': 'Ungültige Aktion. Nur "on" oder "off" erlaubt.'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Steckdose schalten
|
||||||
|
state = action == 'on'
|
||||||
|
success = tapo_controller.toggle_plug(ip, state)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
action_text = "eingeschaltet" if state else "ausgeschaltet"
|
||||||
|
tapo_logger.info(f"✅ Tapo-Steckdose {ip} erfolgreich {action_text} durch {current_user.name}")
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'message': f'Steckdose {ip} erfolgreich {action_text}',
|
||||||
|
'ip': ip,
|
||||||
|
'action': action,
|
||||||
|
'timestamp': datetime.now().isoformat(),
|
||||||
|
'user': current_user.name
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
action_text = "einschalten" if state else "ausschalten"
|
||||||
|
tapo_logger.error(f"❌ Fehler beim {action_text} der Steckdose {ip}")
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': f'Fehler beim {action_text} der Steckdose {ip}'
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
tapo_logger.error(f"Unerwarteter Fehler bei Steckdosen-Steuerung: {e}")
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': f'Interner Serverfehler: {str(e)}'
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
@tapo_blueprint.route("/status/<ip>", methods=["GET"])
|
||||||
|
@login_required
|
||||||
|
@require_permission(Permission.CONTROL_PRINTER)
|
||||||
|
def get_outlet_status(ip):
|
||||||
|
"""Holt den aktuellen Status einer spezifischen Tapo-Steckdose."""
|
||||||
|
try:
|
||||||
|
# IP-Adresse validieren
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(ip)
|
||||||
|
except ValueError:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': 'Ungültige IP-Adresse'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Status prüfen
|
||||||
|
reachable, status = tapo_controller.check_outlet_status(ip)
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'ip': ip,
|
||||||
|
'status': status,
|
||||||
|
'reachable': reachable,
|
||||||
|
'timestamp': datetime.now().isoformat()
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
tapo_logger.error(f"Fehler beim Abrufen des Status für {ip}: {e}")
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': f'Fehler beim Status-Check: {str(e)}'
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
@tapo_blueprint.route("/discover", methods=["POST"])
|
||||||
|
@login_required
|
||||||
|
@admin_required
|
||||||
|
@measure_execution_time(logger=tapo_logger, task_name="Tapo-Steckdosen-Erkennung")
|
||||||
|
def discover_outlets():
|
||||||
|
"""Startet die automatische Erkennung von Tapo-Steckdosen."""
|
||||||
|
try:
|
||||||
|
tapo_logger.info(f"🔍 Starte Tapo-Steckdosen-Erkennung auf Anfrage von {current_user.name}")
|
||||||
|
|
||||||
|
# Discovery starten
|
||||||
|
results = tapo_controller.auto_discover_outlets()
|
||||||
|
|
||||||
|
success_count = sum(1 for success in results.values() if success)
|
||||||
|
total_count = len(results)
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'message': f'Erkennung abgeschlossen: {success_count}/{total_count} Steckdosen gefunden',
|
||||||
|
'results': results,
|
||||||
|
'discovered_count': success_count,
|
||||||
|
'total_tested': total_count,
|
||||||
|
'timestamp': datetime.now().isoformat()
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
tapo_logger.error(f"Fehler bei der Steckdosen-Erkennung: {e}")
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': f'Fehler bei der Erkennung: {str(e)}'
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
@tapo_blueprint.route("/test/<ip>", methods=["POST"])
|
||||||
|
@login_required
|
||||||
|
@require_permission(Permission.CONTROL_PRINTER)
|
||||||
|
def test_connection(ip):
|
||||||
|
"""Testet die Verbindung zu einer spezifischen Tapo-Steckdose."""
|
||||||
|
try:
|
||||||
|
# IP-Adresse validieren
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(ip)
|
||||||
|
except ValueError:
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': 'Ungültige IP-Adresse'
|
||||||
|
}), 400
|
||||||
|
|
||||||
|
# Verbindung testen
|
||||||
|
test_result = tapo_controller.test_connection(ip)
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'ip': ip,
|
||||||
|
'test_result': test_result,
|
||||||
|
'timestamp': datetime.now().isoformat()
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
tapo_logger.error(f"Fehler beim Verbindungstest für {ip}: {e}")
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': f'Fehler beim Verbindungstest: {str(e)}'
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
@tapo_blueprint.route("/all-status", methods=["GET"])
|
||||||
|
@login_required
|
||||||
|
@require_permission(Permission.CONTROL_PRINTER)
|
||||||
|
def get_all_status():
|
||||||
|
"""Holt den Status aller konfigurierten Tapo-Steckdosen."""
|
||||||
|
try:
|
||||||
|
# Alle Tapo-Steckdosen aus der Datenbank laden
|
||||||
|
db_session = get_db_session()
|
||||||
|
printers_with_tapo = db_session.query(Printer).filter(
|
||||||
|
Printer.active == True,
|
||||||
|
Printer.plug_ip.isnot(None)
|
||||||
|
).all()
|
||||||
|
|
||||||
|
all_status = {}
|
||||||
|
online_count = 0
|
||||||
|
total_count = len(printers_with_tapo)
|
||||||
|
|
||||||
|
tapo_logger.info(f"Status-Abfrage für {total_count} Tapo-Steckdosen gestartet")
|
||||||
|
|
||||||
|
for printer in printers_with_tapo:
|
||||||
|
try:
|
||||||
|
tapo_logger.debug(f"Prüfe Status für {printer.plug_ip} ({printer.name})")
|
||||||
|
reachable, status = tapo_controller.check_outlet_status(
|
||||||
|
printer.plug_ip,
|
||||||
|
printer_id=printer.id
|
||||||
|
)
|
||||||
|
|
||||||
|
if reachable:
|
||||||
|
online_count += 1
|
||||||
|
tapo_logger.debug(f"✅ {printer.plug_ip} erreichbar - Status: {status}")
|
||||||
|
else:
|
||||||
|
tapo_logger.debug(f"⚠️ {printer.plug_ip} nicht erreichbar")
|
||||||
|
|
||||||
|
all_status[printer.plug_ip] = {
|
||||||
|
'printer_name': printer.name,
|
||||||
|
'printer_id': printer.id,
|
||||||
|
'status': status,
|
||||||
|
'reachable': reachable,
|
||||||
|
'location': printer.location or "Unbekannt",
|
||||||
|
'last_checked': time.time()
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
tapo_logger.warning(f"❌ Status-Check für {printer.plug_ip} fehlgeschlagen: {e}")
|
||||||
|
all_status[printer.plug_ip] = {
|
||||||
|
'printer_name': printer.name,
|
||||||
|
'printer_id': printer.id,
|
||||||
|
'status': 'error',
|
||||||
|
'reachable': False,
|
||||||
|
'location': printer.location or "Unbekannt",
|
||||||
|
'error': str(e),
|
||||||
|
'last_checked': time.time()
|
||||||
|
}
|
||||||
|
|
||||||
|
db_session.close()
|
||||||
|
|
||||||
|
# Zusammenfassung loggen
|
||||||
|
tapo_logger.info(f"Status-Abfrage abgeschlossen: {online_count}/{total_count} Steckdosen erreichbar")
|
||||||
|
|
||||||
|
response_data = {
|
||||||
|
'success': True,
|
||||||
|
'outlets': all_status,
|
||||||
|
'summary': {
|
||||||
|
'total': total_count,
|
||||||
|
'online': online_count,
|
||||||
|
'offline': total_count - online_count,
|
||||||
|
'last_update': time.time()
|
||||||
|
},
|
||||||
|
'timestamp': datetime.now().isoformat()
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonify(response_data)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
tapo_logger.error(f"Fehler beim Abrufen aller Tapo-Status: {e}")
|
||||||
|
return jsonify({
|
||||||
|
'success': False,
|
||||||
|
'error': str(e),
|
||||||
|
'outlets': {},
|
||||||
|
'summary': {'total': 0, 'online': 0, 'offline': 0}
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
@tapo_blueprint.route("/manual-control", methods=["GET", "POST"])
|
||||||
|
@login_required
|
||||||
|
@admin_required
|
||||||
|
def manual_control():
|
||||||
|
"""Manuelle Steuerung für beliebige IP-Adressen (Admin-only)."""
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template('tapo_manual_control.html')
|
||||||
|
|
||||||
|
try:
|
||||||
|
ip = request.form.get('ip')
|
||||||
|
action = request.form.get('action')
|
||||||
|
|
||||||
|
if not ip or not action:
|
||||||
|
flash('IP-Adresse und Aktion sind erforderlich', 'error')
|
||||||
|
return redirect(url_for('tapo.manual_control'))
|
||||||
|
|
||||||
|
# IP-Adresse validieren
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(ip)
|
||||||
|
except ValueError:
|
||||||
|
flash('Ungültige IP-Adresse', 'error')
|
||||||
|
return redirect(url_for('tapo.manual_control'))
|
||||||
|
|
||||||
|
if action not in ['on', 'off', 'status']:
|
||||||
|
flash('Ungültige Aktion', 'error')
|
||||||
|
return redirect(url_for('tapo.manual_control'))
|
||||||
|
|
||||||
|
if action == 'status':
|
||||||
|
# Status abfragen
|
||||||
|
reachable, status = tapo_controller.check_outlet_status(ip)
|
||||||
|
if reachable:
|
||||||
|
flash(f'Steckdose {ip} ist {status.upper()}', 'success')
|
||||||
|
else:
|
||||||
|
flash(f'Steckdose {ip} ist nicht erreichbar', 'error')
|
||||||
|
else:
|
||||||
|
# Ein/Ausschalten
|
||||||
|
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"✅ Manuelle Steuerung: {ip} {action_text} durch {current_user.name}")
|
||||||
|
else:
|
||||||
|
action_text = "einschalten" if state else "ausschalten"
|
||||||
|
flash(f'Fehler beim {action_text} der Steckdose {ip}', 'error')
|
||||||
|
|
||||||
|
return redirect(url_for('tapo.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'))
|
626
backend/blueprints/user_management.py
Normal file
626
backend/blueprints/user_management.py
Normal file
@ -0,0 +1,626 @@
|
|||||||
|
"""
|
||||||
|
Vereinheitlichtes User-Management-Blueprint für das MYP System
|
||||||
|
|
||||||
|
Konsolidierte Implementierung aller benutzerbezogenen Funktionen:
|
||||||
|
- Benutzer-Selbstverwaltung (ursprünglich user.py)
|
||||||
|
- Administrative Benutzerverwaltung (ursprünglich users.py)
|
||||||
|
- Vereinheitlichte API-Schnittstellen
|
||||||
|
|
||||||
|
Funktionsbereiche:
|
||||||
|
- /user/* - Selbstverwaltung für eingeloggte Benutzer
|
||||||
|
- /admin/users/* - Administrative Benutzerverwaltung
|
||||||
|
- /api/users/* - Unified API Layer
|
||||||
|
|
||||||
|
Optimierungen:
|
||||||
|
- Einheitliche Database-Session-Verwaltung
|
||||||
|
- Konsistente Error-Handling und Logging
|
||||||
|
- Vollständige API-Kompatibilität zu beiden ursprünglichen Blueprints
|
||||||
|
|
||||||
|
Autor: MYP Team - Konsolidiert für IHK-Projektarbeit
|
||||||
|
Datum: 2025-06-09
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
from flask import Blueprint, render_template, request, jsonify, redirect, url_for, flash, make_response, abort
|
||||||
|
from flask_login import login_required, current_user
|
||||||
|
from werkzeug.security import check_password_hash
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
from functools import wraps
|
||||||
|
from models import User, UserPermission, get_cached_session
|
||||||
|
from utils.logging_config import get_logger
|
||||||
|
|
||||||
|
# ===== BLUEPRINT-KONFIGURATION =====
|
||||||
|
|
||||||
|
# Hauptblueprint für User-Management
|
||||||
|
users_blueprint = Blueprint('users', __name__)
|
||||||
|
|
||||||
|
# Logger für verschiedene Funktionsbereiche
|
||||||
|
user_logger = get_logger("user")
|
||||||
|
users_logger = get_logger("users")
|
||||||
|
|
||||||
|
# ===== DECORATOR-FUNKTIONEN =====
|
||||||
|
|
||||||
|
def users_admin_required(f):
|
||||||
|
"""
|
||||||
|
Decorator für Admin-Berechtigung bei Benutzerverwaltung.
|
||||||
|
Erweitert den Standard-Admin-Check um spezifische User-Management-Rechte.
|
||||||
|
"""
|
||||||
|
@wraps(f)
|
||||||
|
@login_required
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
# Grundlegende Admin-Prüfung
|
||||||
|
if not current_user.is_authenticated:
|
||||||
|
users_logger.warning("Unauthenticated access attempt to user management")
|
||||||
|
abort(401)
|
||||||
|
|
||||||
|
# Admin-Status prüfen (doppelte Methode für Robustheit)
|
||||||
|
is_admin = False
|
||||||
|
if hasattr(current_user, 'is_admin') and current_user.is_admin:
|
||||||
|
is_admin = True
|
||||||
|
elif hasattr(current_user, 'role') and current_user.role == 'admin':
|
||||||
|
is_admin = True
|
||||||
|
|
||||||
|
if not is_admin:
|
||||||
|
users_logger.warning(f"Non-admin user {current_user.id} attempted to access user management")
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
users_logger.info(f"Admin access granted to {current_user.username} for function {f.__name__}")
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
|
||||||
|
# ===== BENUTZER-SELBSTVERWALTUNG (ursprünglich user.py) =====
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/profile', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def user_profile():
|
||||||
|
"""Benutzerprofil-Seite anzeigen"""
|
||||||
|
try:
|
||||||
|
user_logger.info(f"User {current_user.username} accessed profile page")
|
||||||
|
return render_template('profile.html', user=current_user)
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error loading profile page: {str(e)}")
|
||||||
|
flash("Fehler beim Laden des Profils", "error")
|
||||||
|
return redirect(url_for('dashboard'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/settings', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def user_settings():
|
||||||
|
"""Benutzereinstellungen-Seite anzeigen"""
|
||||||
|
try:
|
||||||
|
user_logger.info(f"User {current_user.username} accessed settings page")
|
||||||
|
return render_template('settings.html', user=current_user)
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error loading settings page: {str(e)}")
|
||||||
|
flash("Fehler beim Laden der Einstellungen", "error")
|
||||||
|
return redirect(url_for('dashboard'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/update-profile', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def update_profile_form():
|
||||||
|
"""Profil via Formular aktualisieren"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
flash("Benutzer nicht gefunden", "error")
|
||||||
|
return redirect(url_for('users.user_profile'))
|
||||||
|
|
||||||
|
# Formular-Daten extrahieren
|
||||||
|
user.name = request.form.get('name', user.name)
|
||||||
|
user.email = request.form.get('email', user.email)
|
||||||
|
user.department = request.form.get('department', user.department)
|
||||||
|
user.position = request.form.get('position', user.position)
|
||||||
|
user.phone = request.form.get('phone', user.phone)
|
||||||
|
user.bio = request.form.get('bio', user.bio)
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated profile via form")
|
||||||
|
flash("Profil erfolgreich aktualisiert", "success")
|
||||||
|
return redirect(url_for('users.user_profile'))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error updating profile via form: {str(e)}")
|
||||||
|
flash("Fehler beim Aktualisieren des Profils", "error")
|
||||||
|
return redirect(url_for('users.user_profile'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/profile', methods=['PUT'])
|
||||||
|
@login_required
|
||||||
|
def update_profile_api():
|
||||||
|
"""Profil via API aktualisieren"""
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
# API-Daten verarbeiten
|
||||||
|
updatable_fields = ['name', 'email', 'department', 'position', 'phone', 'bio']
|
||||||
|
for field in updatable_fields:
|
||||||
|
if field in data:
|
||||||
|
setattr(user, field, data[field])
|
||||||
|
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated profile via API")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Profil erfolgreich aktualisiert"
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error updating profile via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Aktualisieren des Profils"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/api/user/settings', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def user_settings_api():
|
||||||
|
"""Benutzereinstellungen via API abrufen oder aktualisieren"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
if request.method == 'GET':
|
||||||
|
# Einstellungen abrufen
|
||||||
|
settings = {
|
||||||
|
'theme_preference': getattr(user, 'theme_preference', 'auto'),
|
||||||
|
'language_preference': getattr(user, 'language_preference', 'de'),
|
||||||
|
'email_notifications': getattr(user, 'email_notifications', True),
|
||||||
|
'browser_notifications': getattr(user, 'browser_notifications', True),
|
||||||
|
'dashboard_layout': getattr(user, 'dashboard_layout', 'default'),
|
||||||
|
'compact_mode': getattr(user, 'compact_mode', False),
|
||||||
|
'show_completed_jobs': getattr(user, 'show_completed_jobs', True),
|
||||||
|
'auto_refresh_interval': getattr(user, 'auto_refresh_interval', 30),
|
||||||
|
'privacy': {
|
||||||
|
'auto_logout': getattr(user, 'auto_logout_timeout', 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} retrieved settings via API")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"settings": settings
|
||||||
|
})
|
||||||
|
|
||||||
|
elif request.method == 'POST':
|
||||||
|
# Einstellungen aktualisieren
|
||||||
|
data = request.get_json()
|
||||||
|
|
||||||
|
# Einstellungen aktualisieren
|
||||||
|
settings_fields = [
|
||||||
|
'theme_preference', 'language_preference', 'email_notifications',
|
||||||
|
'browser_notifications', 'dashboard_layout', 'compact_mode',
|
||||||
|
'show_completed_jobs', 'auto_refresh_interval'
|
||||||
|
]
|
||||||
|
|
||||||
|
for field in settings_fields:
|
||||||
|
if field in data:
|
||||||
|
setattr(user, field, data[field])
|
||||||
|
|
||||||
|
# Privacy-Einstellungen
|
||||||
|
if 'privacy' in data and isinstance(data['privacy'], dict):
|
||||||
|
if 'auto_logout' in data['privacy']:
|
||||||
|
user.auto_logout_timeout = data['privacy']['auto_logout']
|
||||||
|
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated settings via API")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Einstellungen erfolgreich aktualisiert"
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error handling user settings API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Verarbeiten der Einstellungen"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/api/update-settings', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def update_settings_api():
|
||||||
|
"""Benutzereinstellungen via API aktualisieren (Legacy-Kompatibilität)"""
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
# Einstellungen aktualisieren
|
||||||
|
settings_fields = [
|
||||||
|
'theme_preference', 'language_preference', 'email_notifications',
|
||||||
|
'browser_notifications', 'dashboard_layout', 'compact_mode',
|
||||||
|
'show_completed_jobs', 'auto_refresh_interval'
|
||||||
|
]
|
||||||
|
|
||||||
|
for field in settings_fields:
|
||||||
|
if field in data:
|
||||||
|
setattr(user, field, data[field])
|
||||||
|
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated settings via API")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Einstellungen erfolgreich aktualisiert"
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error updating settings via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Aktualisieren der Einstellungen"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/update-settings', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def update_settings_form():
|
||||||
|
"""Benutzereinstellungen via Formular aktualisieren"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
flash("Benutzer nicht gefunden", "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
# Formular-Einstellungen verarbeiten
|
||||||
|
user.theme_preference = request.form.get('theme_preference', user.theme_preference)
|
||||||
|
user.language_preference = request.form.get('language_preference', user.language_preference)
|
||||||
|
user.email_notifications = 'email_notifications' in request.form
|
||||||
|
user.browser_notifications = 'browser_notifications' in request.form
|
||||||
|
user.dashboard_layout = request.form.get('dashboard_layout', user.dashboard_layout)
|
||||||
|
user.compact_mode = 'compact_mode' in request.form
|
||||||
|
user.show_completed_jobs = 'show_completed_jobs' in request.form
|
||||||
|
|
||||||
|
auto_refresh = request.form.get('auto_refresh_interval')
|
||||||
|
if auto_refresh:
|
||||||
|
user.auto_refresh_interval = int(auto_refresh)
|
||||||
|
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated settings via form")
|
||||||
|
flash("Einstellungen erfolgreich aktualisiert", "success")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error updating settings via form: {str(e)}")
|
||||||
|
flash("Fehler beim Aktualisieren der Einstellungen", "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/change-password', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def change_password():
|
||||||
|
"""Passwort ändern (unterstützt Form und JSON)"""
|
||||||
|
try:
|
||||||
|
# Daten aus Request extrahieren (Form oder JSON)
|
||||||
|
if request.is_json:
|
||||||
|
data = request.get_json()
|
||||||
|
current_password = data.get('current_password')
|
||||||
|
new_password = data.get('new_password')
|
||||||
|
confirm_password = data.get('confirm_password')
|
||||||
|
else:
|
||||||
|
current_password = request.form.get('current_password')
|
||||||
|
new_password = request.form.get('new_password')
|
||||||
|
confirm_password = request.form.get('confirm_password')
|
||||||
|
|
||||||
|
# Validierung
|
||||||
|
if not all([current_password, new_password, confirm_password]):
|
||||||
|
error_msg = "Alle Passwort-Felder sind erforderlich"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 400
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
if new_password != confirm_password:
|
||||||
|
error_msg = "Neue Passwörter stimmen nicht überein"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 400
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
if len(new_password) < 8:
|
||||||
|
error_msg = "Neues Passwort muss mindestens 8 Zeichen lang sein"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 400
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
# Aktuelles Passwort prüfen
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user or not check_password_hash(user.password_hash, current_password):
|
||||||
|
error_msg = "Aktuelles Passwort ist falsch"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 400
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
# Neues Passwort setzen
|
||||||
|
user.set_password(new_password)
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} changed password successfully")
|
||||||
|
|
||||||
|
success_msg = "Passwort erfolgreich geändert"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"success": True, "message": success_msg})
|
||||||
|
flash(success_msg, "success")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error changing password: {str(e)}")
|
||||||
|
error_msg = "Fehler beim Ändern des Passworts"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 500
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/export', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def export_user_data():
|
||||||
|
"""DSGVO-konformer Datenexport für Benutzer"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
# Umfassende Benutzerdaten sammeln
|
||||||
|
user_data = {
|
||||||
|
"export_info": {
|
||||||
|
"generated_at": datetime.now().isoformat(),
|
||||||
|
"user_id": user.id,
|
||||||
|
"export_type": "DSGVO_complete_data_export"
|
||||||
|
},
|
||||||
|
"personal_data": {
|
||||||
|
"username": user.username,
|
||||||
|
"email": user.email,
|
||||||
|
"name": user.name,
|
||||||
|
"department": user.department,
|
||||||
|
"position": user.position,
|
||||||
|
"phone": user.phone,
|
||||||
|
"bio": user.bio,
|
||||||
|
"role": user.role,
|
||||||
|
"active": user.active,
|
||||||
|
"created_at": user.created_at.isoformat() if user.created_at else None,
|
||||||
|
"updated_at": user.updated_at.isoformat() if user.updated_at else None,
|
||||||
|
"last_login": user.last_login.isoformat() if user.last_login else None
|
||||||
|
},
|
||||||
|
"preferences": {
|
||||||
|
"theme_preference": user.theme_preference,
|
||||||
|
"language_preference": user.language_preference,
|
||||||
|
"email_notifications": user.email_notifications,
|
||||||
|
"browser_notifications": user.browser_notifications,
|
||||||
|
"dashboard_layout": user.dashboard_layout,
|
||||||
|
"compact_mode": user.compact_mode,
|
||||||
|
"show_completed_jobs": user.show_completed_jobs,
|
||||||
|
"auto_refresh_interval": user.auto_refresh_interval
|
||||||
|
},
|
||||||
|
"system_info": {
|
||||||
|
"total_jobs_created": len(user.jobs) if hasattr(user, 'jobs') else 0,
|
||||||
|
"account_status": "active" if user.active else "inactive"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Jobs-Daten hinzufügen (falls verfügbar)
|
||||||
|
if hasattr(user, 'jobs'):
|
||||||
|
user_data["job_history"] = []
|
||||||
|
for job in user.jobs:
|
||||||
|
job_info = {
|
||||||
|
"id": job.id,
|
||||||
|
"title": job.title,
|
||||||
|
"status": job.status,
|
||||||
|
"created_at": job.created_at.isoformat() if job.created_at else None,
|
||||||
|
"updated_at": job.updated_at.isoformat() if job.updated_at else None
|
||||||
|
}
|
||||||
|
user_data["job_history"].append(job_info)
|
||||||
|
|
||||||
|
# JSON-Response mit Download-Headers erstellen
|
||||||
|
response = make_response(jsonify(user_data))
|
||||||
|
response.headers['Content-Type'] = 'application/json; charset=utf-8'
|
||||||
|
response.headers['Content-Disposition'] = f'attachment; filename=user_data_export_{user.username}_{datetime.now().strftime("%Y%m%d_%H%M%S")}.json'
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} exported personal data (DSGVO)")
|
||||||
|
return response
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error exporting user data: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Exportieren der Benutzerdaten"}), 500
|
||||||
|
|
||||||
|
# ===== ADMINISTRATIVE BENUTZERVERWALTUNG (ursprünglich users.py) =====
|
||||||
|
|
||||||
|
@users_blueprint.route('/admin/users/<int:user_id>/permissions', methods=['GET'])
|
||||||
|
@users_admin_required
|
||||||
|
def user_permissions_page(user_id):
|
||||||
|
"""Admin-Seite für Benutzerberechtigungen"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
flash("Benutzer nicht gefunden", "error")
|
||||||
|
return redirect(url_for('admin.users_overview'))
|
||||||
|
|
||||||
|
# UserPermissions laden oder erstellen
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
session.add(permissions)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
users_logger.info(f"Admin {current_user.username} accessed permissions for user {user.username}")
|
||||||
|
return render_template('admin/user_permissions.html', user=user, permissions=permissions)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error loading user permissions page: {str(e)}")
|
||||||
|
flash("Fehler beim Laden der Benutzerberechtigungen", "error")
|
||||||
|
return redirect(url_for('admin.users_overview'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/api/users/<int:user_id>/permissions', methods=['GET'])
|
||||||
|
@users_admin_required
|
||||||
|
def get_user_permissions_api(user_id):
|
||||||
|
"""API-Endpunkt für Benutzerberechtigungen"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
session.add(permissions)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
permissions_data = {
|
||||||
|
"user_id": user_id,
|
||||||
|
"username": user.username,
|
||||||
|
"can_start_jobs": permissions.can_start_jobs,
|
||||||
|
"needs_approval": permissions.needs_approval,
|
||||||
|
"can_approve_jobs": permissions.can_approve_jobs
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonify(permissions_data)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error getting user permissions via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Abrufen der Benutzerberechtigungen"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/api/users/<int:user_id>/permissions', methods=['PUT'])
|
||||||
|
@users_admin_required
|
||||||
|
def update_user_permissions_api(user_id):
|
||||||
|
"""Benutzerberechtigungen via API aktualisieren"""
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
session.add(permissions)
|
||||||
|
|
||||||
|
# Berechtigungen aktualisieren
|
||||||
|
if 'can_start_jobs' in data:
|
||||||
|
permissions.can_start_jobs = data['can_start_jobs']
|
||||||
|
if 'needs_approval' in data:
|
||||||
|
permissions.needs_approval = data['needs_approval']
|
||||||
|
if 'can_approve_jobs' in data:
|
||||||
|
permissions.can_approve_jobs = data['can_approve_jobs']
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
users_logger.info(f"Admin {current_user.username} updated permissions for user {user.username}")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Berechtigungen erfolgreich aktualisiert"
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error updating user permissions via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Aktualisieren der Berechtigungen"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/admin/users/<int:user_id>/permissions/update', methods=['POST'])
|
||||||
|
@users_admin_required
|
||||||
|
def update_user_permissions_form(user_id):
|
||||||
|
"""Benutzerberechtigungen via Formular aktualisieren"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
if not user:
|
||||||
|
flash("Benutzer nicht gefunden", "error")
|
||||||
|
return redirect(url_for('admin.users_overview'))
|
||||||
|
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
session.add(permissions)
|
||||||
|
|
||||||
|
# Formular-Daten verarbeiten
|
||||||
|
permissions.can_start_jobs = 'can_start_jobs' in request.form
|
||||||
|
permissions.needs_approval = 'needs_approval' in request.form
|
||||||
|
permissions.can_approve_jobs = 'can_approve_jobs' in request.form
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
users_logger.info(f"Admin {current_user.username} updated permissions for user {user.username} via form")
|
||||||
|
flash("Berechtigungen erfolgreich aktualisiert", "success")
|
||||||
|
return redirect(url_for('users.user_permissions_page', user_id=user_id))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error updating user permissions via form: {str(e)}")
|
||||||
|
flash("Fehler beim Aktualisieren der Berechtigungen", "error")
|
||||||
|
return redirect(url_for('users.user_permissions_page', user_id=user_id))
|
||||||
|
|
||||||
|
@users_blueprint.route('/admin/users/<int:user_id>/edit/permissions', methods=['GET'])
|
||||||
|
@users_admin_required
|
||||||
|
def edit_user_permissions_section(user_id):
|
||||||
|
"""Berechtigungsbereich für Benutzer bearbeiten"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
|
||||||
|
return render_template('admin/edit_user_permissions_section.html', user=user, permissions=permissions)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error loading user permissions edit section: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Laden der Berechtigungsbearbeitung"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/api/users/<int:user_id>', methods=['GET'])
|
||||||
|
@users_admin_required
|
||||||
|
def get_user_details_api(user_id):
|
||||||
|
"""API-Endpunkt für detaillierte Benutzerdaten"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
user_data = {
|
||||||
|
"id": user.id,
|
||||||
|
"username": user.username,
|
||||||
|
"email": user.email,
|
||||||
|
"name": user.name,
|
||||||
|
"role": user.role,
|
||||||
|
"active": user.active,
|
||||||
|
"created_at": user.created_at.isoformat() if user.created_at else None,
|
||||||
|
"last_login": user.last_login.isoformat() if user.last_login else None,
|
||||||
|
"department": user.department,
|
||||||
|
"position": user.position,
|
||||||
|
"phone": user.phone,
|
||||||
|
"bio": user.bio,
|
||||||
|
"theme_preference": user.theme_preference,
|
||||||
|
"language_preference": user.language_preference,
|
||||||
|
"email_notifications": user.email_notifications,
|
||||||
|
"browser_notifications": user.browser_notifications
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonify(user_data)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error getting user details via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Abrufen der Benutzerdaten"}), 500
|
664
backend/blueprints/user_management.py.backup
Normal file
664
backend/blueprints/user_management.py.backup
Normal file
@ -0,0 +1,664 @@
|
|||||||
|
"""
|
||||||
|
Vereinheitlichtes User-Management-Blueprint für das MYP System
|
||||||
|
|
||||||
|
Konsolidierte Implementierung aller benutzerbezogenen Funktionen:
|
||||||
|
- Benutzer-Selbstverwaltung (ursprünglich user.py)
|
||||||
|
- Administrative Benutzerverwaltung (ursprünglich users.py)
|
||||||
|
- Vereinheitlichte API-Schnittstellen
|
||||||
|
|
||||||
|
Funktionsbereiche:
|
||||||
|
- /user/* - Selbstverwaltung für eingeloggte Benutzer
|
||||||
|
- /admin/users/* - Administrative Benutzerverwaltung
|
||||||
|
- /api/users/* - Unified API Layer
|
||||||
|
|
||||||
|
Optimierungen:
|
||||||
|
- Einheitliche Database-Session-Verwaltung
|
||||||
|
- Konsistente Error-Handling und Logging
|
||||||
|
- Vollständige API-Kompatibilität zu beiden ursprünglichen Blueprints
|
||||||
|
|
||||||
|
Autor: MYP Team - Konsolidiert für IHK-Projektarbeit
|
||||||
|
Datum: 2025-06-09
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
from flask import Blueprint, render_template, request, jsonify, redirect, url_for, flash, make_response, abort
|
||||||
|
from flask_login import login_required, current_user
|
||||||
|
from werkzeug.security import check_password_hash
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
from functools import wraps
|
||||||
|
from models import User, UserPermission, get_cached_session
|
||||||
|
from utils.logging_config import get_logger
|
||||||
|
|
||||||
|
# ===== BLUEPRINT-KONFIGURATION =====
|
||||||
|
|
||||||
|
# Hauptblueprint für User-Management
|
||||||
|
users_blueprint = Blueprint('users', __name__)
|
||||||
|
|
||||||
|
# Logger für verschiedene Funktionsbereiche
|
||||||
|
user_logger = get_logger("user")
|
||||||
|
users_logger = get_logger("users")
|
||||||
|
|
||||||
|
# ===== DECORATOR-FUNKTIONEN =====
|
||||||
|
|
||||||
|
def users_admin_required(f):
|
||||||
|
"""
|
||||||
|
Decorator für Admin-Berechtigung bei Benutzerverwaltung.
|
||||||
|
Erweitert den Standard-Admin-Check um spezifische User-Management-Rechte.
|
||||||
|
"""
|
||||||
|
@wraps(f)
|
||||||
|
@login_required
|
||||||
|
def decorated_function(*args, **kwargs):
|
||||||
|
# Grundlegende Admin-Prüfung
|
||||||
|
if not current_user.is_authenticated:
|
||||||
|
users_logger.warning("Unauthenticated access attempt to user management")
|
||||||
|
abort(401)
|
||||||
|
|
||||||
|
# Admin-Status prüfen (doppelte Methode für Robustheit)
|
||||||
|
is_admin = False
|
||||||
|
if hasattr(current_user, 'is_admin') and current_user.is_admin:
|
||||||
|
is_admin = True
|
||||||
|
elif hasattr(current_user, 'role') and current_user.role == 'admin':
|
||||||
|
is_admin = True
|
||||||
|
|
||||||
|
if not is_admin:
|
||||||
|
users_logger.warning(f"Non-admin user {current_user.id} attempted to access user management")
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
users_logger.info(f"Admin access granted to {current_user.username} for function {f.__name__}")
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
return decorated_function
|
||||||
|
|
||||||
|
# ===== BENUTZER-SELBSTVERWALTUNG (ursprünglich user.py) =====
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/profile', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def user_profile():
|
||||||
|
"""Benutzerprofil-Seite anzeigen"""
|
||||||
|
try:
|
||||||
|
user_logger.info(f"User {current_user.username} accessed profile page")
|
||||||
|
return render_template('user/profile.html', user=current_user)
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error loading profile page: {str(e)}")
|
||||||
|
flash("Fehler beim Laden des Profils", "error")
|
||||||
|
return redirect(url_for('dashboard'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/settings', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def user_settings():
|
||||||
|
"""Benutzereinstellungen-Seite anzeigen"""
|
||||||
|
try:
|
||||||
|
user_logger.info(f"User {current_user.username} accessed settings page")
|
||||||
|
return render_template('user/settings.html', user=current_user)
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error loading settings page: {str(e)}")
|
||||||
|
flash("Fehler beim Laden der Einstellungen", "error")
|
||||||
|
return redirect(url_for('dashboard'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/update-profile', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def update_profile_form():
|
||||||
|
"""Profil via Formular aktualisieren"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
flash("Benutzer nicht gefunden", "error")
|
||||||
|
return redirect(url_for('users.user_profile'))
|
||||||
|
|
||||||
|
# Formular-Daten extrahieren
|
||||||
|
user.name = request.form.get('name', user.name)
|
||||||
|
user.email = request.form.get('email', user.email)
|
||||||
|
user.department = request.form.get('department', user.department)
|
||||||
|
user.position = request.form.get('position', user.position)
|
||||||
|
user.phone = request.form.get('phone', user.phone)
|
||||||
|
user.bio = request.form.get('bio', user.bio)
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated profile via form")
|
||||||
|
flash("Profil erfolgreich aktualisiert", "success")
|
||||||
|
return redirect(url_for('users.user_profile'))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error updating profile via form: {str(e)}")
|
||||||
|
flash("Fehler beim Aktualisieren des Profils", "error")
|
||||||
|
return redirect(url_for('users.user_profile'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/profile', methods=['PUT'])
|
||||||
|
@login_required
|
||||||
|
def update_profile_api():
|
||||||
|
"""Profil via API aktualisieren"""
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
# API-Daten verarbeiten
|
||||||
|
updatable_fields = ['name', 'email', 'department', 'position', 'phone', 'bio']
|
||||||
|
for field in updatable_fields:
|
||||||
|
if field in data:
|
||||||
|
setattr(user, field, data[field])
|
||||||
|
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated profile via API")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Profil erfolgreich aktualisiert"
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error updating profile via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Aktualisieren des Profils"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/api/user/settings', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def user_settings_api():
|
||||||
|
"""Benutzereinstellungen via API abrufen oder aktualisieren"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
if request.method == 'GET':
|
||||||
|
# Einstellungen abrufen
|
||||||
|
settings = {
|
||||||
|
'theme_preference': getattr(user, 'theme_preference', 'auto'),
|
||||||
|
'language_preference': getattr(user, 'language_preference', 'de'),
|
||||||
|
'email_notifications': getattr(user, 'email_notifications', True),
|
||||||
|
'browser_notifications': getattr(user, 'browser_notifications', True),
|
||||||
|
'dashboard_layout': getattr(user, 'dashboard_layout', 'default'),
|
||||||
|
'compact_mode': getattr(user, 'compact_mode', False),
|
||||||
|
'show_completed_jobs': getattr(user, 'show_completed_jobs', True),
|
||||||
|
'auto_refresh_interval': getattr(user, 'auto_refresh_interval', 30),
|
||||||
|
'privacy': {
|
||||||
|
'auto_logout': getattr(user, 'auto_logout_timeout', 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} retrieved settings via API")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"settings": settings
|
||||||
|
})
|
||||||
|
|
||||||
|
elif request.method == 'POST':
|
||||||
|
# Einstellungen aktualisieren
|
||||||
|
data = request.get_json()
|
||||||
|
|
||||||
|
# Einstellungen aktualisieren
|
||||||
|
settings_fields = [
|
||||||
|
'theme_preference', 'language_preference', 'email_notifications',
|
||||||
|
'browser_notifications', 'dashboard_layout', 'compact_mode',
|
||||||
|
'show_completed_jobs', 'auto_refresh_interval'
|
||||||
|
]
|
||||||
|
|
||||||
|
for field in settings_fields:
|
||||||
|
if field in data:
|
||||||
|
setattr(user, field, data[field])
|
||||||
|
|
||||||
|
# Privacy-Einstellungen
|
||||||
|
if 'privacy' in data and isinstance(data['privacy'], dict):
|
||||||
|
if 'auto_logout' in data['privacy']:
|
||||||
|
user.auto_logout_timeout = data['privacy']['auto_logout']
|
||||||
|
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated settings via API")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Einstellungen erfolgreich aktualisiert"
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error handling user settings API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Verarbeiten der Einstellungen"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/api/update-settings', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def update_settings_api():
|
||||||
|
"""Benutzereinstellungen via API aktualisieren (Legacy-Kompatibilität)"""
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
# Einstellungen aktualisieren
|
||||||
|
settings_fields = [
|
||||||
|
'theme_preference', 'language_preference', 'email_notifications',
|
||||||
|
'browser_notifications', 'dashboard_layout', 'compact_mode',
|
||||||
|
'show_completed_jobs', 'auto_refresh_interval'
|
||||||
|
]
|
||||||
|
|
||||||
|
for field in settings_fields:
|
||||||
|
if field in data:
|
||||||
|
setattr(user, field, data[field])
|
||||||
|
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated settings via API")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Einstellungen erfolgreich aktualisiert"
|
||||||
|
})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error updating settings via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Aktualisieren der Einstellungen"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/update-settings', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def update_settings_form():
|
||||||
|
"""Benutzereinstellungen via Formular aktualisieren"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
flash("Benutzer nicht gefunden", "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
# Formular-Einstellungen verarbeiten
|
||||||
|
user.theme_preference = request.form.get('theme_preference', user.theme_preference)
|
||||||
|
user.language_preference = request.form.get('language_preference', user.language_preference)
|
||||||
|
user.email_notifications = 'email_notifications' in request.form
|
||||||
|
user.browser_notifications = 'browser_notifications' in request.form
|
||||||
|
user.dashboard_layout = request.form.get('dashboard_layout', user.dashboard_layout)
|
||||||
|
user.compact_mode = 'compact_mode' in request.form
|
||||||
|
user.show_completed_jobs = 'show_completed_jobs' in request.form
|
||||||
|
|
||||||
|
auto_refresh = request.form.get('auto_refresh_interval')
|
||||||
|
if auto_refresh:
|
||||||
|
user.auto_refresh_interval = int(auto_refresh)
|
||||||
|
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} updated settings via form")
|
||||||
|
flash("Einstellungen erfolgreich aktualisiert", "success")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error updating settings via form: {str(e)}")
|
||||||
|
flash("Fehler beim Aktualisieren der Einstellungen", "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/change-password', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def change_password():
|
||||||
|
"""Passwort ändern (unterstützt Form und JSON)"""
|
||||||
|
try:
|
||||||
|
# Daten aus Request extrahieren (Form oder JSON)
|
||||||
|
if request.is_json:
|
||||||
|
data = request.get_json()
|
||||||
|
current_password = data.get('current_password')
|
||||||
|
new_password = data.get('new_password')
|
||||||
|
confirm_password = data.get('confirm_password')
|
||||||
|
else:
|
||||||
|
current_password = request.form.get('current_password')
|
||||||
|
new_password = request.form.get('new_password')
|
||||||
|
confirm_password = request.form.get('confirm_password')
|
||||||
|
|
||||||
|
# Validierung
|
||||||
|
if not all([current_password, new_password, confirm_password]):
|
||||||
|
error_msg = "Alle Passwort-Felder sind erforderlich"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 400
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
if new_password != confirm_password:
|
||||||
|
error_msg = "Neue Passwörter stimmen nicht überein"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 400
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
if len(new_password) < 8:
|
||||||
|
error_msg = "Neues Passwort muss mindestens 8 Zeichen lang sein"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 400
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
# Aktuelles Passwort prüfen
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user or not check_password_hash(user.password_hash, current_password):
|
||||||
|
error_msg = "Aktuelles Passwort ist falsch"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 400
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
# Neues Passwort setzen
|
||||||
|
user.set_password(new_password)
|
||||||
|
user.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} changed password successfully")
|
||||||
|
|
||||||
|
success_msg = "Passwort erfolgreich geändert"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"success": True, "message": success_msg})
|
||||||
|
flash(success_msg, "success")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error changing password: {str(e)}")
|
||||||
|
error_msg = "Fehler beim Ändern des Passworts"
|
||||||
|
if request.is_json:
|
||||||
|
return jsonify({"error": error_msg}), 500
|
||||||
|
flash(error_msg, "error")
|
||||||
|
return redirect(url_for('users.user_settings'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/user/export', methods=['GET'])
|
||||||
|
@login_required
|
||||||
|
def export_user_data():
|
||||||
|
"""DSGVO-konformer Datenexport für Benutzer"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == current_user.id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
# Umfassende Benutzerdaten sammeln
|
||||||
|
user_data = {
|
||||||
|
"export_info": {
|
||||||
|
"generated_at": datetime.now().isoformat(),
|
||||||
|
"user_id": user.id,
|
||||||
|
"export_type": "DSGVO_complete_data_export"
|
||||||
|
},
|
||||||
|
"personal_data": {
|
||||||
|
"username": user.username,
|
||||||
|
"email": user.email,
|
||||||
|
"name": user.name,
|
||||||
|
"department": user.department,
|
||||||
|
"position": user.position,
|
||||||
|
"phone": user.phone,
|
||||||
|
"bio": user.bio,
|
||||||
|
"role": user.role,
|
||||||
|
"active": user.active,
|
||||||
|
"created_at": user.created_at.isoformat() if user.created_at else None,
|
||||||
|
"updated_at": user.updated_at.isoformat() if user.updated_at else None,
|
||||||
|
"last_login": user.last_login.isoformat() if user.last_login else None
|
||||||
|
},
|
||||||
|
"preferences": {
|
||||||
|
"theme_preference": user.theme_preference,
|
||||||
|
"language_preference": user.language_preference,
|
||||||
|
"email_notifications": user.email_notifications,
|
||||||
|
"browser_notifications": user.browser_notifications,
|
||||||
|
"dashboard_layout": user.dashboard_layout,
|
||||||
|
"compact_mode": user.compact_mode,
|
||||||
|
"show_completed_jobs": user.show_completed_jobs,
|
||||||
|
"auto_refresh_interval": user.auto_refresh_interval
|
||||||
|
},
|
||||||
|
"system_info": {
|
||||||
|
"total_jobs_created": len(user.jobs) if hasattr(user, 'jobs') else 0,
|
||||||
|
"account_status": "active" if user.active else "inactive"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Jobs-Daten hinzufügen (falls verfügbar)
|
||||||
|
if hasattr(user, 'jobs'):
|
||||||
|
user_data["job_history"] = []
|
||||||
|
for job in user.jobs:
|
||||||
|
job_info = {
|
||||||
|
"id": job.id,
|
||||||
|
"title": job.title,
|
||||||
|
"status": job.status,
|
||||||
|
"created_at": job.created_at.isoformat() if job.created_at else None,
|
||||||
|
"updated_at": job.updated_at.isoformat() if job.updated_at else None
|
||||||
|
}
|
||||||
|
user_data["job_history"].append(job_info)
|
||||||
|
|
||||||
|
# JSON-Response mit Download-Headers erstellen
|
||||||
|
response = make_response(jsonify(user_data))
|
||||||
|
response.headers['Content-Type'] = 'application/json; charset=utf-8'
|
||||||
|
response.headers['Content-Disposition'] = f'attachment; filename=user_data_export_{user.username}_{datetime.now().strftime("%Y%m%d_%H%M%S")}.json'
|
||||||
|
|
||||||
|
user_logger.info(f"User {user.username} exported personal data (DSGVO)")
|
||||||
|
return response
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
user_logger.error(f"Error exporting user data: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Exportieren der Benutzerdaten"}), 500
|
||||||
|
|
||||||
|
# ===== ADMINISTRATIVE BENUTZERVERWALTUNG (ursprünglich users.py) =====
|
||||||
|
|
||||||
|
@users_blueprint.route('/admin/users/<int:user_id>/permissions', methods=['GET'])
|
||||||
|
@users_admin_required
|
||||||
|
def user_permissions_page(user_id):
|
||||||
|
"""Admin-Seite für Benutzerberechtigungen"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
flash("Benutzer nicht gefunden", "error")
|
||||||
|
return redirect(url_for('admin.users_overview'))
|
||||||
|
|
||||||
|
# UserPermissions laden oder erstellen
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
session.add(permissions)
|
||||||
|
session.commit()
|
||||||
|
users_logger.info(f"Admin {current_user.username} accessed permissions for user {user.username}")
|
||||||
|
return render_template('admin/user_permissions.html', user=user, permissions=permissions)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error loading user permissions page: {str(e)}")
|
||||||
|
flash("Fehler beim Laden der Benutzerberechtigungen", "error")
|
||||||
|
return redirect(url_for('admin.users_overview'))
|
||||||
|
|
||||||
|
@users_blueprint.route('/api/users/<int:user_id>/permissions', methods=['GET'])
|
||||||
|
@users_admin_required
|
||||||
|
def get_user_permissions_api(user_id):
|
||||||
|
"""API-Endpunkt für Benutzerberechtigungen"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
session.add(permissions)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
permissions_data = {
|
||||||
|
"user_id": user_id,
|
||||||
|
"username": user.username,
|
||||||
|
"can_start_jobs": permissions.can_start_jobs,
|
||||||
|
"needs_approval": permissions.needs_approval,
|
||||||
|
"can_approve_jobs": permissions.can_approve_jobs,
|
||||||
|
"max_concurrent_jobs": permissions.max_concurrent_jobs,
|
||||||
|
"created_at": permissions.created_at.isoformat() if permissions.created_at else None,
|
||||||
|
"updated_at": permissions.updated_at.isoformat() if permissions.updated_at else None
|
||||||
|
}
|
||||||
|
return jsonify(permissions_data)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error getting user permissions via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Abrufen der Benutzerberechtigungen"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/api/users/<int:user_id>/permissions', methods=['PUT'])
|
||||||
|
@users_admin_required
|
||||||
|
def update_user_permissions_api(user_id):
|
||||||
|
"""Benutzerberechtigungen via API aktualisieren"""
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
with get_cached_session() as session:
|
||||||
|
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
session.add(permissions)
|
||||||
|
|
||||||
|
# Berechtigungen aktualisieren
|
||||||
|
permission_fields = ['can_start_jobs', 'needs_approval', 'can_approve_jobs', 'max_concurrent_jobs']
|
||||||
|
for field in permission_fields:
|
||||||
|
if field in data:
|
||||||
|
setattr(permissions, field, data[field])
|
||||||
|
|
||||||
|
permissions.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
users_logger.info(f"Admin {current_user.username} updated permissions for user {user.username} via API")
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Benutzerberechtigungen erfolgreich aktualisiert"
|
||||||
|
})
|
||||||
|
|
||||||
|
except SQLAlchemyError as e:
|
||||||
|
users_logger.error(f"Database error updating permissions: {str(e)}")
|
||||||
|
return jsonify({"error": "Datenbankfehler beim Aktualisieren der Berechtigungen"}), 500
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error updating user permissions via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Aktualisieren der Benutzerberechtigungen"}), 500
|
||||||
|
|
||||||
|
@users_blueprint.route('/admin/users/<int:user_id>/permissions/update', methods=['POST'])
|
||||||
|
@users_admin_required
|
||||||
|
def update_user_permissions_form(user_id):
|
||||||
|
"""Benutzerberechtigungen via Formular aktualisieren"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
if not user:
|
||||||
|
flash("Benutzer nicht gefunden", "error")
|
||||||
|
return redirect(url_for('admin.users_overview'))
|
||||||
|
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
session.add(permissions)
|
||||||
|
|
||||||
|
# Formular-Daten verarbeiten (Checkboxen)
|
||||||
|
permissions.can_start_jobs = 'can_start_jobs' in request.form
|
||||||
|
permissions.needs_approval = 'needs_approval' in request.form
|
||||||
|
permissions.can_approve_jobs = 'can_approve_jobs' in request.form
|
||||||
|
|
||||||
|
# Max concurrent jobs
|
||||||
|
max_jobs = request.form.get('max_concurrent_jobs')
|
||||||
|
if max_jobs:
|
||||||
|
try:
|
||||||
|
permissions.max_concurrent_jobs = int(max_jobs)
|
||||||
|
except ValueError:
|
||||||
|
permissions.max_concurrent_jobs = 3 # Default
|
||||||
|
|
||||||
|
permissions.updated_at = datetime.now()
|
||||||
|
session.commit()
|
||||||
|
users_logger.info(f"Admin {current_user.username} updated permissions for user {user.username} via form")
|
||||||
|
flash(f"Berechtigungen für {user.username} erfolgreich aktualisiert", "success")
|
||||||
|
return redirect(url_for('users.user_permissions_page', user_id=user_id))
|
||||||
|
|
||||||
|
except SQLAlchemyError as e:
|
||||||
|
users_logger.error(f"Database error updating permissions via form: {str(e)}")
|
||||||
|
flash("Datenbankfehler beim Aktualisieren der Berechtigungen", "error")
|
||||||
|
return redirect(url_for('users.user_permissions_page', user_id=user_id))
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error updating user permissions via form: {str(e)}")
|
||||||
|
flash("Fehler beim Aktualisieren der Benutzerberechtigungen", "error")
|
||||||
|
return redirect(url_for('users.user_permissions_page', user_id=user_id))
|
||||||
|
|
||||||
|
@users_blueprint.route('/admin/users/<int:user_id>/edit/permissions', methods=['GET'])
|
||||||
|
@users_admin_required
|
||||||
|
def edit_user_permissions_section(user_id):
|
||||||
|
"""Berechtigungsbereich für Benutzer-Bearbeitungsformular"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
if not permissions:
|
||||||
|
permissions = UserPermission(user_id=user_id)
|
||||||
|
session.add(permissions)
|
||||||
|
session.commit()
|
||||||
|
# Template-Fragment für AJAX-Anfragen
|
||||||
|
return render_template('admin/user_permissions_section.html', user=user, permissions=permissions)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error loading permissions section: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Laden der Berechtigungen"}), 500
|
||||||
|
|
||||||
|
# ===== UNIFIED API LAYER =====
|
||||||
|
|
||||||
|
@users_blueprint.route('/api/users/<int:user_id>', methods=['GET'])
|
||||||
|
@users_admin_required
|
||||||
|
def get_user_details_api(user_id):
|
||||||
|
"""Vollständige Benutzerdaten via API (Admin-Zugriff)"""
|
||||||
|
try:
|
||||||
|
with get_cached_session() as session:
|
||||||
|
user = session.query(User).filter(User.id == user_id).first()
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return jsonify({"error": "Benutzer nicht gefunden"}), 404
|
||||||
|
|
||||||
|
# Berechtigungen laden
|
||||||
|
permissions = session.query(UserPermission).filter(UserPermission.user_id == user_id).first()
|
||||||
|
|
||||||
|
user_data = {
|
||||||
|
"id": user.id,
|
||||||
|
"username": user.username,
|
||||||
|
"email": user.email,
|
||||||
|
"name": user.name,
|
||||||
|
"role": user.role,
|
||||||
|
"active": user.active,
|
||||||
|
"department": user.department,
|
||||||
|
"position": user.position,
|
||||||
|
"phone": user.phone,
|
||||||
|
"bio": user.bio,
|
||||||
|
"created_at": user.created_at.isoformat() if user.created_at else None,
|
||||||
|
"updated_at": user.updated_at.isoformat() if user.updated_at else None,
|
||||||
|
"last_login": user.last_login.isoformat() if user.last_login else None,
|
||||||
|
"preferences": {
|
||||||
|
"theme_preference": user.theme_preference,
|
||||||
|
"language_preference": user.language_preference,
|
||||||
|
"email_notifications": user.email_notifications,
|
||||||
|
"browser_notifications": user.browser_notifications,
|
||||||
|
"dashboard_layout": user.dashboard_layout,
|
||||||
|
"compact_mode": user.compact_mode,
|
||||||
|
"show_completed_jobs": user.show_completed_jobs,
|
||||||
|
"auto_refresh_interval": user.auto_refresh_interval
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Berechtigungen hinzufügen (falls verfügbar)
|
||||||
|
if permissions:
|
||||||
|
user_data["permissions"] = {
|
||||||
|
"can_start_jobs": permissions.can_start_jobs,
|
||||||
|
"needs_approval": permissions.needs_approval,
|
||||||
|
"can_approve_jobs": permissions.can_approve_jobs,
|
||||||
|
"max_concurrent_jobs": permissions.max_concurrent_jobs
|
||||||
|
}
|
||||||
|
return jsonify(user_data)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
users_logger.error(f"Error getting user details via API: {str(e)}")
|
||||||
|
return jsonify({"error": "Fehler beim Abrufen der Benutzerdaten"}), 500
|
95
backend/create_test_tapo_printers.py
Normal file
95
backend/create_test_tapo_printers.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#!/usr/bin/env python3.11
|
||||||
|
"""
|
||||||
|
Script zum Erstellen von Test-Druckern mit Tapo-Steckdosen
|
||||||
|
"""
|
||||||
|
|
||||||
|
from models import get_db_session, Printer
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
def create_test_printers():
|
||||||
|
"""Erstellt Test-Drucker mit Tapo-Steckdosen."""
|
||||||
|
db = get_db_session()
|
||||||
|
|
||||||
|
# Test-Drucker mit Tapo-Steckdosen
|
||||||
|
test_printers = [
|
||||||
|
{
|
||||||
|
'name': 'Ender 3 Pro',
|
||||||
|
'ip': '192.168.0.100',
|
||||||
|
'plug_ip': '192.168.0.103',
|
||||||
|
'location': 'Werkstatt A',
|
||||||
|
'description': 'Creality Ender 3 Pro - Einsteigermodell'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'Prusa i3 MK3S',
|
||||||
|
'ip': '192.168.0.101',
|
||||||
|
'plug_ip': '192.168.0.104',
|
||||||
|
'location': 'Werkstatt B',
|
||||||
|
'description': 'Prusa i3 MK3S+ - Profi-Drucker'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'Artillery Sidewinder',
|
||||||
|
'ip': '192.168.0.102',
|
||||||
|
'plug_ip': '192.168.0.100',
|
||||||
|
'location': 'Labor',
|
||||||
|
'description': 'Artillery Sidewinder X1 - Großformat'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'Bambu Lab A1 mini',
|
||||||
|
'ip': '192.168.0.105',
|
||||||
|
'plug_ip': '192.168.0.101',
|
||||||
|
'location': 'Entwicklung',
|
||||||
|
'description': 'Bambu Lab A1 mini - Kompakt und schnell'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'Ultimaker S3',
|
||||||
|
'ip': '192.168.0.106',
|
||||||
|
'plug_ip': '192.168.0.102',
|
||||||
|
'location': 'Prototyping',
|
||||||
|
'description': 'Ultimaker S3 - Dual-Extruder'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
created_count = 0
|
||||||
|
updated_count = 0
|
||||||
|
|
||||||
|
for printer_data in test_printers:
|
||||||
|
existing = db.query(Printer).filter_by(name=printer_data['name']).first()
|
||||||
|
|
||||||
|
if not existing:
|
||||||
|
printer = Printer(
|
||||||
|
name=printer_data['name'],
|
||||||
|
ip=printer_data['ip'],
|
||||||
|
plug_ip=printer_data['plug_ip'],
|
||||||
|
location=printer_data['location'],
|
||||||
|
description=printer_data['description'],
|
||||||
|
active=True,
|
||||||
|
created_at=datetime.now()
|
||||||
|
)
|
||||||
|
db.add(printer)
|
||||||
|
created_count += 1
|
||||||
|
print(f"✅ Erstellt: {printer_data['name']} mit Tapo {printer_data['plug_ip']}")
|
||||||
|
else:
|
||||||
|
existing.plug_ip = printer_data['plug_ip']
|
||||||
|
existing.location = printer_data['location']
|
||||||
|
existing.description = printer_data['description']
|
||||||
|
existing.active = True
|
||||||
|
updated_count += 1
|
||||||
|
print(f"🔄 Aktualisiert: {printer_data['name']} mit Tapo {printer_data['plug_ip']}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
db.commit()
|
||||||
|
print(f"\n🎯 Erfolgreich abgeschlossen:")
|
||||||
|
print(f" - {created_count} neue Drucker erstellt")
|
||||||
|
print(f" - {updated_count} Drucker aktualisiert")
|
||||||
|
print(f" - Gesamt: {created_count + updated_count} Drucker mit Tapo-Steckdosen")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db.rollback()
|
||||||
|
print(f"❌ Fehler beim Speichern: {e}")
|
||||||
|
|
||||||
|
finally:
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("🔧 Erstelle Test-Drucker mit Tapo-Steckdosen...")
|
||||||
|
create_test_printers()
|
171
backend/debug_admin.py
Normal file
171
backend/debug_admin.py
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
#!/usr/bin/env python3.11
|
||||||
|
"""
|
||||||
|
Debug-Skript für Admin-Dashboard-Probleme
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
from app import app
|
||||||
|
from models import User, get_cached_session
|
||||||
|
from flask import url_for
|
||||||
|
from flask_login import login_user
|
||||||
|
|
||||||
|
def test_admin_route():
|
||||||
|
"""Testet die Admin-Route mit verschiedenen Szenarien"""
|
||||||
|
|
||||||
|
print("=== ADMIN ROUTE DEBUG ===")
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
try:
|
||||||
|
# 1. Test ohne Login (sollte 302 redirect geben)
|
||||||
|
print("\n1. Test ohne Login:")
|
||||||
|
with app.test_client() as client:
|
||||||
|
response = client.get('/admin/')
|
||||||
|
print(f" Status: {response.status_code}")
|
||||||
|
print(f" Location: {response.headers.get('Location', 'None')}")
|
||||||
|
|
||||||
|
# 2. Admin-Benutzer finden
|
||||||
|
print("\n2. Admin-Benutzer suchen:")
|
||||||
|
with get_cached_session() as session:
|
||||||
|
admin_users = session.query(User).filter(User.role == 'admin').all()
|
||||||
|
print(f" Gefundene Admin-Benutzer: {len(admin_users)}")
|
||||||
|
|
||||||
|
if admin_users:
|
||||||
|
admin_user = admin_users[0]
|
||||||
|
print(f" Admin: {admin_user.username} (ID: {admin_user.id})")
|
||||||
|
|
||||||
|
# 3. Test mit korrektem Flask-Login
|
||||||
|
print("\n3. Test mit Flask-Login:")
|
||||||
|
with app.test_client() as client:
|
||||||
|
# Simuliere Login über POST-Request
|
||||||
|
login_data = {
|
||||||
|
'username': admin_user.username,
|
||||||
|
'password': 'admin123' # Standard-Admin-Passwort
|
||||||
|
}
|
||||||
|
|
||||||
|
# Erst einloggen
|
||||||
|
login_response = client.post('/auth/login', data=login_data, follow_redirects=False)
|
||||||
|
print(f" Login Status: {login_response.status_code}")
|
||||||
|
|
||||||
|
# Dann Admin-Dashboard aufrufen
|
||||||
|
response = client.get('/admin/', follow_redirects=False)
|
||||||
|
print(f" Admin Dashboard Status: {response.status_code}")
|
||||||
|
|
||||||
|
if response.status_code == 500:
|
||||||
|
print(" ERROR DATA:")
|
||||||
|
error_data = response.get_data(as_text=True)
|
||||||
|
print(f" {error_data[:1000]}...")
|
||||||
|
elif response.status_code == 200:
|
||||||
|
print(" SUCCESS: Admin-Dashboard lädt korrekt!")
|
||||||
|
elif response.status_code == 302:
|
||||||
|
print(f" Redirect zu: {response.headers.get('Location', 'Unknown')}")
|
||||||
|
else:
|
||||||
|
print(f" Unerwarteter Status: {response.status_code}")
|
||||||
|
|
||||||
|
# 4. Test der Admin-Dashboard-Funktion direkt
|
||||||
|
print("\n4. Test der Admin-Dashboard-Funktion direkt:")
|
||||||
|
try:
|
||||||
|
from blueprints.admin_unified import admin_dashboard
|
||||||
|
from flask import g
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
|
# Simuliere Request-Context
|
||||||
|
with app.test_request_context('/admin/'):
|
||||||
|
# Simuliere eingeloggten Admin
|
||||||
|
login_user(admin_user)
|
||||||
|
|
||||||
|
# Rufe Dashboard-Funktion direkt auf
|
||||||
|
result = admin_dashboard()
|
||||||
|
print(f" Direkter Aufruf erfolgreich: {type(result)}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f" Direkter Aufruf fehlgeschlagen: {e}")
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(" FEHLER: Kein Admin-Benutzer gefunden!")
|
||||||
|
|
||||||
|
# Admin-Benutzer erstellen
|
||||||
|
print("\n Erstelle Admin-Benutzer...")
|
||||||
|
from models import create_initial_admin
|
||||||
|
success = create_initial_admin()
|
||||||
|
print(f" Admin erstellt: {success}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\nFEHLER: {e}")
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
def test_admin_decorator():
|
||||||
|
"""Testet den Admin-Decorator"""
|
||||||
|
print("\n=== ADMIN DECORATOR TEST ===")
|
||||||
|
|
||||||
|
try:
|
||||||
|
from blueprints.admin_unified import admin_required
|
||||||
|
print("✅ Admin-Decorator importiert")
|
||||||
|
|
||||||
|
# Test-Funktion mit Decorator
|
||||||
|
@admin_required
|
||||||
|
def test_func():
|
||||||
|
return "Success"
|
||||||
|
|
||||||
|
print("✅ Decorator angewendet")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Decorator-Fehler: {e}")
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
def test_template():
|
||||||
|
"""Testet das Admin-Template"""
|
||||||
|
print("\n=== TEMPLATE TEST ===")
|
||||||
|
|
||||||
|
try:
|
||||||
|
with app.app_context():
|
||||||
|
with app.test_request_context('/admin/'):
|
||||||
|
from flask import render_template
|
||||||
|
|
||||||
|
# Test mit leeren Stats
|
||||||
|
result = render_template('admin.html', stats={})
|
||||||
|
print(f"✅ Template gerendert (Länge: {len(result)} Zeichen)")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Template-Fehler: {e}")
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
def check_admin_user_password():
|
||||||
|
"""Überprüft das Admin-Benutzer-Passwort"""
|
||||||
|
print("\n=== ADMIN PASSWORD CHECK ===")
|
||||||
|
|
||||||
|
try:
|
||||||
|
with app.app_context():
|
||||||
|
with get_cached_session() as session:
|
||||||
|
admin_user = session.query(User).filter(User.role == 'admin').first()
|
||||||
|
if admin_user:
|
||||||
|
# Teste verschiedene Standard-Passwörter
|
||||||
|
test_passwords = ['admin123', 'admin', 'password', 'test123']
|
||||||
|
|
||||||
|
for pwd in test_passwords:
|
||||||
|
if admin_user.check_password(pwd):
|
||||||
|
print(f"✅ Admin-Passwort gefunden: {pwd}")
|
||||||
|
return pwd
|
||||||
|
|
||||||
|
print("❌ Kein Standard-Passwort funktioniert")
|
||||||
|
|
||||||
|
# Setze neues Passwort
|
||||||
|
print(" Setze neues Admin-Passwort: admin123")
|
||||||
|
admin_user.set_password('admin123')
|
||||||
|
session.commit()
|
||||||
|
print("✅ Neues Passwort gesetzt")
|
||||||
|
return 'admin123'
|
||||||
|
else:
|
||||||
|
print("❌ Kein Admin-Benutzer gefunden")
|
||||||
|
return None
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Passwort-Check-Fehler: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_admin_decorator()
|
||||||
|
test_template()
|
||||||
|
check_admin_user_password()
|
||||||
|
test_admin_route()
|
266
backend/docs/TAPO_CONTROL.md
Normal file
266
backend/docs/TAPO_CONTROL.md
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
# Tapo-Steckdosen-Steuerung - MYP Platform
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Die Tapo-Steckdosen-Steuerung ist eine eigenständige Web-Interface für die direkte Kontrolle aller TP-Link Tapo-Steckdosen (P100/P110) über die MYP Platform. Diese Funktion ermöglicht es Benutzern, Smart-Steckdosen unabhängig von den Druckern zu verwalten und zu steuern.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### 🔌 Hauptfunktionen
|
||||||
|
- **Live-Status-Überwachung**: Echtzeit-Status aller konfigurierten Tapo-Steckdosen
|
||||||
|
- **Direkte Steuerung**: Ein- und Ausschalten einzelner Steckdosen
|
||||||
|
- **Automatische Erkennung**: Suche nach neuen Tapo-Steckdosen im Netzwerk
|
||||||
|
- **Batch-Operationen**: Gleichzeitiges Steuern mehrerer Steckdosen
|
||||||
|
- **Verbindungstest**: Testen der Erreichbarkeit einzelner Geräte
|
||||||
|
|
||||||
|
### 🛡️ Sicherheit & Berechtigungen
|
||||||
|
- **Rollenbasierte Zugriffskontrolle**: Nur Benutzer mit `CONTROL_PRINTER` Berechtigung haben Zugriff
|
||||||
|
- **Admin-Funktionen**: Erweiterte Funktionen nur für Administratoren
|
||||||
|
- **Audit-Logging**: Alle Aktionen werden protokolliert
|
||||||
|
- **CSRF-Schutz**: Schutz vor Cross-Site Request Forgery
|
||||||
|
|
||||||
|
### 📱 Benutzeroberfläche
|
||||||
|
- **Responsive Design**: Optimiert für Desktop und Mobile
|
||||||
|
- **Live-Updates**: Automatische Status-Aktualisierung alle 30 Sekunden
|
||||||
|
- **Moderne UI**: Glassmorphism-Design mit Dark-Mode-Unterstützung
|
||||||
|
- **Intuitive Bedienung**: Einfache Ein-Klick-Steuerung
|
||||||
|
|
||||||
|
## Zugriff & Navigation
|
||||||
|
|
||||||
|
### Haupt-Dashboard
|
||||||
|
```
|
||||||
|
URL: /tapo/
|
||||||
|
Berechtigung: CONTROL_PRINTER
|
||||||
|
```
|
||||||
|
|
||||||
|
Das Haupt-Dashboard zeigt alle konfigurierten Tapo-Steckdosen mit:
|
||||||
|
- Live-Status (Online/Offline, Ein/Aus)
|
||||||
|
- Zugehöriger Drucker-Name
|
||||||
|
- IP-Adresse
|
||||||
|
- Standort-Information
|
||||||
|
- Direkte Steuerungsbuttons
|
||||||
|
|
||||||
|
### Manuelle Steuerung (Admin)
|
||||||
|
```
|
||||||
|
URL: /tapo/manual-control
|
||||||
|
Berechtigung: ADMIN
|
||||||
|
```
|
||||||
|
|
||||||
|
Erweiterte Funktionen für Administratoren:
|
||||||
|
- Steuerung beliebiger IP-Adressen
|
||||||
|
- Verbindungstests
|
||||||
|
- Notaus-Funktion (alle Steckdosen ausschalten)
|
||||||
|
- Status-Abfrage ohne Drucker-Zuordnung
|
||||||
|
|
||||||
|
## API-Endpunkte
|
||||||
|
|
||||||
|
### Steckdosen-Steuerung
|
||||||
|
```http
|
||||||
|
POST /tapo/control
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"ip": "192.168.1.100",
|
||||||
|
"action": "on|off"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Status abfragen
|
||||||
|
```http
|
||||||
|
GET /tapo/status/{ip}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alle Status abrufen
|
||||||
|
```http
|
||||||
|
GET /tapo/all-status
|
||||||
|
```
|
||||||
|
|
||||||
|
### Automatische Erkennung
|
||||||
|
```http
|
||||||
|
POST /tapo/discover
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verbindungstest
|
||||||
|
```http
|
||||||
|
POST /tapo/test/{ip}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Konfiguration
|
||||||
|
|
||||||
|
### Tapo-Anmeldedaten
|
||||||
|
Die globalen Tapo-Anmeldedaten werden in `utils/settings.py` konfiguriert:
|
||||||
|
|
||||||
|
```python
|
||||||
|
TAPO_USERNAME = "ihr_tapo_username"
|
||||||
|
TAPO_PASSWORD = "ihr_tapo_passwort"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Standard-IP-Bereiche
|
||||||
|
Für die automatische Erkennung können Standard-IP-Adressen definiert werden:
|
||||||
|
|
||||||
|
```python
|
||||||
|
DEFAULT_TAPO_IPS = [
|
||||||
|
"192.168.0.100",
|
||||||
|
"192.168.0.101",
|
||||||
|
"192.168.0.102",
|
||||||
|
# weitere IPs...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Timeout-Einstellungen
|
||||||
|
```python
|
||||||
|
TAPO_TIMEOUT = 5 # Sekunden
|
||||||
|
TAPO_RETRY_COUNT = 3 # Wiederholungsversuche
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation & Setup
|
||||||
|
|
||||||
|
### 1. Abhängigkeiten installieren
|
||||||
|
```bash
|
||||||
|
pip install PyP100
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Tapo-Steckdosen konfigurieren
|
||||||
|
1. Steckdosen über Tapo-App einrichten
|
||||||
|
2. Statische IP-Adressen zuweisen
|
||||||
|
3. Anmeldedaten in der Plattform konfigurieren
|
||||||
|
|
||||||
|
### 3. Drucker-Zuordnung
|
||||||
|
Steckdosen werden automatisch erkannt wenn sie in den Drucker-Einstellungen konfiguriert sind:
|
||||||
|
- Admin → Drucker verwalten → Drucker bearbeiten
|
||||||
|
- IP-Adresse der Tapo-Steckdose eingeben
|
||||||
|
|
||||||
|
## Fehlerbehebung
|
||||||
|
|
||||||
|
### Häufige Probleme
|
||||||
|
|
||||||
|
#### Steckdose nicht erreichbar
|
||||||
|
1. **Netzwerk-Verbindung prüfen**
|
||||||
|
```bash
|
||||||
|
ping 192.168.1.100
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Tapo-App-Konfiguration überprüfen**
|
||||||
|
- Steckdose in Tapo-App sichtbar?
|
||||||
|
- WLAN-Verbindung stabil?
|
||||||
|
- Remote-Zugriff aktiviert?
|
||||||
|
|
||||||
|
3. **Anmeldedaten verifizieren**
|
||||||
|
- Username/Passwort korrekt?
|
||||||
|
- Account nicht gesperrt?
|
||||||
|
|
||||||
|
#### Verbindung funktioniert, aber keine Steuerung
|
||||||
|
1. **Berechtigungen prüfen**
|
||||||
|
- Hat der Benutzer `CONTROL_PRINTER` Berechtigung?
|
||||||
|
- Ist die Steckdose einem aktiven Drucker zugeordnet?
|
||||||
|
|
||||||
|
2. **Firewall/Router-Einstellungen**
|
||||||
|
- Port 9999 (Tapo-Standard) offen?
|
||||||
|
- Keine Blockierung zwischen Subnets?
|
||||||
|
|
||||||
|
#### Performance-Probleme
|
||||||
|
1. **Timeout-Werte anpassen**
|
||||||
|
```python
|
||||||
|
TAPO_TIMEOUT = 10 # Erhöhen bei langsamen Verbindungen
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Anzahl gleichzeitiger Verbindungen reduzieren**
|
||||||
|
3. **WLAN-Signal der Steckdosen verbessern**
|
||||||
|
|
||||||
|
### Debug-Logging
|
||||||
|
Für detaillierte Fehlermeldungen Debug-Logging aktivieren:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# In utils/logging_config.py
|
||||||
|
TAPO_LOG_LEVEL = "DEBUG"
|
||||||
|
```
|
||||||
|
|
||||||
|
Logs finden Sie unter:
|
||||||
|
```
|
||||||
|
backend/logs/tapo_controller/tapo_controller.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sicherheitshinweise
|
||||||
|
|
||||||
|
### Netzwerk-Sicherheit
|
||||||
|
- **VLAN-Isolation**: Tapo-Steckdosen in separates VLAN
|
||||||
|
- **Firewalling**: Nur notwendige Ports öffnen
|
||||||
|
- **Monitoring**: Ungewöhnliche Aktivitäten überwachen
|
||||||
|
|
||||||
|
### Zugriffskontrolle
|
||||||
|
- **Starke Passwörter**: Für Tapo-Accounts verwenden
|
||||||
|
- **Berechtigungen**: Minimale notwendige Rechte vergeben
|
||||||
|
- **Audit-Logs**: Regelmäßig überprüfen
|
||||||
|
|
||||||
|
### Physische Sicherheit
|
||||||
|
- **Steckdosen-Zugang**: Physischen Zugang beschränken
|
||||||
|
- **Reset-Buttons**: Vor unbefugtem Zugriff schützen
|
||||||
|
|
||||||
|
## Erweiterte Funktionen
|
||||||
|
|
||||||
|
### Zeitgesteuerte Schaltungen
|
||||||
|
```python
|
||||||
|
# Beispiel für geplante Abschaltung
|
||||||
|
from utils.tapo_controller import tapo_controller
|
||||||
|
import schedule
|
||||||
|
|
||||||
|
def shutdown_all_outlets():
|
||||||
|
results = tapo_controller.initialize_all_outlets()
|
||||||
|
print(f"Alle Steckdosen ausgeschaltet: {results}")
|
||||||
|
|
||||||
|
# Jeden Tag um 22:00 alle ausschalten
|
||||||
|
schedule.every().day.at("22:00").do(shutdown_all_outlets)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Energiemonitoring (P110)
|
||||||
|
```python
|
||||||
|
# P110-spezifische Funktionen für Energiemessung
|
||||||
|
device_info = tapo_controller._collect_device_info(p100, device_info)
|
||||||
|
power_consumption = device_info.get('power_consumption')
|
||||||
|
voltage = device_info.get('voltage')
|
||||||
|
current = device_info.get('current')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Integration mit anderen Systemen
|
||||||
|
Die API-Endpunkte können auch von externen Systemen genutzt werden:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# cURL-Beispiele
|
||||||
|
curl -X POST http://localhost:5000/tapo/control \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"ip": "192.168.1.100", "action": "on"}'
|
||||||
|
|
||||||
|
curl http://localhost:5000/tapo/status/192.168.1.100
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
1. **Caching nutzen**: Status-Abfragen werden automatisch gecacht
|
||||||
|
2. **Batch-Operationen**: Mehrere Steckdosen gleichzeitig steuern
|
||||||
|
3. **Timeout-Optimierung**: Für lokale Netzwerke niedrigere Werte
|
||||||
|
|
||||||
|
### Zuverlässigkeit
|
||||||
|
1. **Retry-Mechanismus**: Automatische Wiederholung bei Fehlern
|
||||||
|
2. **Fallback-Strategien**: Alternative Steuerungsmethoden vorbereiten
|
||||||
|
3. **Monitoring**: Kontinuierliche Überwachung der Verfügbarkeit
|
||||||
|
|
||||||
|
### Wartung
|
||||||
|
1. **Regelmäßige Updates**: Tapo-Firmware aktuell halten
|
||||||
|
2. **Log-Rotation**: Große Log-Dateien vermeiden
|
||||||
|
3. **Backup**: Konfigurationen sichern
|
||||||
|
|
||||||
|
## Lizenz & Credits
|
||||||
|
|
||||||
|
Diese Implementierung basiert auf:
|
||||||
|
- **PyP100**: Python-Library für TP-Link Tapo-Geräte
|
||||||
|
- **Flask**: Web-Framework
|
||||||
|
- **MYP Platform**: 3D-Druck-Management-System
|
||||||
|
|
||||||
|
Entwickelt für die IHK-Abschlussprüfung 2025.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Autor**: MYP Development Team
|
||||||
|
**Version**: 1.0.0
|
||||||
|
**Datum**: Juni 2025
|
Binary file not shown.
9647
backend/legacy/app_original.py
Normal file
9647
backend/legacy/app_original.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,108 @@
|
|||||||
|
2025-06-09 17:47:19 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 17:47:19 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 17:47:19 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: admin/dashboard.html
|
||||||
|
2025-06-09 18:00:29 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:00:29 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:00:29 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: Could not build url for endpoint 'admin_page' with values ['tab']. Did you mean 'admin.add_user_page' instead?
|
||||||
|
2025-06-09 18:00:32 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:00:32 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:00:32 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: Could not build url for endpoint 'admin_page' with values ['tab']. Did you mean 'admin.add_user_page' instead?
|
||||||
|
2025-06-09 18:00:57 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:00:57 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:00:57 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: Could not build url for endpoint 'admin_page' with values ['tab']. Did you mean 'admin.add_user_page' instead?
|
||||||
|
2025-06-09 18:16:18 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:16:18 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:16:18 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: Could not build url for endpoint 'admin_page' with values ['tab']. Did you mean 'admin.add_user_page' instead?
|
||||||
|
2025-06-09 18:20:09 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:20:09 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:20:09 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: Could not build url for endpoint 'admin_page' with values ['tab']. Did you mean 'admin.add_user_page' instead?
|
||||||
|
2025-06-09 18:21:25 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:21:25 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:21:25 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: Could not build url for endpoint 'jobs.jobs_overview'. Did you mean 'admin.logs_overview' instead?
|
||||||
|
2025-06-09 18:21:56 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:21:56 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:21:56 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: Could not build url for endpoint 'jobs_overview'. Did you mean 'admin.logs_overview' instead?
|
||||||
|
2025-06-09 18:22:29 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:22:29 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:22:29 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: Could not build url for endpoint 'admin_guest_requests'. Did you mean 'admin.guest_requests' instead?
|
||||||
|
2025-06-09 18:24:26 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:24:26 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:26:04 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:26:04 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:27:03 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:27:03 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:27:07 - [admin] admin - [INFO] INFO - Admin-Check für Funktion printers_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:27:14 - [admin] admin - [INFO] INFO - Admin-Check für Funktion advanced_settings: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:27:17 - [admin] admin - [INFO] INFO - Admin-Check für Funktion logs_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:27:19 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:27:19 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:27:20 - [admin] admin - [INFO] INFO - Admin-Check für Funktion guest_requests: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:27:24 - [admin] admin - [INFO] INFO - Admin-Check für Funktion users_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:46:24 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:46:24 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:46:26 - [admin] admin - [INFO] INFO - Admin-Check für Funktion guest_requests: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:46:31 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:46:31 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 18:46:34 - [admin] admin - [INFO] INFO - Admin-Check für Funktion logs_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:46:40 - [admin] admin - [INFO] INFO - Admin-Check für Funktion advanced_settings: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:46:48 - [admin] admin - [INFO] INFO - Admin-Check für Funktion printers_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 18:46:51 - [admin] admin - [INFO] INFO - Admin-Check für Funktion users_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:03:16 - [admin] admin - [INFO] INFO - Admin-Check für Funktion users_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:03:16 - [admin] admin - [INFO] INFO - Benutzerübersicht geladen von admin
|
||||||
|
2025-06-09 19:03:16 - [admin] admin - [ERROR] ERROR - Fehler beim Laden der Benutzerübersicht: 'models.User object' has no attribute 'has_permission'
|
||||||
|
2025-06-09 19:03:17 - [admin] admin - [INFO] INFO - Admin-Check für Funktion users_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:03:17 - [admin] admin - [INFO] INFO - Benutzerübersicht geladen von admin
|
||||||
|
2025-06-09 19:03:17 - [admin] admin - [ERROR] ERROR - Fehler beim Laden der Benutzerübersicht: 'models.User object' has no attribute 'has_permission'
|
||||||
|
2025-06-09 19:07:44 - [admin] admin - [INFO] INFO - Admin-Check für Funktion users_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:07:44 - [admin] admin - [INFO] INFO - Benutzerübersicht geladen von admin
|
||||||
|
2025-06-09 19:07:50 - [admin] admin - [INFO] INFO - Admin-Check für Funktion printers_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:07:50 - [admin] admin - [INFO] INFO - Druckerübersicht geladen von admin
|
||||||
|
2025-06-09 19:07:55 - [admin] admin - [INFO] INFO - Admin-Check für Funktion advanced_settings: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:07:57 - [admin] admin - [INFO] INFO - Admin-Check für Funktion logs_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:07:57 - [admin] admin - [INFO] INFO - Logs-Übersicht geladen von admin
|
||||||
|
2025-06-09 19:07:58 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_logs_api: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:07:58 - [admin] admin - [INFO] INFO - Logs abgerufen: 0 Einträge, Level: all
|
||||||
|
2025-06-09 19:07:59 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_logs_api: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:07:59 - [admin] admin - [INFO] INFO - Logs abgerufen: 0 Einträge, Level: all
|
||||||
|
2025-06-09 19:08:01 - [admin] admin - [INFO] INFO - Admin-Check für Funktion guest_requests: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:14:56 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:14:56 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:15:11 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:15:11 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:20:16 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:20:17 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:20:26 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:20:26 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:20:28 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:20:28 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:20:36 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:20:36 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:21:06 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:21:06 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:21:09 - [admin] admin - [INFO] INFO - Admin-Check für Funktion printers_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:21:09 - [admin] admin - [INFO] INFO - Druckerübersicht geladen von admin
|
||||||
|
2025-06-09 19:31:09 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:31:09 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:31:09 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: 'dict object' has no attribute 'online_printers'
|
||||||
|
2025-06-09 19:31:32 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:31:32 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:31:32 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: 'dict object' has no attribute 'online_printers'
|
||||||
|
2025-06-09 19:31:46 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:31:46 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:31:46 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: 'dict object' has no attribute 'online_printers'
|
||||||
|
2025-06-09 19:31:51 - [admin] admin - [INFO] INFO - Admin-Check für Funktion logs_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:31:51 - [admin] admin - [INFO] INFO - Logs-Übersicht geladen von admin
|
||||||
|
2025-06-09 19:31:51 - [admin] admin - [ERROR] ERROR - Fehler beim Laden der Logs-Übersicht: 'dict object' has no attribute 'online_printers'
|
||||||
|
2025-06-09 19:31:52 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_logs_api: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:31:52 - [admin] admin - [INFO] INFO - Logs abgerufen: 0 Einträge, Level: all
|
||||||
|
2025-06-09 19:31:53 - [admin] admin - [INFO] INFO - Admin-Check für Funktion get_logs_api: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:31:53 - [admin] admin - [INFO] INFO - Logs abgerufen: 0 Einträge, Level: all
|
||||||
|
2025-06-09 19:31:53 - [admin] admin - [INFO] INFO - Admin-Check für Funktion advanced_settings: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:32:01 - [admin] admin - [INFO] INFO - Admin-Check für Funktion admin_dashboard: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:32:01 - [admin] admin - [INFO] INFO - Admin-Dashboard geladen von admin
|
||||||
|
2025-06-09 19:32:01 - [admin] admin - [ERROR] ERROR - Fehler beim Laden des Admin-Dashboards: 'dict object' has no attribute 'online_printers'
|
||||||
|
2025-06-09 19:32:06 - [admin] admin - [INFO] INFO - Admin-Check für Funktion printers_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:32:06 - [admin] admin - [INFO] INFO - Druckerübersicht geladen von admin
|
||||||
|
2025-06-09 19:32:12 - [admin] admin - [INFO] INFO - Admin-Check für Funktion users_overview: User authenticated: True, User ID: 1, Is Admin: True
|
||||||
|
2025-06-09 19:32:12 - [admin] admin - [INFO] INFO - Benutzerübersicht geladen von admin
|
||||||
|
2025-06-09 19:32:12 - [admin] admin - [ERROR] ERROR - Fehler beim Laden der Benutzerübersicht: 'dict object' has no attribute 'online_printers'
|
||||||
|
0
backend/logs/api_simple/api_simple.log
Normal file
0
backend/logs/api_simple/api_simple.log
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,3 +4,22 @@
|
|||||||
2025-06-05 09:33:30 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)
|
2025-06-05 09:33:30 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)
|
||||||
2025-06-05 09:33:31 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
2025-06-05 09:33:31 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||||
2025-06-05 09:33:32 - [auth] auth - [INFO] INFO - 🔐 Neue Session erstellt für Benutzer admin@mercedes-benz.com von IP 127.0.0.1
|
2025-06-05 09:33:32 - [auth] auth - [INFO] INFO - 🔐 Neue Session erstellt für Benutzer admin@mercedes-benz.com von IP 127.0.0.1
|
||||||
|
2025-06-09 17:44:24 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
|
||||||
|
2025-06-09 17:44:24 - [auth] auth - [WARNING] WARNING - Fehlgeschlagener Login-Versuch für Benutzer admin@example.com
|
||||||
|
2025-06-09 17:45:36 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
|
||||||
|
2025-06-09 17:45:36 - [auth] auth - [WARNING] WARNING - Fehlgeschlagener Login-Versuch für Benutzer admin@mercedes-benz.com
|
||||||
|
2025-06-09 17:45:43 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
|
||||||
|
2025-06-09 17:45:43 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||||
|
2025-06-09 18:00:23 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
|
||||||
|
2025-06-09 18:00:24 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||||
|
2025-06-09 18:00:24 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||||
|
2025-06-09 18:16:13 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
|
||||||
|
2025-06-09 18:16:13 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||||
|
2025-06-09 18:26:59 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
|
||||||
|
2025-06-09 18:27:00 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||||
|
2025-06-09 18:46:21 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
|
||||||
|
2025-06-09 18:46:21 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||||
|
2025-06-09 19:21:25 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich abgemeldet
|
||||||
|
2025-06-09 19:31:05 - [auth] auth - [WARNING] WARNING - JSON-Parsing fehlgeschlagen: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
|
||||||
|
2025-06-09 19:31:05 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich erfolgreich angemeldet
|
||||||
|
2025-06-09 19:32:21 - [auth] auth - [INFO] INFO - Benutzer admin@mercedes-benz.com hat sich abgemeldet
|
||||||
|
@ -1,2 +1,8 @@
|
|||||||
2025-06-04 23:36:31 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
|
2025-06-04 23:36:31 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
|
||||||
2025-06-05 11:12:52 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
|
2025-06-05 11:12:52 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
|
||||||
|
2025-06-09 17:47:13 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-08 00:00:00 bis 2025-06-15 00:00:00
|
||||||
|
2025-06-09 18:16:27 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-08 00:00:00 bis 2025-06-15 00:00:00
|
||||||
|
2025-06-09 19:18:38 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-08 00:00:00 bis 2025-06-15 00:00:00
|
||||||
|
2025-06-09 19:20:12 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-08 00:00:00 bis 2025-06-15 00:00:00
|
||||||
|
2025-06-09 19:20:12 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-08 00:00:00 bis 2025-06-15 00:00:00
|
||||||
|
2025-06-09 19:20:52 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-08 00:00:00 bis 2025-06-15 00:00:00
|
||||||
|
21
backend/logs/migration/migration.log
Normal file
21
backend/logs/migration/migration.log
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
2025-06-09 18:03:08 - [migration] migration - [INFO] INFO - Starte Migration der Benutzereinstellungen...
|
||||||
|
2025-06-09 18:03:08 - [migration] migration - [INFO] INFO - Füge Spalte theme_preference zur users-Tabelle hinzu...
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Spalte theme_preference erfolgreich hinzugefügt
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Füge Spalte language_preference zur users-Tabelle hinzu...
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Spalte language_preference erfolgreich hinzugefügt
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Füge Spalte email_notifications zur users-Tabelle hinzu...
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Spalte email_notifications erfolgreich hinzugefügt
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Füge Spalte browser_notifications zur users-Tabelle hinzu...
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Spalte browser_notifications erfolgreich hinzugefügt
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Füge Spalte dashboard_layout zur users-Tabelle hinzu...
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Spalte dashboard_layout erfolgreich hinzugefügt
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Füge Spalte compact_mode zur users-Tabelle hinzu...
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Spalte compact_mode erfolgreich hinzugefügt
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Füge Spalte show_completed_jobs zur users-Tabelle hinzu...
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Spalte show_completed_jobs erfolgreich hinzugefügt
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Füge Spalte auto_refresh_interval zur users-Tabelle hinzu...
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Spalte auto_refresh_interval erfolgreich hinzugefügt
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Füge Spalte auto_logout_timeout zur users-Tabelle hinzu...
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Spalte auto_logout_timeout erfolgreich hinzugefügt
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Migration der Benutzereinstellungen erfolgreich abgeschlossen
|
||||||
|
2025-06-09 18:03:09 - [migration] migration - [INFO] INFO - Migration erfolgreich abgeschlossen
|
0
backend/logs/performance/performance.log
Normal file
0
backend/logs/performance/performance.log
Normal file
@ -10,3 +10,44 @@
|
|||||||
2025-06-05 09:31:08 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
2025-06-05 09:31:08 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
2025-06-05 10:12:45 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
2025-06-05 10:12:45 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
2025-06-05 11:12:34 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
2025-06-05 11:12:34 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:23:17 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:25:41 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:28:04 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:31:36 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:37:51 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:40:19 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:44:12 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:47:00 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:48:56 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 17:59:59 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:02:02 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:05:20 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:12:28 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:15:35 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:17:29 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:19:09 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:20:08 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:21:25 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:21:56 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:22:28 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:24:25 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:26:04 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:26:38 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 18:46:13 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:01:46 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:03:11 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:05:11 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:05:14 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:09:19 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:10:52 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:11:04 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:11:42 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:14:33 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:15:30 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:18:14 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:19:50 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:20:23 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:20:53 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:21:30 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:26:04 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
2025-06-09 19:30:59 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||||
|
@ -165,3 +165,368 @@
|
|||||||
2025-06-05 11:13:02 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
2025-06-05 11:13:02 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
2025-06-05 11:13:02 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
2025-06-05 11:13:02 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
2025-06-05 11:13:02 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
2025-06-05 11:13:02 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:23:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:23:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 17:25:41 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:25:41 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 17:28:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:28:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 17:31:36 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:31:36 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 17:37:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:37:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 17:40:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:40:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 17:44:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:44:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 17:47:00 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:47:00 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 17:47:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:47:06 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:47:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:47:06 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:47:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:47:08 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:47:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:47:08 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:47:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:47:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:47:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:47:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:47:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:47:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:47:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:47:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:48:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:48:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:48:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 17:48:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 17:48:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:48:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 17:59:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 17:59:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:00:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:24 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:00:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:24 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:00:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:28 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:00:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:28 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:00:30 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:30 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:00:30 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:30 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:00:33 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:33 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:00:33 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:33 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:00:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:00:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:00:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:01:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:01:28 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:01:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:01:28 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:02:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:02:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:05:20 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:05:20 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:12:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:12:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:15:35 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:15:35 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:16:16 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:16:16 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:16:16 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:16:16 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:16:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:16:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:16:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:16:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:16:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:16:34 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:16:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:16:34 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:16:35 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:16:35 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:16:35 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:16:35 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:17:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:17:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:19:09 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:19:09 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:20:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:20:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:21:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:21:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:21:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:21:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:22:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:22:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:24:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:24:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:26:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:26:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:26:38 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:26:38 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:27:02 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:02 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:02 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:02 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:04 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:04 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:08 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:08 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:15 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:15 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:18 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:18 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:18 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:18 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:20 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:20 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:20 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:20 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:21 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:21 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:24 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:27:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:27:24 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 18:46:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 18:46:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:23 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:23 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:27 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:27 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:32 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:32 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:34 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:34 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:40 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:40 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:40 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:40 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:48 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:48 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:48 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:48 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:46:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:46:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:47:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:47:21 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 18:47:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 18:47:21 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:00:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:00:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:01:46 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:01:46 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:03:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:03:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:03:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:03:14 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:03:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:03:14 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:05:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:05:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:05:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:05:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:07:45 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:07:45 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:07:45 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:07:45 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:07:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:07:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:07:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:07:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:07:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:07:55 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:07:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:07:55 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:07:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:07:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:07:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:07:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:08:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:08:01 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:08:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:08:01 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:08:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:08:04 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:08:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:08:04 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:09:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:09:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:34 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:34 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:34 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:34 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:09:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:10:00 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:10:00 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:10:00 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:10:00 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:10:02 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:10:02 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:10:02 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:10:02 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:10:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:10:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:11:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:11:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:11:41 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:11:41 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:14:33 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:14:33 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:14:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:14:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:14:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:14:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:14:54 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:14:54 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:14:54 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:14:54 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:14:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:14:57 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:14:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:14:57 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:15:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:15:11 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:15:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:15:11 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:15:30 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:15:30 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:18:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:18:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:19:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:19:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:20:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:20:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:20:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:27 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:27 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:29 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:29 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:36 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:36 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:36 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:36 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:45 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:45 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:45 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:45 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:45 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:45 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:45 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:45 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:20:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:20:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:59 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:20:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:20:59 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:21:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:21:01 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:21:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:21:01 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:21:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:21:06 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:21:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:21:06 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:21:10 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:21:10 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:21:10 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:21:10 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:21:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:21:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:21:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:21:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||||
|
2025-06-09 19:21:30 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:21:30 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:26:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:26:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:30:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||||
|
2025-06-09 19:30:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||||
|
2025-06-09 19:31:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||||
|
2025-06-09 19:31:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 6 aktiven Druckern...
|
||||||
|
2025-06-09 19:31:08 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.100): UNREACHABLE (Ping fehlgeschlagen)
|
||||||
|
2025-06-09 19:31:08 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.101): UNREACHABLE (Ping fehlgeschlagen)
|
||||||
|
2025-06-09 19:31:08 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
|
||||||
|
2025-06-09 19:31:08 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
|
||||||
|
2025-06-09 19:31:08 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.106): UNREACHABLE (Ping fehlgeschlagen)
|
||||||
|
2025-06-09 19:31:08 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.102): UNREACHABLE (Ping fehlgeschlagen)
|
||||||
|
2025-06-09 19:31:08 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 6 Drucker
|
||||||
|
@ -72,3 +72,240 @@
|
|||||||
2025-06-05 11:13:02 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
2025-06-05 11:13:02 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
2025-06-05 11:13:02 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
2025-06-05 11:13:02 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
2025-06-05 11:13:02 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 25.19ms
|
2025-06-05 11:13:02 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 25.19ms
|
||||||
|
2025-06-09 17:47:06 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 17:47:06 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 17:47:06 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 24.55ms
|
||||||
|
2025-06-09 17:47:08 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 17:47:08 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 17:47:08 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.29ms
|
||||||
|
2025-06-09 17:47:19 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 17:47:19 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 17:47:19 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 3.49ms
|
||||||
|
2025-06-09 17:47:49 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 17:47:49 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 17:47:49 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 11.72ms
|
||||||
|
2025-06-09 17:48:19 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 17:48:19 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 17:48:19 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.25ms
|
||||||
|
2025-06-09 18:00:24 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:00:24 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:00:24 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.45ms
|
||||||
|
2025-06-09 18:00:28 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:00:28 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:00:28 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.88ms
|
||||||
|
2025-06-09 18:00:30 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:00:30 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:00:30 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.66ms
|
||||||
|
2025-06-09 18:00:33 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:00:33 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:00:33 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.47ms
|
||||||
|
2025-06-09 18:00:58 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:00:58 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:00:58 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 15.55ms
|
||||||
|
2025-06-09 18:01:28 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:01:28 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:01:28 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.34ms
|
||||||
|
2025-06-09 18:16:16 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:16:16 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:16:16 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 12.47ms
|
||||||
|
2025-06-09 18:16:19 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:16:19 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:16:19 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 3.84ms
|
||||||
|
2025-06-09 18:16:34 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:16:34 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:16:34 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.83ms
|
||||||
|
2025-06-09 18:16:35 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:16:35 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:16:35 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 25.36ms
|
||||||
|
2025-06-09 18:27:02 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:27:02 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:27:02 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 16.00ms
|
||||||
|
2025-06-09 18:27:04 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:27:04 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:27:04 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 8.06ms
|
||||||
|
2025-06-09 18:27:08 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:27:08 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:27:08 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 12.70ms
|
||||||
|
2025-06-09 18:27:15 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:27:15 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:27:15 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.22ms
|
||||||
|
2025-06-09 18:27:18 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:27:18 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:27:18 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 21.84ms
|
||||||
|
2025-06-09 18:27:20 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:27:20 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:27:20 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 34.79ms
|
||||||
|
2025-06-09 18:27:21 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:27:21 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:27:21 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.40ms
|
||||||
|
2025-06-09 18:27:24 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:27:24 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:27:24 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 14.96ms
|
||||||
|
2025-06-09 18:46:23 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:46:23 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:46:23 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.82ms
|
||||||
|
2025-06-09 18:46:25 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:46:25 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:46:25 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 11.69ms
|
||||||
|
2025-06-09 18:46:27 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:46:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:46:27 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 3.08ms
|
||||||
|
2025-06-09 18:46:32 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:46:32 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:46:32 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 3.02ms
|
||||||
|
2025-06-09 18:46:34 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:46:34 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:46:34 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.29ms
|
||||||
|
2025-06-09 18:46:40 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:46:40 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:46:40 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 4.37ms
|
||||||
|
2025-06-09 18:46:48 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:46:48 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:46:48 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.96ms
|
||||||
|
2025-06-09 18:46:51 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:46:51 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:46:51 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 4.87ms
|
||||||
|
2025-06-09 18:47:21 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 18:47:21 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 18:47:21 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.81ms
|
||||||
|
2025-06-09 19:03:14 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:03:14 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:03:14 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.39ms
|
||||||
|
2025-06-09 19:07:45 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:07:45 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:07:45 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 14.42ms
|
||||||
|
2025-06-09 19:07:51 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:07:51 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:07:51 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 11.15ms
|
||||||
|
2025-06-09 19:07:55 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:07:55 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:07:55 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 20.53ms
|
||||||
|
2025-06-09 19:07:58 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:07:58 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:07:58 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 6.95ms
|
||||||
|
2025-06-09 19:08:01 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:08:01 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:08:01 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.89ms
|
||||||
|
2025-06-09 19:08:04 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:08:04 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:08:04 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 16.05ms
|
||||||
|
2025-06-09 19:09:34 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:34 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:34 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 4.43ms
|
||||||
|
2025-06-09 19:09:34 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:34 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:34 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.97ms
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.81ms
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.56ms
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 3.71ms
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 3.72ms
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:56 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 3.79ms
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.56ms
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.34ms
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.91ms
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 6.40ms
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:09:58 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 12.42ms
|
||||||
|
2025-06-09 19:10:00 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:10:00 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:10:00 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.98ms
|
||||||
|
2025-06-09 19:10:02 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:10:02 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:10:02 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.85ms
|
||||||
|
2025-06-09 19:14:53 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:14:53 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:14:53 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 8.89ms
|
||||||
|
2025-06-09 19:14:54 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:14:54 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:14:54 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 22.42ms
|
||||||
|
2025-06-09 19:14:57 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:14:57 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:14:57 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 18.57ms
|
||||||
|
2025-06-09 19:15:11 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:15:11 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:15:11 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 3.96ms
|
||||||
|
2025-06-09 19:20:17 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:20:17 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:20:17 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.06ms
|
||||||
|
2025-06-09 19:20:27 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:20:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:20:27 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 38.83ms
|
||||||
|
2025-06-09 19:20:29 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:20:29 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:20:29 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 33.48ms
|
||||||
|
2025-06-09 19:20:36 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:20:36 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:20:36 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 1.90ms
|
||||||
|
2025-06-09 19:20:45 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:20:45 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:20:45 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 6.03ms
|
||||||
|
2025-06-09 19:20:45 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:20:45 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:20:45 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 19.79ms
|
||||||
|
2025-06-09 19:20:59 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:20:59 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:20:59 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 6.43ms
|
||||||
|
2025-06-09 19:21:01 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:21:01 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:21:01 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.67ms
|
||||||
|
2025-06-09 19:21:06 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:21:06 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:21:06 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 4.33ms
|
||||||
|
2025-06-09 19:21:10 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:21:10 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:21:10 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.63ms
|
||||||
|
2025-06-09 19:21:19 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:21:19 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||||
|
2025-06-09 19:21:19 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 8.99ms
|
||||||
|
2025-06-09 19:31:08 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:31:08 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:31:08 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 64.46ms
|
||||||
|
2025-06-09 19:31:10 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:31:10 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:31:10 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.55ms
|
||||||
|
2025-06-09 19:31:32 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:31:32 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:31:32 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.75ms
|
||||||
|
2025-06-09 19:31:42 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:31:42 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:31:42 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 6.24ms
|
||||||
|
2025-06-09 19:31:47 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:31:47 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:31:47 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.28ms
|
||||||
|
2025-06-09 19:31:52 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:31:52 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:31:52 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.61ms
|
||||||
|
2025-06-09 19:31:54 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:31:54 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:31:54 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 17.26ms
|
||||||
|
2025-06-09 19:31:56 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:31:56 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:31:56 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.87ms
|
||||||
|
2025-06-09 19:32:01 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:32:01 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:32:01 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 11.95ms
|
||||||
|
2025-06-09 19:32:06 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:32:06 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:32:06 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.78ms
|
||||||
|
2025-06-09 19:32:13 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||||
|
2025-06-09 19:32:13 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 6 Drucker
|
||||||
|
2025-06-09 19:32:13 - [printers] printers - [INFO] INFO - [OK] API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.53ms
|
||||||
|
@ -20,3 +20,234 @@
|
|||||||
2025-06-04 23:39:42 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
2025-06-04 23:39:42 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
2025-06-04 23:39:42 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
2025-06-04 23:39:42 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
2025-06-04 23:39:42 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
2025-06-04 23:39:42 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 17:23:18 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 17:23:18 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 17:23:18 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 17:23:18 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 17:23:18 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 17:23:18 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 17:23:43 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 17:23:43 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 17:23:43 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 17:23:43 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 17:23:43 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 17:25:41 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 17:25:41 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 17:25:41 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 17:25:41 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 17:25:41 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 17:25:41 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 17:26:10 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 17:26:10 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 17:26:10 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 17:26:10 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 17:26:10 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 17:28:04 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 17:28:04 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 17:28:04 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 17:28:04 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 17:28:04 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 17:28:04 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 17:28:45 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 17:28:45 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 17:28:45 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 17:28:45 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 17:28:45 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 17:31:36 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 17:31:36 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 17:31:36 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 17:31:36 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 17:31:36 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 17:31:36 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 17:31:54 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 17:31:54 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 17:31:54 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 17:31:54 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 17:31:54 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 17:37:51 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 17:37:51 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 17:37:51 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 17:37:51 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 17:37:51 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 17:37:51 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 17:39:00 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 17:39:00 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 17:39:00 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 17:39:00 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 17:39:00 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 17:40:20 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 17:40:20 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 17:40:20 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 17:40:20 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 17:40:20 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 17:40:20 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 17:40:44 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 17:40:44 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 17:40:44 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 17:40:44 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 17:40:44 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 17:44:13 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 17:44:13 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 17:44:13 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 17:44:13 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 17:44:13 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 17:44:13 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 17:46:11 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 17:46:11 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 17:46:11 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 17:46:11 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 17:46:11 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 17:47:00 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 17:47:00 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 17:47:00 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 17:47:00 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 17:47:00 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 17:47:00 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 17:48:31 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 17:48:31 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 17:48:31 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 17:48:31 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 17:48:31 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 17:59:59 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 17:59:59 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 17:59:59 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 17:59:59 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 17:59:59 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 17:59:59 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 18:01:29 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 18:01:29 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 18:01:29 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 18:01:29 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 18:01:29 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 18:15:36 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 18:15:36 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 18:15:36 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 18:15:36 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 18:15:36 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 18:15:36 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 18:16:42 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 18:16:42 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 18:16:42 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 18:16:42 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 18:16:42 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 18:26:38 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 18:26:38 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 18:26:38 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 18:26:38 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 18:26:38 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 18:26:38 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 18:27:31 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 18:27:31 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 18:27:31 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 18:27:31 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 18:27:31 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 18:46:13 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 18:46:13 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 18:46:13 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 18:46:13 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 18:46:13 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 18:46:13 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 18:47:22 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 18:47:22 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 18:47:22 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 18:47:22 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 18:47:22 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 19:03:12 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 19:03:12 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 19:03:12 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 19:03:12 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 19:03:12 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 19:03:12 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 19:03:41 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 19:03:41 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 19:03:41 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 19:03:41 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 19:03:41 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 19:05:14 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 19:05:14 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 19:05:14 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 19:05:14 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 19:05:14 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 19:05:14 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 19:08:11 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 19:08:11 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 19:08:11 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 19:08:11 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 19:08:11 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 19:09:19 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 19:09:19 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 19:09:19 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 19:09:19 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 19:09:19 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 19:09:19 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 19:10:12 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 19:10:12 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 19:10:12 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 19:10:12 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 19:10:12 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 19:11:05 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 19:11:05 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 19:11:05 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 19:11:05 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 19:11:05 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 19:11:05 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 19:13:24 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 19:13:24 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 19:13:24 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 19:13:24 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 19:13:24 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 19:14:34 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 19:14:34 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 19:14:34 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 19:14:34 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 19:14:34 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 19:14:34 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 19:15:27 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 19:15:27 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 19:15:27 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 19:15:27 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 19:15:27 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 19:18:15 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 19:18:15 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 19:18:15 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 19:18:15 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 19:18:15 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 19:18:15 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 19:20:21 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 19:20:21 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 19:20:21 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 19:20:21 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 19:20:21 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 19:20:24 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 19:20:24 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 19:20:24 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 19:20:24 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 19:20:24 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 19:20:24 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 19:26:02 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 19:26:02 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 19:26:02 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 19:26:02 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 19:26:02 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 19:26:05 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 19:26:05 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 19:26:05 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 19:26:05 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 19:26:05 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 19:26:05 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 19:27:07 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 19:27:07 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 19:27:07 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 19:27:07 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 19:27:07 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
2025-06-09 19:30:59 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||||
|
2025-06-09 19:30:59 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||||
|
2025-06-09 19:30:59 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||||
|
2025-06-09 19:30:59 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||||
|
2025-06-09 19:30:59 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||||
|
2025-06-09 19:30:59 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||||
|
2025-06-09 19:32:29 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||||
|
2025-06-09 19:32:29 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||||
|
2025-06-09 19:32:29 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||||
|
2025-06-09 19:32:29 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||||
|
2025-06-09 19:32:29 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||||
|
@ -25,3 +25,90 @@
|
|||||||
2025-06-05 11:12:32 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
2025-06-05 11:12:32 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
2025-06-05 11:12:38 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
2025-06-05 11:12:38 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
2025-06-05 11:12:38 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
2025-06-05 11:12:38 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 17:23:17 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:23:18 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 17:23:18 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 17:25:41 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:25:41 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 17:25:41 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 17:28:04 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:28:04 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 17:28:04 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 17:31:36 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:31:36 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 17:31:36 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 17:37:51 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:37:51 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 17:37:51 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 17:40:19 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:40:20 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 17:40:20 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 17:44:12 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:44:13 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 17:44:13 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 17:47:00 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:47:00 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 17:47:00 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 17:48:56 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:59:59 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 17:59:59 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 17:59:59 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 18:02:01 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:05:20 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:08:27 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:09:00 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:09:49 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:12:28 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:15:35 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:15:36 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 18:15:36 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 18:17:29 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:19:09 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:20:08 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:21:25 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:21:55 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:22:28 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:24:25 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:26:04 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:26:38 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:26:38 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 18:26:38 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 18:46:12 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 18:46:13 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 18:46:13 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 19:00:53 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:01:46 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:03:11 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:03:12 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 19:03:12 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 19:05:11 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:05:14 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:05:14 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 19:05:14 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 19:09:19 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:09:19 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 19:09:19 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 19:10:52 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:11:04 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:11:05 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 19:11:05 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 19:11:41 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:14:33 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:14:34 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 19:14:34 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 19:15:30 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:18:14 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:18:15 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 19:18:15 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 19:19:50 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:20:23 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:20:24 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 19:20:24 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 19:20:53 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:21:30 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:26:04 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:26:05 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 19:26:05 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
2025-06-09 19:30:59 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||||
|
2025-06-09 19:30:59 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||||
|
2025-06-09 19:30:59 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||||
|
@ -10,3 +10,44 @@
|
|||||||
2025-06-05 09:31:08 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
2025-06-05 09:31:08 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
2025-06-05 10:12:45 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
2025-06-05 10:12:45 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
2025-06-05 11:12:34 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
2025-06-05 11:12:34 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:23:17 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:25:41 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:28:04 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:31:36 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:37:51 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:40:19 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:44:12 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:47:00 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:48:56 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 17:59:59 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:02:02 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:05:20 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:12:28 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:15:35 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:17:29 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:19:09 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:20:08 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:21:25 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:21:56 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:22:28 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:24:25 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:26:04 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:26:38 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 18:46:13 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:01:46 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:03:11 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:05:11 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:05:14 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:09:19 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:10:52 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:11:04 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:11:42 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:14:33 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:15:30 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:18:14 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:19:50 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:20:23 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:20:53 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:21:30 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:26:04 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
2025-06-09 19:30:59 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||||
|
@ -106,3 +106,290 @@
|
|||||||
2025-06-05 11:12:34 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
2025-06-05 11:12:34 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||||
2025-06-05 11:12:34 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
2025-06-05 11:12:34 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||||
2025-06-05 11:12:34 - [startup] startup - [INFO] INFO - ==================================================
|
2025-06-05 11:12:34 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:23:17 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:23:17 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:23:17 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:23:17 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:23:17 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:23:17 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:23:17.666889
|
||||||
|
2025-06-09 17:23:17 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:25:41 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:25:41 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:25:41 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:25:41 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:25:41 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:25:41 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:25:41.300258
|
||||||
|
2025-06-09 17:25:41 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:28:04 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:28:04 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:28:04 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:28:04 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:28:04 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:28:04 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:28:04.381492
|
||||||
|
2025-06-09 17:28:04 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:31:36 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:31:36 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:31:36 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:31:36 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:31:36 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:31:36 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:31:36.404129
|
||||||
|
2025-06-09 17:31:36 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:37:51 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:37:51 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:37:51 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:37:51 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:37:51 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:37:51 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:37:51.120191
|
||||||
|
2025-06-09 17:37:51 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:40:19 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:40:19 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:40:19 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:40:19 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:40:19 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:40:19 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:40:19.778544
|
||||||
|
2025-06-09 17:40:19 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:44:12 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:44:12 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:44:12 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:44:12 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:44:12 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:44:12 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:44:12.875425
|
||||||
|
2025-06-09 17:44:12 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:47:00 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:47:00 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:47:00 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:47:00 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:47:00 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:47:00 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:47:00.356358
|
||||||
|
2025-06-09 17:47:00 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:48:56 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:48:56 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:48:56 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:48:56 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:48:56 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:48:56 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:48:56.372745
|
||||||
|
2025-06-09 17:48:56 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:59:59 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 17:59:59 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 17:59:59 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 17:59:59 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 17:59:59 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 17:59:59 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T17:59:59.208043
|
||||||
|
2025-06-09 17:59:59 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:02:01 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:02:01 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:02:01 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:02:01 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:02:01 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:02:01 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:02:01.894426
|
||||||
|
2025-06-09 18:02:01 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:05:20 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:05:20 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:05:20 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:05:20 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:05:20 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:05:20 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:05:20.368424
|
||||||
|
2025-06-09 18:05:20 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:12:28 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:12:28 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:12:28 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:12:28 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:12:28 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:12:28 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:12:28.485108
|
||||||
|
2025-06-09 18:12:28 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:15:35 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:15:35 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:15:35 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:15:35 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:15:35 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:15:35 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:15:35.719706
|
||||||
|
2025-06-09 18:15:35 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:17:29 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:17:29 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:17:29 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:17:29 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:17:29 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:17:29 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:17:29.522538
|
||||||
|
2025-06-09 18:17:29 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:19:09 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:19:09 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:19:09 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:19:09 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:19:09 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:19:09 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:19:09.669207
|
||||||
|
2025-06-09 18:19:09 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:20:08 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:20:08 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:20:08 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:20:08 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:20:08 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:20:08 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:20:08.265492
|
||||||
|
2025-06-09 18:20:08 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:21:25 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:21:25 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:21:25 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:21:25 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:21:25 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:21:25 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:21:25.055315
|
||||||
|
2025-06-09 18:21:25 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:21:56 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:21:56 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:21:56 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:21:56 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:21:56 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:21:56 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:21:56.004088
|
||||||
|
2025-06-09 18:21:56 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:22:28 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:22:28 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:22:28 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:22:28 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:22:28 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:22:28 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:22:28.739172
|
||||||
|
2025-06-09 18:22:28 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:24:25 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:24:25 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:24:25 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:24:25 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:24:25 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:24:25 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:24:25.472029
|
||||||
|
2025-06-09 18:24:25 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:26:04 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:26:04 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:26:04 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:26:04 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:26:04 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:26:04 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:26:04.255865
|
||||||
|
2025-06-09 18:26:04 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:26:38 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:26:38 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:26:38 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:26:38 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:26:38 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:26:38 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:26:38.410691
|
||||||
|
2025-06-09 18:26:38 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:46:13 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 18:46:13 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 18:46:13 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 18:46:13 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 18:46:13 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 18:46:13 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T18:46:13.012834
|
||||||
|
2025-06-09 18:46:13 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:01:46 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:01:46 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:01:46 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:01:46 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:01:46 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:01:46 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:01:46.136121
|
||||||
|
2025-06-09 19:01:46 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:03:11 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:03:11 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:03:11 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:03:11 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:03:11 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:03:11 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:03:11.863537
|
||||||
|
2025-06-09 19:03:11 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:05:11 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:05:11 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:05:11 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:05:11 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:05:11 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:05:11 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:05:11.777891
|
||||||
|
2025-06-09 19:05:11 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:05:14 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:05:14 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:05:14 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:05:14 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:05:14 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:05:14 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:05:14.065640
|
||||||
|
2025-06-09 19:05:14 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:09:19 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:09:19 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:09:19 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:09:19 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:09:19 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:09:19 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:09:19.476799
|
||||||
|
2025-06-09 19:09:19 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:10:52 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:10:52 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:10:52 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:10:52 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:10:52 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:10:52 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:10:52.780015
|
||||||
|
2025-06-09 19:10:52 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:11:04 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:11:04 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:11:04 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:11:04 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:11:04 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:11:04 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:11:04.885939
|
||||||
|
2025-06-09 19:11:04 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:11:42 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:11:42 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:11:42 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:11:42 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:11:42 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:11:42 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:11:42.015691
|
||||||
|
2025-06-09 19:11:42 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:14:33 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:14:33 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:14:33 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:14:33 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:14:33 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:14:33 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:14:33.857417
|
||||||
|
2025-06-09 19:14:33 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:15:30 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:15:30 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:15:30 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:15:30 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:15:30 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:15:30 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:15:30.249963
|
||||||
|
2025-06-09 19:15:30 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:18:14 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:18:14 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:18:14 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:18:14 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:18:14 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:18:14 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:18:14.791089
|
||||||
|
2025-06-09 19:18:14 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:19:50 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:19:50 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:19:50 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:19:50 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:19:50 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:19:50 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:19:50.620469
|
||||||
|
2025-06-09 19:19:50 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:20:23 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:20:23 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:20:23 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:20:23 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:20:23 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:20:23 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:20:23.817368
|
||||||
|
2025-06-09 19:20:23 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:20:53 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:20:53 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:20:53 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:20:53 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:20:53 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:20:53 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:20:53.389651
|
||||||
|
2025-06-09 19:20:53 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:21:30 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:21:30 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:21:30 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:21:30 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:21:30 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:21:30 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:21:30.465024
|
||||||
|
2025-06-09 19:21:30 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:26:04 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:26:04 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:26:04 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:26:04 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:26:04 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:26:04 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:26:04.814457
|
||||||
|
2025-06-09 19:26:04 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:30:59 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
2025-06-09 19:30:59 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet...
|
||||||
|
2025-06-09 19:30:59 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.11.2 (main, Mar 05 2023, 19:08:04) [GCC]
|
||||||
|
2025-06-09 19:30:59 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: posix (linux)
|
||||||
|
2025-06-09 19:30:59 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: /cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend
|
||||||
|
2025-06-09 19:30:59 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-09T19:30:59.553304
|
||||||
|
2025-06-09 19:30:59 - [startup] startup - [INFO] INFO - ==================================================
|
||||||
|
17
backend/logs/tapo_control/tapo_control.log
Normal file
17
backend/logs/tapo_control/tapo_control.log
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
2025-06-09 19:10:03 - [tapo_control] tapo_control - [ERROR] ERROR - Fehler beim Laden des Tapo-Dashboards: Could not build url for endpoint 'admin.manage_printers'. Did you mean 'admin.get_printer_api' instead?
|
||||||
|
2025-06-09 19:10:05 - [tapo_control] tapo_control - [ERROR] ERROR - Fehler beim Laden des Tapo-Dashboards: Could not build url for endpoint 'admin.manage_printers'. Did you mean 'admin.get_printer_api' instead?
|
||||||
|
2025-06-09 19:11:07 - [tapo_control] tapo_control - [ERROR] ERROR - Fehler beim Laden des Tapo-Dashboards: Could not build url for endpoint 'admin.manage_printers'. Did you mean 'admin.get_printer_api' instead?
|
||||||
|
2025-06-09 19:13:21 - [tapo_control] tapo_control - [ERROR] ERROR - Fehler beim Laden des Tapo-Dashboards: Could not build url for endpoint 'admin.manage_printers'. Did you mean 'admin.get_printer_api' instead?
|
||||||
|
2025-06-09 19:14:48 - [tapo_control] tapo_control - [ERROR] ERROR - Fehler beim Laden des Tapo-Dashboards: Could not build url for endpoint 'admin.manage_printers'. Did you mean 'admin.get_printer_api' instead?
|
||||||
|
2025-06-09 19:14:52 - [tapo_control] tapo_control - [ERROR] ERROR - Fehler beim Laden des Tapo-Dashboards: Could not build url for endpoint 'admin.manage_printers'. Did you mean 'admin.get_printer_api' instead?
|
||||||
|
2025-06-09 19:18:29 - [tapo_control] tapo_control - [INFO] INFO - Tapo Dashboard aufgerufen von Benutzer: Administrator
|
||||||
|
2025-06-09 19:20:33 - [tapo_control] tapo_control - [INFO] INFO - Tapo Dashboard aufgerufen von Benutzer: Administrator
|
||||||
|
2025-06-09 19:20:57 - [tapo_control] tapo_control - [INFO] INFO - Tapo Dashboard aufgerufen von Benutzer: Administrator
|
||||||
|
2025-06-09 19:31:12 - [tapo_control] tapo_control - [INFO] INFO - Tapo Dashboard aufgerufen von Benutzer: Administrator
|
||||||
|
2025-06-09 19:31:14 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Tapo-Steckdose 192.168.0.100 nicht erreichbar
|
||||||
|
2025-06-09 19:31:17 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Tapo-Steckdose 192.168.0.101 nicht erreichbar
|
||||||
|
2025-06-09 19:31:19 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Tapo-Steckdose 192.168.0.102 nicht erreichbar
|
||||||
|
2025-06-09 19:31:21 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Tapo-Steckdose 192.168.0.103 nicht erreichbar
|
||||||
|
2025-06-09 19:31:23 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Tapo-Steckdose 192.168.0.104 nicht erreichbar
|
||||||
|
2025-06-09 19:31:25 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Tapo-Steckdose 192.168.0.106 nicht erreichbar
|
||||||
|
2025-06-09 19:31:25 - [tapo_control] tapo_control - [INFO] INFO - Dashboard geladen: 6 Steckdosen, 0 online
|
@ -10,3 +10,266 @@
|
|||||||
2025-06-05 11:12:58 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
2025-06-05 11:12:58 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
2025-06-05 11:13:04 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
2025-06-05 11:13:04 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
2025-06-05 11:13:10 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 36.7s
|
2025-06-05 11:13:10 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 36.7s
|
||||||
|
2025-06-09 17:23:17 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 17:23:19 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 17:23:19 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 17:23:19 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 17:23:19 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 17:23:19 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 17:23:19 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 17:23:19 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 17:23:19 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 17:23:19 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 17:25:41 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 17:25:43 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 17:25:43 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 17:25:43 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 17:25:43 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 17:25:43 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 17:25:43 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 17:25:43 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 17:25:43 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 17:25:43 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 17:28:04 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 17:28:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 17:28:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 17:28:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 17:28:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 17:28:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 17:28:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 17:28:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 17:28:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 17:28:06 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 17:31:36 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 17:31:38 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 17:31:38 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 17:31:38 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 17:31:38 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 17:31:38 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 17:31:38 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 17:31:38 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 17:31:38 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 17:31:38 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 17:37:51 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 17:37:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 17:37:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 17:37:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 17:37:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 17:37:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 17:37:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 17:37:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 17:37:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 17:37:53 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 17:40:19 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 17:40:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 17:40:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 17:40:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 17:40:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 17:40:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 17:40:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 17:40:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 17:40:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 17:40:21 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 17:44:12 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 17:44:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 17:44:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 17:44:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 17:44:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 17:44:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 17:44:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 17:44:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 17:44:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 17:44:14 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 17:47:00 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 17:47:02 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 17:47:02 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 17:47:02 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 17:47:02 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 17:47:02 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 17:47:02 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 17:47:02 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 17:47:02 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 17:47:02 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 17:48:56 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 17:59:59 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:00:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 18:00:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 18:00:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 18:00:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 18:00:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 18:00:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 18:00:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 18:00:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 18:00:01 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 18:02:01 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:05:20 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:08:27 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:09:00 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:09:49 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:12:28 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:15:35 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:15:37 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 18:15:37 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 18:15:37 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 18:15:37 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 18:15:37 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 18:15:37 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 18:15:37 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 18:15:37 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 18:15:37 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 18:17:29 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:19:09 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:20:08 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:21:25 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:21:55 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:22:28 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:24:25 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:26:04 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:26:38 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:26:40 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 18:26:40 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 18:26:40 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 18:26:40 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 18:26:40 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 18:26:40 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 18:26:40 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 18:26:40 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 18:26:40 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 18:46:12 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 18:46:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 18:46:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 18:46:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 18:46:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 18:46:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 18:46:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 18:46:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 18:46:14 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 18:46:14 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:00:45 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:00:51 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:00:53 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:01:40 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:01:46 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:03:11 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:03:13 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:03:13 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:03:13 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:03:13 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:03:13 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:03:13 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:03:13 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:03:13 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:03:13 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:04:30 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:05:11 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:05:14 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:05:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:05:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:05:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:05:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:05:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:05:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:05:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:05:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:05:16 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:05:48 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:09:19 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:09:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:09:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:09:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:09:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:09:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:09:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:09:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:09:21 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:09:21 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:10:28 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:10:40 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:10:46 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:10:52 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:11:04 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:11:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:11:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:11:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:11:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:11:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:11:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:11:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:11:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:11:06 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:11:41 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:14:33 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:14:35 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:14:35 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:14:35 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:14:35 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:14:35 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:14:35 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:14:35 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:14:35 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:14:35 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:15:30 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:18:14 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:18:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:18:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:18:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:18:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:18:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:18:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:18:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:18:16 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:18:16 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:19:50 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:20:23 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:20:25 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:20:25 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:20:25 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:20:25 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:20:25 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:20:25 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:20:25 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:20:25 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:20:25 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:20:53 - [tapo_controller] tapo_controller - [INFO] INFO - ℹ️ keine drucker mit tapo-steckdosen konfiguriert
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:21:30 - [tapo_controller] tapo_controller - [INFO] INFO - ℹ️ keine drucker mit tapo-steckdosen konfiguriert
|
||||||
|
2025-06-09 19:26:04 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:26:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:26:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:26:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:26:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:26:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:26:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:26:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:26:06 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:26:06 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:30:59 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
2025-06-09 19:31:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 starte automatische tapo-steckdosenerkennung...
|
||||||
|
2025-06-09 19:31:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔄 teste 6 standard-ips aus der konfiguration
|
||||||
|
2025-06-09 19:31:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 1/6: 192.168.0.103
|
||||||
|
2025-06-09 19:31:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 2/6: 192.168.0.104
|
||||||
|
2025-06-09 19:31:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 3/6: 192.168.0.100
|
||||||
|
2025-06-09 19:31:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 4/6: 192.168.0.101
|
||||||
|
2025-06-09 19:31:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 5/6: 192.168.0.102
|
||||||
|
2025-06-09 19:31:01 - [tapo_controller] tapo_controller - [INFO] INFO - 🔍 teste ip 6/6: 192.168.0.105
|
||||||
|
2025-06-09 19:31:01 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ steckdosen-erkennung abgeschlossen: 0/6 steckdosen gefunden in 0.0s
|
||||||
|
2025-06-09 19:31:17 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert
|
||||||
|
67
backend/logs/tapo_setup/tapo_setup.log
Normal file
67
backend/logs/tapo_setup/tapo_setup.log
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
2025-06-09 19:29:27 - [tapo_setup] tapo_setup - [INFO] INFO - 🔧 Starte Tapo-Steckdosen Setup...
|
||||||
|
2025-06-09 19:29:27 - [tapo_setup] tapo_setup - [ERROR] ERROR - ❌ Fehler beim Setup: 'octoprint_enabled' is an invalid keyword argument for Printer
|
||||||
|
2025-06-09 19:29:57 - [tapo_setup] tapo_setup - [INFO] INFO - 🔧 Starte Tapo-Steckdosen Setup...
|
||||||
|
2025-06-09 19:29:57 - [tapo_setup] tapo_setup - [ERROR] ERROR - ❌ Fehler beim Setup: Unknown format code 'd' for object of type 'str'
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - 🔧 Starte Tapo-Steckdosen Setup...
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ➕ Tapo-Steckdose 192.168.0.100 hinzugefügt: Tapo P110 (192.168.0.100)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ➕ Tapo-Steckdose 192.168.0.101 hinzugefügt: Tapo P110 (192.168.0.101)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ➕ Tapo-Steckdose 192.168.0.102 hinzugefügt: Tapo P110 (192.168.0.102)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ➕ Tapo-Steckdose 192.168.0.103 hinzugefügt: Tapo P110 (192.168.0.103)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ➕ Tapo-Steckdose 192.168.0.104 hinzugefügt: Tapo P110 (192.168.0.104)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ➕ Tapo-Steckdose 192.168.0.106 hinzugefügt: Tapo P110 (192.168.0.106)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - 🎉 Setup abgeschlossen: 6 Tapo-Steckdosen konfiguriert
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO -
|
||||||
|
📊 Tapo-Steckdosen Übersicht (6 konfiguriert):
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ================================================================================
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.100 - Tapo P110 (192.168.0.100)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.101 - Tapo P110 (192.168.0.101)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.102 - Tapo P110 (192.168.0.102)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.103 - Tapo P110 (192.168.0.103)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.104 - Tapo P110 (192.168.0.104)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.106 - Tapo P110 (192.168.0.106)
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:13 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - 📊 Zeige Tapo-Status...
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO -
|
||||||
|
📊 Tapo-Steckdosen Übersicht (6 konfiguriert):
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - ================================================================================
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.100 - Tapo P110 (192.168.0.100)
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.101 - Tapo P110 (192.168.0.101)
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.102 - Tapo P110 (192.168.0.102)
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.103 - Tapo P110 (192.168.0.103)
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.104 - Tapo P110 (192.168.0.104)
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - 📍 192.168.0.106 - Tapo P110 (192.168.0.106)
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Standort: Werk 040 - Berlin - TBA
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - Aktiv: ✅
|
||||||
|
2025-06-09 19:30:19 - [tapo_setup] tapo_setup - [INFO] INFO - ------------------------------------------------------------
|
@ -0,0 +1,94 @@
|
|||||||
|
2025-06-09 18:00:24 - [user] user - [ERROR] ERROR - Error handling user settings API: '_GeneratorContextManager' object has no attribute 'query'
|
||||||
|
2025-06-09 18:00:28 - [user] user - [ERROR] ERROR - Error handling user settings API: '_GeneratorContextManager' object has no attribute 'query'
|
||||||
|
2025-06-09 18:00:30 - [user] user - [ERROR] ERROR - Error handling user settings API: '_GeneratorContextManager' object has no attribute 'query'
|
||||||
|
2025-06-09 18:00:33 - [user] user - [ERROR] ERROR - Error handling user settings API: '_GeneratorContextManager' object has no attribute 'query'
|
||||||
|
2025-06-09 18:00:36 - [user] user - [ERROR] ERROR - Error handling user settings API: '_GeneratorContextManager' object has no attribute 'query'
|
||||||
|
2025-06-09 18:00:58 - [user] user - [ERROR] ERROR - Error handling user settings API: '_GeneratorContextManager' object has no attribute 'query'
|
||||||
|
2025-06-09 18:16:16 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:16:19 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:16:23 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:16:24 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:16:27 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:16:31 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:16:33 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:16:34 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:16:35 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:27:02 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:27:04 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:27:08 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:27:12 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:27:15 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:27:18 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:27:20 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:27:21 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:27:24 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:46:23 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:46:25 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:46:27 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:46:32 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:46:34 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:46:40 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:46:44 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:46:48 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 18:46:51 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:07:45 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:07:51 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:07:52 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:07:55 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:07:58 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:08:01 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:08:04 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:10:00 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:10:02 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:10:03 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:10:04 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:10:05 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:11:08 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:13:21 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:14:48 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:14:51 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:14:52 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:14:53 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:14:54 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:14:56 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:14:57 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:15:02 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:15:05 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:15:11 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:15:20 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:18:30 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:18:38 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:13 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:17 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:27 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:29 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:33 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:36 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:39 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:43 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:45 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:45 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:53 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:55 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:56 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:57 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:20:59 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:21:01 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:21:06 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:21:10 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:21:12 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:21:19 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:08 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:10 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:26 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:32 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:38 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:42 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:47 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:52 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:54 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:31:56 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:32:01 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:32:03 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:32:06 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
2025-06-09 19:32:13 - [user] user - [INFO] INFO - User admin retrieved settings via API
|
||||||
|
@ -344,6 +344,17 @@ class User(UserMixin, Base):
|
|||||||
phone = Column(String(50), nullable=True) # Telefonnummer
|
phone = Column(String(50), nullable=True) # Telefonnummer
|
||||||
bio = Column(Text, nullable=True) # Kurze Beschreibung/Bio
|
bio = Column(Text, nullable=True) # Kurze Beschreibung/Bio
|
||||||
|
|
||||||
|
# Benutzereinstellungen
|
||||||
|
theme_preference = Column(String(20), default="auto") # auto, light, dark
|
||||||
|
language_preference = Column(String(10), default="de") # de, en, etc.
|
||||||
|
email_notifications = Column(Boolean, default=True)
|
||||||
|
browser_notifications = Column(Boolean, default=True)
|
||||||
|
dashboard_layout = Column(String(20), default="default") # default, compact, detailed
|
||||||
|
compact_mode = Column(Boolean, default=False)
|
||||||
|
show_completed_jobs = Column(Boolean, default=True)
|
||||||
|
auto_refresh_interval = Column(Integer, default=30) # Sekunden
|
||||||
|
auto_logout_timeout = Column(Integer, default=0) # Minuten, 0 = deaktiviert
|
||||||
|
|
||||||
jobs = relationship("Job", back_populates="user", foreign_keys="Job.user_id", cascade="all, delete-orphan")
|
jobs = relationship("Job", back_populates="user", foreign_keys="Job.user_id", cascade="all, delete-orphan")
|
||||||
owned_jobs = relationship("Job", foreign_keys="Job.owner_id", overlaps="owner")
|
owned_jobs = relationship("Job", foreign_keys="Job.owner_id", overlaps="owner")
|
||||||
permissions = relationship("UserPermission", back_populates="user", uselist=False, cascade="all, delete-orphan")
|
permissions = relationship("UserPermission", back_populates="user", uselist=False, cascade="all, delete-orphan")
|
||||||
@ -450,9 +461,65 @@ class User(UserMixin, Base):
|
|||||||
Aktualisiert den letzten Login-Zeitstempel.
|
Aktualisiert den letzten Login-Zeitstempel.
|
||||||
"""
|
"""
|
||||||
self.last_login = datetime.now()
|
self.last_login = datetime.now()
|
||||||
# Cache invalidieren
|
|
||||||
invalidate_model_cache("User", self.id)
|
invalidate_model_cache("User", self.id)
|
||||||
|
|
||||||
|
def has_permission(self, permission_name: str) -> bool:
|
||||||
|
"""
|
||||||
|
Überprüft, ob der Benutzer eine bestimmte Berechtigung hat.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
permission_name: Name der Berechtigung (z.B. 'CONTROL_PRINTER', 'START_JOBS', 'APPROVE_JOBS')
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True wenn Berechtigung vorhanden, sonst False
|
||||||
|
"""
|
||||||
|
# Administratoren haben alle Berechtigungen
|
||||||
|
if self.is_admin:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Inaktive Benutzer haben keine Berechtigungen
|
||||||
|
if not self.is_active:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Spezifische Berechtigungen
|
||||||
|
if permission_name == 'ADMIN':
|
||||||
|
return self.is_admin
|
||||||
|
|
||||||
|
# Überprüfe spezifische Berechtigungen über UserPermission
|
||||||
|
if self.permissions:
|
||||||
|
if permission_name == 'CONTROL_PRINTER':
|
||||||
|
return self.permissions.can_start_jobs and not self.permissions.needs_approval
|
||||||
|
elif permission_name == 'START_JOBS':
|
||||||
|
return self.permissions.can_start_jobs
|
||||||
|
elif permission_name == 'APPROVE_JOBS':
|
||||||
|
return self.permissions.can_approve_jobs
|
||||||
|
elif permission_name == 'NEEDS_APPROVAL':
|
||||||
|
return self.permissions.needs_approval
|
||||||
|
|
||||||
|
# Fallback für unbekannte Berechtigungen - nur Administratoren erlaubt
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_permission_level(self) -> str:
|
||||||
|
"""
|
||||||
|
Gibt das Berechtigungslevel des Benutzers zurück.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: 'admin', 'advanced', 'standard', 'restricted'
|
||||||
|
"""
|
||||||
|
if self.is_admin:
|
||||||
|
return 'admin'
|
||||||
|
|
||||||
|
if not self.is_active:
|
||||||
|
return 'restricted'
|
||||||
|
|
||||||
|
if self.permissions:
|
||||||
|
if self.permissions.can_approve_jobs:
|
||||||
|
return 'advanced'
|
||||||
|
elif self.permissions.can_start_jobs and not self.permissions.needs_approval:
|
||||||
|
return 'standard'
|
||||||
|
|
||||||
|
return 'restricted'
|
||||||
|
|
||||||
|
|
||||||
class Printer(Base):
|
class Printer(Base):
|
||||||
__tablename__ = "printers"
|
__tablename__ = "printers"
|
||||||
|
79
backend/quick_admin_test.py
Normal file
79
backend/quick_admin_test.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3.11
|
||||||
|
"""
|
||||||
|
Schneller Test für das Admin-Dashboard ohne Server
|
||||||
|
"""
|
||||||
|
|
||||||
|
from app import app
|
||||||
|
from models import User, get_cached_session
|
||||||
|
from flask_login import login_user
|
||||||
|
|
||||||
|
def test_admin_dashboard_direct():
|
||||||
|
"""Testet das Admin-Dashboard direkt"""
|
||||||
|
|
||||||
|
print("=== DIREKTER ADMIN DASHBOARD TEST ===")
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
try:
|
||||||
|
# Admin-Benutzer finden
|
||||||
|
with get_cached_session() as session:
|
||||||
|
admin_user = session.query(User).filter(User.role == 'admin').first()
|
||||||
|
|
||||||
|
if not admin_user:
|
||||||
|
print("❌ Kein Admin-Benutzer gefunden!")
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"✅ Admin-Benutzer gefunden: {admin_user.username}")
|
||||||
|
|
||||||
|
# Test mit simuliertem Login
|
||||||
|
with app.test_client() as client:
|
||||||
|
with client.session_transaction() as sess:
|
||||||
|
sess['_user_id'] = str(admin_user.id)
|
||||||
|
sess['_fresh'] = True
|
||||||
|
|
||||||
|
# Admin-Dashboard aufrufen
|
||||||
|
response = client.get('/admin/')
|
||||||
|
print(f"Status: {response.status_code}")
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
print("✅ SUCCESS: Admin-Dashboard lädt erfolgreich!")
|
||||||
|
print(f"Content-Length: {len(response.get_data())} Bytes")
|
||||||
|
|
||||||
|
# Prüfe, ob wichtige Inhalte vorhanden sind
|
||||||
|
content = response.get_data(as_text=True)
|
||||||
|
if "Admin-Dashboard" in content:
|
||||||
|
print("✅ Dashboard-Titel gefunden")
|
||||||
|
if "Benutzerverwaltung" in content:
|
||||||
|
print("✅ Benutzer-Tab gefunden")
|
||||||
|
if "Drucker-Steckdosen" in content:
|
||||||
|
print("✅ Drucker-Tab gefunden")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
elif response.status_code == 302:
|
||||||
|
print(f"❌ Redirect zu: {response.headers.get('Location', 'Unknown')}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif response.status_code == 500:
|
||||||
|
print("❌ 500 Internal Server Error")
|
||||||
|
error_data = response.get_data(as_text=True)
|
||||||
|
print(f"Error: {error_data[:500]}...")
|
||||||
|
return False
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f"❌ Unerwarteter Status: {response.status_code}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ FEHLER: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
success = test_admin_dashboard_direct()
|
||||||
|
if success:
|
||||||
|
print("\n🎉 ADMIN-DASHBOARD FUNKTIONIERT!")
|
||||||
|
else:
|
||||||
|
print("\n❌ ADMIN-DASHBOARD HAT PROBLEME!")
|
||||||
|
|
||||||
|
exit(0 if success else 1)
|
151
backend/setup_tapo_outlets.py
Normal file
151
backend/setup_tapo_outlets.py
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#!/usr/bin/env python3.11
|
||||||
|
"""
|
||||||
|
Script zum Einrichten der Tapo-Steckdosen in der Datenbank
|
||||||
|
Hardkodierte IPs: 192.168.0.100 - 192.168.0.106 (außer 105)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Pfad zum Backend-Verzeichnis hinzufügen
|
||||||
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
from models import get_db_session, Printer
|
||||||
|
from utils.logging_config import get_logger
|
||||||
|
|
||||||
|
logger = get_logger("tapo_setup")
|
||||||
|
|
||||||
|
def setup_tapo_outlets():
|
||||||
|
"""Richtet die hardkodierten Tapo-Steckdosen-IPs in der Datenbank ein."""
|
||||||
|
|
||||||
|
# Hardkodierte IP-Adressen (192.168.0.100 - 192.168.0.106, außer 105)
|
||||||
|
tapo_ips = [
|
||||||
|
"192.168.0.100",
|
||||||
|
"192.168.0.101",
|
||||||
|
"192.168.0.102",
|
||||||
|
"192.168.0.103",
|
||||||
|
"192.168.0.104",
|
||||||
|
"192.168.0.106" # 105 ist ausgenommen
|
||||||
|
]
|
||||||
|
|
||||||
|
db_session = get_db_session()
|
||||||
|
|
||||||
|
try:
|
||||||
|
for i, ip in enumerate(tapo_ips, start=1):
|
||||||
|
# Prüfen ob bereits vorhanden
|
||||||
|
existing_printer = db_session.query(Printer).filter(
|
||||||
|
Printer.plug_ip == ip
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if existing_printer:
|
||||||
|
logger.info(f"✅ Tapo-Steckdose {ip} bereits vorhanden (Drucker: {existing_printer.name})")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Neuen Drucker-Eintrag erstellen
|
||||||
|
printer_name = f"Tapo P110 ({ip})"
|
||||||
|
location = f"Werk 040 - Berlin - TBA"
|
||||||
|
|
||||||
|
new_printer = Printer(
|
||||||
|
name=printer_name,
|
||||||
|
model="P115", # Tapo P110/P115 Modell
|
||||||
|
location=location,
|
||||||
|
ip_address=ip,
|
||||||
|
mac_address=f"00:00:00:00:{int(ip.split('.')[-1]):02d}:00", # Dummy MAC
|
||||||
|
plug_ip=ip, # Wichtig: plug_ip für Tapo-Steuerung
|
||||||
|
plug_username="tapo_user", # Standard Tapo-Benutzername
|
||||||
|
plug_password="tapo_pass", # Standard Tapo-Passwort
|
||||||
|
active=True
|
||||||
|
)
|
||||||
|
|
||||||
|
db_session.add(new_printer)
|
||||||
|
logger.info(f"➕ Tapo-Steckdose {ip} hinzugefügt: {printer_name}")
|
||||||
|
|
||||||
|
# Änderungen speichern
|
||||||
|
db_session.commit()
|
||||||
|
logger.info(f"🎉 Setup abgeschlossen: {len(tapo_ips)} Tapo-Steckdosen konfiguriert")
|
||||||
|
|
||||||
|
# Status anzeigen
|
||||||
|
show_tapo_status(db_session)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db_session.rollback()
|
||||||
|
logger.error(f"❌ Fehler beim Setup: {e}")
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
db_session.close()
|
||||||
|
|
||||||
|
def show_tapo_status(db_session):
|
||||||
|
"""Zeigt den aktuellen Status aller Tapo-Steckdosen an."""
|
||||||
|
|
||||||
|
tapo_printers = db_session.query(Printer).filter(
|
||||||
|
Printer.plug_ip.isnot(None),
|
||||||
|
Printer.active == True
|
||||||
|
).order_by(Printer.plug_ip).all()
|
||||||
|
|
||||||
|
logger.info(f"\n📊 Tapo-Steckdosen Übersicht ({len(tapo_printers)} konfiguriert):")
|
||||||
|
logger.info("=" * 80)
|
||||||
|
|
||||||
|
for printer in tapo_printers:
|
||||||
|
logger.info(f" 📍 {printer.plug_ip} - {printer.name}")
|
||||||
|
logger.info(f" Standort: {printer.location}")
|
||||||
|
logger.info(f" Aktiv: {'✅' if printer.active else '❌'}")
|
||||||
|
logger.info("-" * 60)
|
||||||
|
|
||||||
|
def remove_all_tapo_outlets():
|
||||||
|
"""Entfernt alle Tapo-Steckdosen aus der Datenbank (Cleanup-Funktion)."""
|
||||||
|
|
||||||
|
db_session = get_db_session()
|
||||||
|
|
||||||
|
try:
|
||||||
|
tapo_printers = db_session.query(Printer).filter(
|
||||||
|
Printer.plug_ip.isnot(None)
|
||||||
|
).all()
|
||||||
|
|
||||||
|
count = len(tapo_printers)
|
||||||
|
|
||||||
|
if count == 0:
|
||||||
|
logger.info("ℹ️ Keine Tapo-Steckdosen in der Datenbank gefunden")
|
||||||
|
return
|
||||||
|
|
||||||
|
for printer in tapo_printers:
|
||||||
|
logger.info(f"🗑️ Entferne: {printer.name} ({printer.plug_ip})")
|
||||||
|
db_session.delete(printer)
|
||||||
|
|
||||||
|
db_session.commit()
|
||||||
|
logger.info(f"✅ {count} Tapo-Steckdosen erfolgreich entfernt")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db_session.rollback()
|
||||||
|
logger.error(f"❌ Fehler beim Entfernen: {e}")
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
db_session.close()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Tapo-Steckdosen Setup")
|
||||||
|
parser.add_argument("--setup", action="store_true", help="Tapo-Steckdosen einrichten")
|
||||||
|
parser.add_argument("--status", action="store_true", help="Status anzeigen")
|
||||||
|
parser.add_argument("--cleanup", action="store_true", help="Alle Tapo-Steckdosen entfernen")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.setup:
|
||||||
|
logger.info("🔧 Starte Tapo-Steckdosen Setup...")
|
||||||
|
setup_tapo_outlets()
|
||||||
|
elif args.status:
|
||||||
|
logger.info("📊 Zeige Tapo-Status...")
|
||||||
|
db_session = get_db_session()
|
||||||
|
try:
|
||||||
|
show_tapo_status(db_session)
|
||||||
|
finally:
|
||||||
|
db_session.close()
|
||||||
|
elif args.cleanup:
|
||||||
|
logger.info("🗑️ Starte Cleanup...")
|
||||||
|
remove_all_tapo_outlets()
|
||||||
|
else:
|
||||||
|
logger.info("📋 Verwendung:")
|
||||||
|
logger.info(" python3.11 setup_tapo_outlets.py --setup # Steckdosen einrichten")
|
||||||
|
logger.info(" python3.11 setup_tapo_outlets.py --status # Status anzeigen")
|
||||||
|
logger.info(" python3.11 setup_tapo_outlets.py --cleanup # Alle entfernen")
|
@ -232,40 +232,44 @@ class AdminDashboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attachModalEvents() {
|
attachModalEvents() {
|
||||||
// Error-Alert Buttons
|
// Logs-Funktionalität Event-Listener
|
||||||
this.addEventListenerSafe('#fix-errors-btn', 'click', (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
this.fixErrors();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addEventListenerSafe('#dismiss-errors-btn', 'click', (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
this.dismissErrors();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addEventListenerSafe('#view-error-details-btn', 'click', (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
window.location.href = '/admin-dashboard?tab=logs';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Logs-Funktionalität
|
|
||||||
this.addEventListenerSafe('#refresh-logs-btn', 'click', (e) => {
|
this.addEventListenerSafe('#refresh-logs-btn', 'click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.loadLogs();
|
this.loadLogs();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addEventListenerSafe('#export-logs-btn', 'click', (e) => {
|
this.addEventListenerSafe('#export-logs-btn', 'click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.exportLogs();
|
this.exportLogs();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addEventListenerSafe('#log-level-filter', 'change', (e) => {
|
this.addEventListenerSafe('#log-level-filter', 'change', (e) => {
|
||||||
this.loadLogs();
|
e.preventDefault();
|
||||||
|
const selectedLevel = e.target.value;
|
||||||
|
this.loadLogs(selectedLevel);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Modal-bezogene Event-Listener (existierende)
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
// User-Modal schließen bei Klick außerhalb
|
||||||
|
if (e.target.id === 'user-modal') {
|
||||||
|
this.closeUserModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printer-Modal schließen bei Klick außerhalb
|
||||||
|
if (e.target.id === 'printer-modal') {
|
||||||
|
this.closePrinterModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ESC-Taste für Modal-Schließen
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Escape') {
|
||||||
|
this.closeUserModal();
|
||||||
|
this.closePrinterModal();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,28 +305,26 @@ class AdminDashboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadInitialData() {
|
async loadInitialData() {
|
||||||
await this.loadLiveStats();
|
try {
|
||||||
await this.checkSystemHealth();
|
console.log('📋 Lade initiale Admin-Daten...');
|
||||||
|
|
||||||
// Button-Test ausführen
|
// Live-Statistiken laden
|
||||||
setTimeout(() => {
|
await this.loadLiveStats();
|
||||||
this.testButtons();
|
|
||||||
}, 1000);
|
// System-Health prüfen
|
||||||
|
await this.checkSystemHealth();
|
||||||
// Logs laden falls wir auf dem Logs-Tab sind
|
|
||||||
if (window.location.search.includes('tab=logs') || document.querySelector('.tabs [href*="logs"]')?.classList.contains('active')) {
|
// Falls wir auf der Logs-Seite sind, Logs laden
|
||||||
await this.loadLogs();
|
const currentPath = window.location.pathname;
|
||||||
}
|
if (currentPath.includes('/admin/logs') || document.querySelector('.admin-logs-tab')) {
|
||||||
// Prüfe auch ob der Logs-Tab durch die URL-Parameter aktiv ist
|
await this.loadLogs();
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
}
|
||||||
const activeTab = urlParams.get('tab');
|
|
||||||
if (activeTab === 'logs') {
|
console.log('✅ Initiale Admin-Daten geladen');
|
||||||
await this.loadLogs();
|
|
||||||
}
|
} catch (error) {
|
||||||
// Oder prüfe ob das Logs-Container-Element sichtbar ist
|
console.error('❌ Fehler beim Laden der initialen Daten:', error);
|
||||||
const logsContainer = document.getElementById('logs-container');
|
this.showNotification('Fehler beim Laden der Admin-Daten', 'error');
|
||||||
if (logsContainer && logsContainer.offsetParent !== null) {
|
|
||||||
await this.loadLogs();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,7 +1062,7 @@ class AdminDashboard {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const filter = level || document.getElementById('log-level-filter')?.value || 'all';
|
const filter = level || document.getElementById('log-level-filter')?.value || 'all';
|
||||||
const url = `${this.apiBaseUrl}/api/admin/logs?level=${filter}&limit=100`;
|
const url = `${this.apiBaseUrl}/admin/api/logs?level=${filter}&limit=100`;
|
||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
headers: {
|
headers: {
|
||||||
@ -1203,30 +1205,42 @@ class AdminDashboard {
|
|||||||
this.showNotification('📥 Logs werden exportiert...', 'info');
|
this.showNotification('📥 Logs werden exportiert...', 'info');
|
||||||
|
|
||||||
const filter = document.getElementById('log-level-filter')?.value || 'all';
|
const filter = document.getElementById('log-level-filter')?.value || 'all';
|
||||||
const url = `${this.apiBaseUrl}/api/admin/logs/export?level=${filter}`;
|
const url = `${this.apiBaseUrl}/admin/api/logs/export`;
|
||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
'X-CSRFToken': this.csrfToken
|
'X-CSRFToken': this.csrfToken
|
||||||
}
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
level: filter,
|
||||||
|
format: 'csv'
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download als Datei
|
const data = await response.json();
|
||||||
const blob = await response.blob();
|
|
||||||
const downloadUrl = window.URL.createObjectURL(blob);
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = downloadUrl;
|
|
||||||
a.download = `system-logs-${new Date().toISOString().split('T')[0]}.csv`;
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
document.body.removeChild(a);
|
|
||||||
window.URL.revokeObjectURL(downloadUrl);
|
|
||||||
|
|
||||||
this.showNotification('✅ Logs erfolgreich exportiert!', 'success');
|
if (data.success && data.content) {
|
||||||
|
// Download als Datei
|
||||||
|
const blob = new Blob([data.content], { type: data.content_type });
|
||||||
|
const downloadUrl = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = downloadUrl;
|
||||||
|
a.download = data.filename;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
window.URL.revokeObjectURL(downloadUrl);
|
||||||
|
|
||||||
|
this.showNotification('✅ Logs erfolgreich exportiert!', 'success');
|
||||||
|
} else {
|
||||||
|
throw new Error(data.error || 'Unbekannter Fehler beim Export');
|
||||||
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Fehler beim Exportieren der Logs:', error);
|
console.error('Fehler beim Exportieren der Logs:', error);
|
||||||
@ -1334,11 +1348,31 @@ class AdminDashboard {
|
|||||||
let adminDashboardInstance = null;
|
let adminDashboardInstance = null;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
if (!adminDashboardInstance) {
|
// Verhindere doppelte Initialisierung
|
||||||
adminDashboardInstance = new AdminDashboard();
|
if (window.adminDashboard) {
|
||||||
window.AdminDashboard = adminDashboardInstance;
|
console.log('⚠️ Admin Dashboard bereits initialisiert, überspringe...');
|
||||||
console.log('🎯 Admin Dashboard erfolgreich initialisiert (unified)');
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('🚀 Starte Mercedes-Benz MYP Admin Dashboard...');
|
||||||
|
|
||||||
|
// Dashboard erstellen
|
||||||
|
window.adminDashboard = new AdminDashboard();
|
||||||
|
|
||||||
|
// Überprüfe, ob wir auf dem Logs-Tab sind und lade Logs
|
||||||
|
setTimeout(() => {
|
||||||
|
const currentUrl = window.location.pathname;
|
||||||
|
const isLogsTab = currentUrl.includes('/admin/logs') ||
|
||||||
|
document.querySelector('[href*="logs"]')?.closest('.bg-gradient-to-r') ||
|
||||||
|
document.getElementById('logs-container');
|
||||||
|
|
||||||
|
if (isLogsTab) {
|
||||||
|
console.log('📋 Logs-Tab erkannt, lade Logs...');
|
||||||
|
window.adminDashboard.loadLogs();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
console.log('✅ Admin Dashboard Initialisierung abgeschlossen');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Export für globalen Zugriff
|
// Export für globalen Zugriff
|
||||||
|
@ -232,7 +232,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
<!-- Navigation Tabs -->
|
<!-- Navigation Tabs -->
|
||||||
<div class="bg-white/80 dark:bg-slate-800/80 backdrop-blur-xl rounded-3xl border border-white/20 dark:border-slate-700/50 p-4 mb-12 shadow-xl">
|
<div class="bg-white/80 dark:bg-slate-800/80 backdrop-blur-xl rounded-3xl border border-white/20 dark:border-slate-700/50 p-4 mb-12 shadow-xl">
|
||||||
<nav class="flex space-x-2" aria-label="Tabs">
|
<nav class="flex space-x-2" aria-label="Tabs">
|
||||||
<a href="{{ url_for('admin_page', tab='users') }}"
|
<a href="{{ url_for('admin.users_overview') }}"
|
||||||
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'users' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'users' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
||||||
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'users' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'users' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
|
||||||
@ -240,7 +240,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
Benutzer
|
Benutzer
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('admin_page', tab='printers') }}"
|
<a href="{{ url_for('admin.printers_overview') }}"
|
||||||
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'printers' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'printers' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
||||||
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'printers' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'printers' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||||
@ -248,7 +248,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
Drucker-Steckdosen
|
Drucker-Steckdosen
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('admin_page', tab='jobs') }}"
|
<a href="{{ url_for('jobs_page') }}"
|
||||||
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'jobs' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'jobs' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
||||||
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'jobs' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'jobs' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"/>
|
||||||
@ -256,7 +256,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
Reservierungen
|
Reservierungen
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('admin_page', tab='system') }}"
|
<a href="{{ url_for('admin.advanced_settings') }}"
|
||||||
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'system' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'system' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
||||||
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'system' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'system' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<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="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"/>
|
||||||
@ -265,7 +265,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
System
|
System
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('admin_page', tab='logs') }}"
|
<a href="{{ url_for('admin.logs_overview') }}"
|
||||||
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'logs' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'logs' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
||||||
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'logs' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'logs' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<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"/>
|
<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"/>
|
||||||
@ -273,7 +273,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
Logs
|
Logs
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('admin_guest_requests') }}"
|
<a href="{{ url_for('admin.guest_requests') }}"
|
||||||
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'guest_requests' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
class="group flex items-center px-6 py-3 text-sm font-medium rounded-xl transition-all duration-300 {{ 'bg-gradient-to-r from-blue-500 to-blue-600 text-white shadow-lg' if active_tab == 'guest_requests' else 'text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700/50 hover:text-slate-900 dark:hover:text-white' }}">
|
||||||
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'guest_requests' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2 {{ 'text-white' if active_tab == 'guest_requests' else 'text-slate-400 group-hover:text-slate-600 dark:group-hover:text-slate-300' }}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<i class="fas fa-print text-blue-600 dark:text-blue-400 text-2xl"></i>
|
<i class="fas fa-print text-blue-600 dark:text-blue-400 text-2xl"></i>
|
||||||
<h1 class="text-2xl font-bold text-slate-800 dark:text-white">Neuen Drucker hinzufügen</h1>
|
<h1 class="text-2xl font-bold text-slate-800 dark:text-white">Neuen Drucker hinzufügen</h1>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ url_for('admin_page', tab='printers') }}"
|
<a href="{{ url_for('admin.admin_dashboard', tab='printers') }}"
|
||||||
class="bg-slate-500 hover:bg-slate-600 text-white px-4 py-2 rounded-lg transition-colors">
|
class="bg-slate-500 hover:bg-slate-600 text-white px-4 py-2 rounded-lg transition-colors">
|
||||||
<i class="fas fa-arrow-left mr-2"></i>Zurück
|
<i class="fas fa-arrow-left mr-2"></i>Zurück
|
||||||
</a>
|
</a>
|
||||||
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
<!-- Formular -->
|
<!-- Formular -->
|
||||||
<div class="form-container rounded-lg p-6">
|
<div class="form-container rounded-lg p-6">
|
||||||
<form action="{{ url_for('admin_create_printer_form') }}" method="POST" class="space-y-6">
|
<form action="{{ url_for('admin.create_printer_api') }}" method="POST" class="space-y-6">
|
||||||
<!-- CSRF Token -->
|
<!-- CSRF Token -->
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
|
|
||||||
@ -142,7 +142,7 @@
|
|||||||
class="flex-1 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors">
|
class="flex-1 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors">
|
||||||
<i class="fas fa-save mr-2"></i>Drucker erstellen
|
<i class="fas fa-save mr-2"></i>Drucker erstellen
|
||||||
</button>
|
</button>
|
||||||
<a href="{{ url_for('admin_page', tab='printers') }}"
|
<a href="{{ url_for('admin.admin_dashboard', tab='printers') }}"
|
||||||
class="flex-1 bg-slate-500 hover:bg-slate-600 text-white px-4 py-2 rounded-lg text-center transition-colors">
|
class="flex-1 bg-slate-500 hover:bg-slate-600 text-white px-4 py-2 rounded-lg text-center transition-colors">
|
||||||
<i class="fas fa-times mr-2"></i>Abbrechen
|
<i class="fas fa-times mr-2"></i>Abbrechen
|
||||||
</a>
|
</a>
|
||||||
|
@ -153,7 +153,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Zurück Button -->
|
<!-- Zurück Button -->
|
||||||
<a href="{{ url_for('admin_page', tab='users') }}"
|
<a href="{{ url_for('admin.admin_dashboard', tab='users') }}"
|
||||||
class="btn-mercedes-secondary text-white px-6 py-3 rounded-xl font-medium transition-all duration-300 flex items-center space-x-2 hover:scale-105">
|
class="btn-mercedes-secondary text-white px-6 py-3 rounded-xl font-medium transition-all duration-300 flex items-center space-x-2 hover:scale-105">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
<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 19l-7-7m0 0l7-7m-7 7h18"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
||||||
@ -165,7 +165,7 @@
|
|||||||
|
|
||||||
<!-- Hauptformular -->
|
<!-- Hauptformular -->
|
||||||
<div class="admin-form-container rounded-2xl p-8 transition-all duration-300">
|
<div class="admin-form-container rounded-2xl p-8 transition-all duration-300">
|
||||||
<form id="userForm" action="{{ url_for('admin_create_user_form') }}" method="POST" class="space-y-8">
|
<form id="userForm" action="{{ url_for('admin.create_user_api') }}" method="POST" class="space-y-8">
|
||||||
<!-- CSRF Token -->
|
<!-- CSRF Token -->
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
|
|
||||||
@ -343,7 +343,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<a href="{{ url_for('admin_page', tab='users') }}"
|
<a href="{{ url_for('admin.admin_dashboard', tab='users') }}"
|
||||||
class="btn-mercedes-secondary text-white px-8 py-4 rounded-xl font-semibold text-center transition-all duration-300 flex items-center justify-center space-x-3 hover:scale-105">
|
class="btn-mercedes-secondary text-white px-8 py-4 rounded-xl font-semibold text-center transition-all duration-300 flex items-center justify-center space-x-3 hover:scale-105">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
<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="M6 18L18 6M6 6l12 12"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||||
|
@ -345,7 +345,7 @@
|
|||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-4">
|
||||||
<a href="{{ url_for('admin_page') }}" class="p-3 hover:bg-black/5 dark:hover:bg-white/5 rounded-2xl transition-all duration-300 group">
|
<a href="{{ url_for('admin.admin_dashboard') }}" class="p-3 hover:bg-black/5 dark:hover:bg-white/5 rounded-2xl transition-all duration-300 group">
|
||||||
<svg class="w-6 h-6 text-slate-600 dark:text-slate-400 group-hover:text-slate-900 dark:group-hover:text-white transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-6 h-6 text-slate-600 dark:text-slate-400 group-hover:text-slate-900 dark:group-hover:text-white transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<i class="fas fa-edit text-blue-600 dark:text-blue-400 text-2xl"></i>
|
<i class="fas fa-edit text-blue-600 dark:text-blue-400 text-2xl"></i>
|
||||||
<h1 class="text-2xl font-bold text-slate-800 dark:text-white">Drucker bearbeiten</h1>
|
<h1 class="text-2xl font-bold text-slate-800 dark:text-white">Drucker bearbeiten</h1>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ url_for('admin_page', tab='printers') }}"
|
<a href="{{ url_for('admin.admin_dashboard', tab='printers') }}"
|
||||||
class="bg-slate-500 hover:bg-slate-600 text-white px-4 py-2 rounded-lg transition-colors">
|
class="bg-slate-500 hover:bg-slate-600 text-white px-4 py-2 rounded-lg transition-colors">
|
||||||
<i class="fas fa-arrow-left mr-2"></i>Zurück
|
<i class="fas fa-arrow-left mr-2"></i>Zurück
|
||||||
</a>
|
</a>
|
||||||
@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
<!-- Formular -->
|
<!-- Formular -->
|
||||||
<div class="form-container rounded-lg p-6">
|
<div class="form-container rounded-lg p-6">
|
||||||
<form action="{{ url_for('admin_update_printer_form', printer_id=printer.id) }}" method="POST" class="space-y-6">
|
<form action="{{ url_for('admin.update_printer_api', printer_id=printer.id) }}" method="POST" class="space-y-6">
|
||||||
<!-- CSRF Token -->
|
<!-- CSRF Token -->
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
|
|
||||||
@ -185,7 +185,7 @@
|
|||||||
class="flex-1 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors">
|
class="flex-1 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors">
|
||||||
<i class="fas fa-save mr-2"></i>Änderungen speichern
|
<i class="fas fa-save mr-2"></i>Änderungen speichern
|
||||||
</button>
|
</button>
|
||||||
<a href="{{ url_for('admin_page', tab='printers') }}"
|
<a href="{{ url_for('admin.admin_dashboard', tab='printers') }}"
|
||||||
class="flex-1 bg-slate-500 hover:bg-slate-600 text-white px-4 py-2 rounded-lg text-center transition-colors">
|
class="flex-1 bg-slate-500 hover:bg-slate-600 text-white px-4 py-2 rounded-lg text-center transition-colors">
|
||||||
<i class="fas fa-times mr-2"></i>Abbrechen
|
<i class="fas fa-times mr-2"></i>Abbrechen
|
||||||
</a>
|
</a>
|
||||||
|
@ -221,7 +221,7 @@ input:checked + .toggle-slider:before {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ url_for('admin_page', tab='users') }}"
|
<a href="{{ url_for('admin.admin_dashboard', tab='users') }}"
|
||||||
class="group inline-flex items-center px-6 py-3 bg-white/80 dark:bg-slate-800/80 backdrop-blur-sm text-slate-700 dark:text-slate-300 rounded-2xl hover:bg-white dark:hover:bg-slate-700 transition-all duration-300 shadow-lg hover:shadow-xl border border-white/20 dark:border-slate-700/50">
|
class="group inline-flex items-center px-6 py-3 bg-white/80 dark:bg-slate-800/80 backdrop-blur-sm text-slate-700 dark:text-slate-300 rounded-2xl hover:bg-white dark:hover:bg-slate-700 transition-all duration-300 shadow-lg hover:shadow-xl border border-white/20 dark:border-slate-700/50">
|
||||||
<svg class="w-5 h-5 mr-2 transition-transform group-hover:-translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2 transition-transform group-hover:-translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
||||||
@ -234,7 +234,7 @@ input:checked + .toggle-slider:before {
|
|||||||
|
|
||||||
<!-- Modern Form with Glass Effect -->
|
<!-- Modern Form with Glass Effect -->
|
||||||
<div class="glass-card rounded-3xl p-10 shadow-2xl">
|
<div class="glass-card rounded-3xl p-10 shadow-2xl">
|
||||||
<form method="POST" action="{{ url_for('admin_update_user_form', user_id=user.id) }}" class="space-y-8" id="userEditForm">
|
<form method="POST" action="{{ url_for('admin.update_user_api', user_id=user.id) }}" class="space-y-8" id="userEditForm">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
<input type="hidden" name="_method" value="PUT"/>
|
<input type="hidden" name="_method" value="PUT"/>
|
||||||
|
|
||||||
@ -494,7 +494,7 @@ input:checked + .toggle-slider:before {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-4">
|
||||||
<a href="{{ url_for('admin_page', tab='users') }}"
|
<a href="{{ url_for('admin.admin_dashboard', tab='users') }}"
|
||||||
class="group inline-flex items-center px-8 py-4 bg-white/80 dark:bg-slate-800/80 backdrop-blur-sm text-slate-700 dark:text-slate-300 rounded-2xl hover:bg-white dark:hover:bg-slate-700 transition-all duration-300 shadow-lg hover:shadow-xl border border-white/20 dark:border-slate-700/50">
|
class="group inline-flex items-center px-8 py-4 bg-white/80 dark:bg-slate-800/80 backdrop-blur-sm text-slate-700 dark:text-slate-300 rounded-2xl hover:bg-white dark:hover:bg-slate-700 transition-all duration-300 shadow-lg hover:shadow-xl border border-white/20 dark:border-slate-700/50">
|
||||||
<svg class="w-5 h-5 mr-2 transition-transform group-hover:-translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2 transition-transform group-hover:-translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
<!-- Back to Admin Button -->
|
<!-- Back to Admin Button -->
|
||||||
<div>
|
<div>
|
||||||
<a href="{{ url_for('admin_page') }}"
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||||
class="inline-flex items-center px-6 py-3 bg-white/15 dark:bg-white/10 backdrop-blur-sm border border-white/30 dark:border-white/20 rounded-xl text-white hover:bg-white/25 dark:hover:bg-white/15 transition-all duration-300 hover:scale-105">
|
class="inline-flex items-center px-6 py-3 bg-white/15 dark:bg-white/10 backdrop-blur-sm border border-white/30 dark:border-white/20 rounded-xl text-white hover:bg-white/25 dark:hover:bg-white/15 transition-all duration-300 hover:scale-105">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<h1 class="text-3xl font-bold text-slate-900 dark:text-white">{{ printer.name }} verwalten</h1>
|
<h1 class="text-3xl font-bold text-slate-900 dark:text-white">{{ printer.name }} verwalten</h1>
|
||||||
<p class="text-slate-600 dark:text-slate-400 mt-2">Verwaltung und Überwachung des Druckers</p>
|
<p class="text-slate-600 dark:text-slate-400 mt-2">Verwaltung und Überwachung des Druckers</p>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ url_for('admin_page', tab='printers') }}" class="inline-flex items-center px-4 py-2 bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl hover:bg-slate-300 dark:hover:bg-slate-600 transition-all duration-300">
|
<a href="{{ url_for('admin.admin_dashboard', tab='printers') }}" class="inline-flex items-center px-4 py-2 bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl hover:bg-slate-300 dark:hover:bg-slate-600 transition-all duration-300">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
||||||
</svg>
|
</svg>
|
||||||
@ -63,7 +63,7 @@
|
|||||||
class="w-full px-4 py-2 bg-green-500 text-white rounded-xl hover:bg-green-600 transition-all duration-300">
|
class="w-full px-4 py-2 bg-green-500 text-white rounded-xl hover:bg-green-600 transition-all duration-300">
|
||||||
Verbindung testen
|
Verbindung testen
|
||||||
</button>
|
</button>
|
||||||
<a href="{{ url_for('admin_printer_settings_page', printer_id=printer.id) }}"
|
<a href="{{ url_for('admin.edit_printer_page', printer_id=printer.id) }}"
|
||||||
class="block w-full px-4 py-2 bg-slate-500 text-white rounded-xl hover:bg-slate-600 transition-all duration-300 text-center">
|
class="block w-full px-4 py-2 bg-slate-500 text-white rounded-xl hover:bg-slate-600 transition-all duration-300 text-center">
|
||||||
Einstellungen
|
Einstellungen
|
||||||
</a>
|
</a>
|
||||||
|
@ -311,7 +311,7 @@
|
|||||||
<nav class="text-sm font-medium text-slate-600 dark:text-slate-400 mb-4">
|
<nav class="text-sm font-medium text-slate-600 dark:text-slate-400 mb-4">
|
||||||
<ol class="list-none p-0 inline-flex">
|
<ol class="list-none p-0 inline-flex">
|
||||||
<li class="flex items-center">
|
<li class="flex items-center">
|
||||||
<a href="{{ url_for('admin_page') }}" class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">Admin-Dashboard</a>
|
<a href="{{ url_for('admin.admin_dashboard') }}" class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">Admin-Dashboard</a>
|
||||||
<svg class="fill-current w-3 h-3 mx-3 text-slate-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
|
<svg class="fill-current w-3 h-3 mx-3 text-slate-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
|
||||||
<path d="m285.476 272.971c4.686 4.686 4.686 12.284 0 16.97l-133.952 133.954c-4.686 4.686-12.284 4.686-16.97 0l-133.952-133.954c-4.686-4.686-4.686-12.284 0-16.97 4.686-4.686 12.284-4.686 16.97 0l125.462 125.463 125.462-125.463c4.686-4.686 12.284-4.686 16.97 0z"/>
|
<path d="m285.476 272.971c4.686 4.686 4.686 12.284 0 16.97l-133.952 133.954c-4.686 4.686-12.284 4.686-16.97 0l-133.952-133.954c-4.686-4.686-4.686-12.284 0-16.97 4.686-4.686 12.284-4.686 16.97 0l125.462 125.463 125.462-125.463c4.686-4.686 12.284-4.686 16.97 0z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<h1 class="text-3xl font-bold text-slate-900 dark:text-white">{{ printer.name }} - Einstellungen</h1>
|
<h1 class="text-3xl font-bold text-slate-900 dark:text-white">{{ printer.name }} - Einstellungen</h1>
|
||||||
<p class="text-slate-600 dark:text-slate-400 mt-2">Konfiguration und Einstellungen des Druckers</p>
|
<p class="text-slate-600 dark:text-slate-400 mt-2">Konfiguration und Einstellungen des Druckers</p>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ url_for('admin_manage_printer_page', printer_id=printer.id) }}" class="inline-flex items-center px-4 py-2 bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl hover:bg-slate-300 dark:hover:bg-slate-600 transition-all duration-300">
|
<a href="{{ url_for('admin.admin_dashboard', tab='printers') }}" class="inline-flex items-center px-4 py-2 bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl hover:bg-slate-300 dark:hover:bg-slate-600 transition-all duration-300">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
||||||
</svg>
|
</svg>
|
||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<!-- Form -->
|
<!-- Form -->
|
||||||
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-xl p-8">
|
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-xl p-8">
|
||||||
<form method="POST" action="{{ url_for('admin_update_printer_form', printer_id=printer.id) }}" class="space-y-6">
|
<form method="POST" action="{{ url_for('admin.update_printer_api', printer_id=printer.id) }}" class="space-y-6">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
<input type="hidden" name="_method" value="PUT"/>
|
<input type="hidden" name="_method" value="PUT"/>
|
||||||
|
|
||||||
@ -103,7 +103,7 @@
|
|||||||
|
|
||||||
<!-- Buttons -->
|
<!-- Buttons -->
|
||||||
<div class="flex items-center justify-end space-x-4 pt-4">
|
<div class="flex items-center justify-end space-x-4 pt-4">
|
||||||
<a href="{{ url_for('admin_manage_printer_page', printer_id=printer.id) }}"
|
<a href="{{ url_for('admin.admin_dashboard', tab='printers') }}"
|
||||||
class="px-6 py-3 border border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700 transition-all duration-300">
|
class="px-6 py-3 border border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700 transition-all duration-300">
|
||||||
Abbrechen
|
Abbrechen
|
||||||
</a>
|
</a>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<h1 class="text-3xl font-bold text-slate-900 dark:text-white">Admin-Einstellungen</h1>
|
<h1 class="text-3xl font-bold text-slate-900 dark:text-white">Admin-Einstellungen</h1>
|
||||||
<p class="text-slate-600 dark:text-slate-400 mt-2">Systemkonfiguration und Verwaltungsoptionen</p>
|
<p class="text-slate-600 dark:text-slate-400 mt-2">Systemkonfiguration und Verwaltungsoptionen</p>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ url_for('admin_page') }}" class="inline-flex items-center px-4 py-2 bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl hover:bg-slate-300 dark:hover:bg-slate-600 transition-all duration-300">
|
<a href="{{ url_for('admin.admin_dashboard') }}" class="inline-flex items-center px-4 py-2 bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-xl hover:bg-slate-300 dark:hover:bg-slate-600 transition-all duration-300">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -84,11 +84,11 @@
|
|||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<!-- Simplified navigation links -->
|
<!-- Simplified navigation links -->
|
||||||
<a href="{{ url_for('dashboard') }}" class="px-3 py-2 rounded-md text-sm font-medium hover:bg-slate-100 dark:hover:bg-slate-800">Dashboard</a>
|
<a href="{{ url_for('dashboard') }}" class="px-3 py-2 rounded-md text-sm font-medium hover:bg-slate-100 dark:hover:bg-slate-800">Dashboard</a>
|
||||||
<a href="{{ url_for('printers') }}" class="px-3 py-2 rounded-md text-sm font-medium hover:bg-slate-100 dark:hover:bg-slate-800">Drucker</a>
|
<a href="{{ url_for('printers_page') }}" class="px-3 py-2 rounded-md text-sm font-medium hover:bg-slate-100 dark:hover:bg-slate-800">Drucker</a>
|
||||||
<a href="{{ url_for('jobs') }}" class="px-3 py-2 rounded-md text-sm font-medium hover:bg-slate-100 dark:hover:bg-slate-800">Aufträge</a>
|
<a href="{{ url_for('jobs_page') }}" class="px-3 py-2 rounded-md text-sm font-medium hover:bg-slate-100 dark:hover:bg-slate-800">Aufträge</a>
|
||||||
|
|
||||||
{% if current_user.is_admin %}
|
{% if current_user.is_admin %}
|
||||||
<a href="{{ url_for('admin') }}" class="px-3 py-2 rounded-md text-sm font-medium hover:bg-slate-100 dark:hover:bg-slate-800">Admin</a>
|
<a href="{{ url_for('admin.admin_dashboard') }}" class="px-3 py-2 rounded-md text-sm font-medium hover:bg-slate-100 dark:hover:bg-slate-800">Admin</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- User menu -->
|
<!-- User menu -->
|
||||||
@ -99,7 +99,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<div id="user-dropdown" class="hidden absolute right-0 mt-2 w-48 bg-white dark:bg-slate-800 rounded-lg shadow-lg">
|
<div id="user-dropdown" class="hidden absolute right-0 mt-2 w-48 bg-white dark:bg-slate-800 rounded-lg shadow-lg">
|
||||||
<a href="{{ url_for('user_profile') }}" class="block px-4 py-2 text-sm hover:bg-slate-100 dark:hover:bg-slate-700">Profil</a>
|
<a href="{{ url_for('users.user_profile') }}" class="block px-4 py-2 text-sm hover:bg-slate-100 dark:hover:bg-slate-700">Profil</a>
|
||||||
<a href="{{ url_for('auth.logout') }}" class="block px-4 py-2 text-sm hover:bg-slate-100 dark:hover:bg-slate-700">Abmelden</a>
|
<a href="{{ url_for('auth.logout') }}" class="block px-4 py-2 text-sm hover:bg-slate-100 dark:hover:bg-slate-700">Abmelden</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -343,8 +343,8 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||||
<a href="{{ url_for('admin_page') }}"
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||||
class="nav-item {{ 'active' if request.endpoint == 'admin_page' else '' }}">
|
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">
|
<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="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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||||
@ -489,7 +489,7 @@
|
|||||||
|
|
||||||
<!-- Menu Items -->
|
<!-- Menu Items -->
|
||||||
<div class="py-1">
|
<div class="py-1">
|
||||||
<a href="{{ url_for('user_profile') }}"
|
<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">
|
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">
|
||||||
<svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
<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"/>
|
<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"/>
|
||||||
@ -497,7 +497,7 @@
|
|||||||
Mein Profil
|
Mein Profil
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('user_settings') }}"
|
<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">
|
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">
|
||||||
<svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
<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="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"/>
|
||||||
@ -552,7 +552,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<!-- Login Button - kompakteres Design -->
|
<!-- Login Button - kompakteres Design -->
|
||||||
<a href="{{ url_for('login') }}"
|
<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">
|
class="flex items-center space-x-1 py-1 px-2 rounded-md bg-blue-600 hover:bg-blue-700 text-white text-xs">
|
||||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
<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"/>
|
<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"/>
|
||||||
@ -625,8 +625,8 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||||
<a href="{{ url_for('admin_page') }}"
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'admin_page' else '' }}">
|
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">
|
<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="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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||||
@ -702,7 +702,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||||
<div class="pt-2 border-t border-slate-200 dark:border-slate-600">
|
<div class="pt-2 border-t border-slate-200 dark:border-slate-600">
|
||||||
<a href="{{ url_for('admin_plug_schedules') }}"
|
<a href="{{ url_for('admin.admin_plug_schedules') }}"
|
||||||
class="flex items-center space-x-2 text-slate-600 dark:text-slate-400 hover:text-blue-600 dark:hover:text-blue-400">
|
class="flex items-center space-x-2 text-slate-600 dark:text-slate-400 hover:text-blue-600 dark:hover:text-blue-400">
|
||||||
<span class="text-sm">🔌</span>
|
<span class="text-sm">🔌</span>
|
||||||
<span class="text-xs">Steckdosenschaltzeiten</span>
|
<span class="text-xs">Steckdosenschaltzeiten</span>
|
||||||
@ -807,7 +807,7 @@
|
|||||||
// Logout-Formular erstellen und absenden
|
// Logout-Formular erstellen und absenden
|
||||||
const form = document.createElement('form');
|
const form = document.createElement('form');
|
||||||
form.method = 'POST';
|
form.method = 'POST';
|
||||||
form.action = '{{ url_for("auth_logout") }}';
|
form.action = '{{ url_for("auth.logout") }}';
|
||||||
form.style.display = 'none';
|
form.style.display = 'none';
|
||||||
|
|
||||||
// CSRF-Token hinzufügen falls verfügbar
|
// CSRF-Token hinzufügen falls verfügbar
|
||||||
|
@ -349,8 +349,8 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||||
<a href="{{ url_for('admin_page') }}"
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||||
class="nav-item {{ 'active' if request.endpoint == 'admin_page' else '' }}">
|
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">
|
<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="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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||||
@ -503,7 +503,7 @@
|
|||||||
|
|
||||||
<!-- Menu Items -->
|
<!-- Menu Items -->
|
||||||
<div class="py-1">
|
<div class="py-1">
|
||||||
<a href="{{ url_for('user_profile') }}"
|
<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">
|
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">
|
<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"/>
|
<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"/>
|
||||||
@ -511,7 +511,7 @@
|
|||||||
Mein Profil
|
Mein Profil
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('user_settings') }}"
|
<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">
|
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">
|
<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="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"/>
|
||||||
@ -566,7 +566,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<!-- Login Button - kompakteres Design -->
|
<!-- Login Button - kompakteres Design -->
|
||||||
<a href="{{ url_for('login') }}"
|
<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">
|
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">
|
<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"/>
|
<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"/>
|
||||||
@ -639,8 +639,8 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||||
<a href="{{ url_for('admin_page') }}"
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'admin_page' else '' }}">
|
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">
|
<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="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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||||
@ -716,7 +716,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||||
<div class="pt-2 border-t border-slate-200 dark:border-slate-600">
|
<div class="pt-2 border-t border-slate-200 dark:border-slate-600">
|
||||||
<a href="{{ url_for('admin_plug_schedules') }}"
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||||
class="flex items-center space-x-2 text-slate-600 dark:text-slate-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200">
|
class="flex items-center space-x-2 text-slate-600 dark:text-slate-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200">
|
||||||
<span class="text-sm">🔌</span>
|
<span class="text-sm">🔌</span>
|
||||||
<span class="text-xs">Steckdosenschaltzeiten</span>
|
<span class="text-xs">Steckdosenschaltzeiten</span>
|
||||||
|
@ -308,10 +308,18 @@
|
|||||||
|
|
||||||
<a href="{{ url_for('printers_page') }}"
|
<a href="{{ url_for('printers_page') }}"
|
||||||
class="nav-item {{ 'active' if request.endpoint == 'printers_page' else '' }}">
|
class="nav-item {{ 'active' if request.endpoint == 'printers_page' else '' }}">
|
||||||
<i class="fas fa-plug w-5 h-5"></i>
|
<i class="fas fa-print w-5 h-5"></i>
|
||||||
<span>Drucker-Steckdosen</span>
|
<span>Drucker</span>
|
||||||
</a>
|
</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') }}"
|
<a href="{{ url_for('jobs_page') }}"
|
||||||
class="nav-item {{ 'active' if request.endpoint == 'jobs_page' else '' }}">
|
class="nav-item {{ 'active' if request.endpoint == 'jobs_page' else '' }}">
|
||||||
<i class="fas fa-clipboard-list w-5 h-5"></i>
|
<i class="fas fa-clipboard-list w-5 h-5"></i>
|
||||||
@ -343,8 +351,8 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||||
<a href="{{ url_for('admin_page') }}"
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||||
class="nav-item {{ 'active' if request.endpoint == 'admin_page' else '' }}">
|
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">
|
<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="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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||||
@ -460,7 +468,7 @@
|
|||||||
|
|
||||||
<!-- Menu Items -->
|
<!-- Menu Items -->
|
||||||
<div class="py-1">
|
<div class="py-1">
|
||||||
<a href="{{ url_for('user_profile') }}"
|
<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">
|
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">
|
<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"/>
|
<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"/>
|
||||||
@ -468,7 +476,7 @@
|
|||||||
Mein Profil
|
Mein Profil
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ url_for('user_settings') }}"
|
<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">
|
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">
|
<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="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"/>
|
||||||
@ -536,7 +544,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Login Button - kompakteres Design -->
|
<!-- Login Button - kompakteres Design -->
|
||||||
<a href="{{ url_for('login') }}"
|
<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">
|
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">
|
<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"/>
|
<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"/>
|
||||||
@ -565,9 +573,19 @@
|
|||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
<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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||||
</svg>
|
</svg>
|
||||||
<span>Drucker-Steckdosen</span>
|
<span>Drucker</span>
|
||||||
</a>
|
</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') }}"
|
<a href="{{ url_for('jobs_page') }}"
|
||||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'jobs_page' else '' }}">
|
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">
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
@ -609,8 +627,8 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||||
<a href="{{ url_for('admin_page') }}"
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||||
class="mobile-nav-item {{ 'active' if request.endpoint == 'admin_page' else '' }}">
|
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">
|
<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="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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||||
@ -686,10 +704,10 @@
|
|||||||
</div>
|
</div>
|
||||||
{% if current_user.is_authenticated and current_user.is_admin %}
|
{% if current_user.is_authenticated and current_user.is_admin %}
|
||||||
<div class="pt-2 border-t border-slate-200 dark:border-slate-600">
|
<div class="pt-2 border-t border-slate-200 dark:border-slate-600">
|
||||||
<a href="{{ url_for('admin_plug_schedules') }}"
|
<a href="{{ url_for('admin.admin_dashboard') }}"
|
||||||
class="flex items-center space-x-2 text-slate-600 dark:text-slate-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200">
|
class="flex items-center space-x-2 text-slate-600 dark:text-slate-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200">
|
||||||
<span class="text-sm">🔌</span>
|
<span class="text-sm">⚙️</span>
|
||||||
<span class="text-xs">Steckdosenschaltzeiten</span>
|
<span class="text-xs">Admin-Dashboard</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -795,7 +813,7 @@
|
|||||||
// Logout-Formular erstellen und absenden
|
// Logout-Formular erstellen und absenden
|
||||||
const form = document.createElement('form');
|
const form = document.createElement('form');
|
||||||
form.method = 'POST';
|
form.method = 'POST';
|
||||||
form.action = '{{ url_for("auth_logout") }}';
|
form.action = '{{ url_for("auth.logout") }}';
|
||||||
form.style.display = 'none';
|
form.style.display = 'none';
|
||||||
|
|
||||||
// CSRF-Token hinzufügen falls verfügbar
|
// CSRF-Token hinzufügen falls verfügbar
|
||||||
|
@ -401,7 +401,7 @@
|
|||||||
<div class="text-xs text-right mt-1 text-slate-500 dark:text-slate-400">{{ job.progress }}%</div>
|
<div class="text-xs text-right mt-1 text-slate-500 dark:text-slate-400">{{ job.progress }}%</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-right">
|
<td class="px-6 py-4 whitespace-nowrap text-right">
|
||||||
<a href="{{ url_for('job_detail', job_id=job.id) }}" class="text-slate-900 dark:text-white hover:text-slate-700 dark:hover:text-slate-300 font-medium">Details</a>
|
<a href="{{ url_for('jobs.get_job', job_id=job.id) }}" class="text-slate-900 dark:text-white hover:text-slate-700 dark:hover:text-slate-300 font-medium">Details</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
37
backend/templates/errors/400.html
Normal file
37
backend/templates/errors/400.html
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>400 - Ungültige Anfrage | MYP System</title>
|
||||||
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/glassmorphism.min.css') }}" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 dark:from-gray-900 dark:to-gray-800 min-h-screen flex items-center justify-center">
|
||||||
|
<div class="glass-card max-w-md w-full mx-4 p-8 text-center">
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="text-6xl font-bold text-red-500 mb-4">400</div>
|
||||||
|
<h1 class="text-2xl font-bold text-gray-800 dark:text-white mb-2">Ungültige Anfrage</h1>
|
||||||
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
|
Die Anfrage konnte nicht verarbeitet werden. Bitte überprüfen Sie Ihre Eingaben.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<a href="{{ url_for('dashboard') if current_user.is_authenticated else url_for('auth.login') }}"
|
||||||
|
class="block w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
{% if current_user.is_authenticated %}
|
||||||
|
Zum Dashboard
|
||||||
|
{% else %}
|
||||||
|
Zur Anmeldung
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button onclick="history.back()"
|
||||||
|
class="block w-full bg-gray-500 hover:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
Zurück
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
37
backend/templates/errors/405.html
Normal file
37
backend/templates/errors/405.html
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>405 - Methode nicht erlaubt | MYP System</title>
|
||||||
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/glassmorphism.min.css') }}" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 dark:from-gray-900 dark:to-gray-800 min-h-screen flex items-center justify-center">
|
||||||
|
<div class="glass-card max-w-md w-full mx-4 p-8 text-center">
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="text-6xl font-bold text-orange-500 mb-4">405</div>
|
||||||
|
<h1 class="text-2xl font-bold text-gray-800 dark:text-white mb-2">Methode nicht erlaubt</h1>
|
||||||
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
|
Die verwendete HTTP-Methode ist für diese URL nicht erlaubt.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<a href="{{ url_for('dashboard') if current_user.is_authenticated else url_for('auth.login') }}"
|
||||||
|
class="block w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
{% if current_user.is_authenticated %}
|
||||||
|
Zum Dashboard
|
||||||
|
{% else %}
|
||||||
|
Zur Anmeldung
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button onclick="history.back()"
|
||||||
|
class="block w-full bg-gray-500 hover:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
Zurück
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
37
backend/templates/errors/413.html
Normal file
37
backend/templates/errors/413.html
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>413 - Datei zu groß | MYP System</title>
|
||||||
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/glassmorphism.min.css') }}" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 dark:from-gray-900 dark:to-gray-800 min-h-screen flex items-center justify-center">
|
||||||
|
<div class="glass-card max-w-md w-full mx-4 p-8 text-center">
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="text-6xl font-bold text-yellow-500 mb-4">413</div>
|
||||||
|
<h1 class="text-2xl font-bold text-gray-800 dark:text-white mb-2">Datei zu groß</h1>
|
||||||
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
|
Die hochgeladene Datei ist zu groß. Maximale Dateigröße: 16 MB.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<a href="{{ url_for('dashboard') if current_user.is_authenticated else url_for('auth.login') }}"
|
||||||
|
class="block w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
{% if current_user.is_authenticated %}
|
||||||
|
Zum Dashboard
|
||||||
|
{% else %}
|
||||||
|
Zur Anmeldung
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button onclick="history.back()"
|
||||||
|
class="block w-full bg-gray-500 hover:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
Zurück
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
45
backend/templates/errors/429.html
Normal file
45
backend/templates/errors/429.html
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>429 - Zu viele Anfragen | MYP System</title>
|
||||||
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/glassmorphism.min.css') }}" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 dark:from-gray-900 dark:to-gray-800 min-h-screen flex items-center justify-center">
|
||||||
|
<div class="glass-card max-w-md w-full mx-4 p-8 text-center">
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="text-6xl font-bold text-red-500 mb-4">429</div>
|
||||||
|
<h1 class="text-2xl font-bold text-gray-800 dark:text-white mb-2">Zu viele Anfragen</h1>
|
||||||
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
|
Sie haben zu viele Anfragen gesendet. Bitte warten Sie einen Moment und versuchen Sie es erneut.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="bg-yellow-100 dark:bg-yellow-900 border border-yellow-400 text-yellow-700 dark:text-yellow-300 px-4 py-3 rounded">
|
||||||
|
<p class="text-sm">
|
||||||
|
<strong>Tipp:</strong> Warten Sie 60 Sekunden und versuchen Sie es dann erneut.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<a href="{{ url_for('dashboard') if current_user.is_authenticated else url_for('auth.login') }}"
|
||||||
|
class="block w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
{% if current_user.is_authenticated %}
|
||||||
|
Zum Dashboard
|
||||||
|
{% else %}
|
||||||
|
Zur Anmeldung
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button onclick="setTimeout(() => history.back(), 1000)"
|
||||||
|
class="block w-full bg-gray-500 hover:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
Zurück (in 1 Sekunde)
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
45
backend/templates/errors/502.html
Normal file
45
backend/templates/errors/502.html
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>502 - Gateway-Fehler | MYP System</title>
|
||||||
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/glassmorphism.min.css') }}" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 dark:from-gray-900 dark:to-gray-800 min-h-screen flex items-center justify-center">
|
||||||
|
<div class="glass-card max-w-md w-full mx-4 p-8 text-center">
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="text-6xl font-bold text-red-600 mb-4">502</div>
|
||||||
|
<h1 class="text-2xl font-bold text-gray-800 dark:text-white mb-2">Gateway-Fehler</h1>
|
||||||
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
|
Der Server ist vorübergehend nicht verfügbar. Bitte versuchen Sie es in wenigen Minuten erneut.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="bg-red-100 dark:bg-red-900 border border-red-400 text-red-700 dark:text-red-300 px-4 py-3 rounded">
|
||||||
|
<p class="text-sm">
|
||||||
|
<strong>Hinweis:</strong> Dies ist ein temporärer Fehler. Der Service wird automatisch wiederhergestellt.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<button onclick="location.reload()"
|
||||||
|
class="block w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
Seite neu laden
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a href="{{ url_for('dashboard') if current_user.is_authenticated else url_for('auth.login') }}"
|
||||||
|
class="block w-full bg-gray-500 hover:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
{% if current_user.is_authenticated %}
|
||||||
|
Zum Dashboard
|
||||||
|
{% else %}
|
||||||
|
Zur Anmeldung
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
57
backend/templates/errors/503.html
Normal file
57
backend/templates/errors/503.html
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>503 - Service nicht verfügbar | MYP System</title>
|
||||||
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/glassmorphism.min.css') }}" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 dark:from-gray-900 dark:to-gray-800 min-h-screen flex items-center justify-center">
|
||||||
|
<div class="glass-card max-w-md w-full mx-4 p-8 text-center">
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="text-6xl font-bold text-orange-600 mb-4">503</div>
|
||||||
|
<h1 class="text-2xl font-bold text-gray-800 dark:text-white mb-2">Service nicht verfügbar</h1>
|
||||||
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
|
Der Service ist vorübergehend nicht verfügbar. Wir arbeiten an der Behebung des Problems.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="bg-orange-100 dark:bg-orange-900 border border-orange-400 text-orange-700 dark:text-orange-300 px-4 py-3 rounded">
|
||||||
|
<p class="text-sm">
|
||||||
|
<strong>Wartung:</strong> Der Service wird in Kürze wieder verfügbar sein.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<button onclick="setTimeout(() => location.reload(), 5000)"
|
||||||
|
class="block w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
Automatisch neu laden (5s)
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button onclick="location.reload()"
|
||||||
|
class="block w-full bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
Jetzt neu laden
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a href="{{ url_for('dashboard') if current_user.is_authenticated else url_for('auth.login') }}"
|
||||||
|
class="block w-full bg-gray-500 hover:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors">
|
||||||
|
{% if current_user.is_authenticated %}
|
||||||
|
Zum Dashboard
|
||||||
|
{% else %}
|
||||||
|
Zur Anmeldung
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Automatisches Neuladen nach 30 Sekunden
|
||||||
|
setTimeout(() => {
|
||||||
|
location.reload();
|
||||||
|
}, 30000);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
51
backend/templates/errors/505.html
Normal file
51
backend/templates/errors/505.html
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de" x-data="{ darkMode: window.matchMedia('(prefers-color-scheme: dark)').matches || localStorage.getItem('theme') === 'dark' }" x-bind:class="{ 'dark': darkMode }">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>505 - HTTP-Version nicht unterstützt | MYP 3D-Druck-Management</title>
|
||||||
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/glassmorphism.min.css') }}" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
.error-bg {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="min-h-screen bg-gradient-to-br from-slate-100 to-slate-200 dark:from-slate-900 dark:to-slate-800 flex items-center justify-center px-4 error-bg">
|
||||||
|
<div class="max-w-lg w-full">
|
||||||
|
<div class="glassmorphism-card text-center p-8">
|
||||||
|
<div class="mb-6">
|
||||||
|
<div class="w-24 h-24 mx-auto bg-red-100 dark:bg-red-900/30 rounded-full flex items-center justify-center mb-4">
|
||||||
|
<svg class="w-12 h-12 text-red-600 dark:text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 19c-.77.833.192 2.5 1.732 2.5z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h1 class="text-4xl font-bold text-slate-800 dark:text-white mb-2">505</h1>
|
||||||
|
<h2 class="text-xl font-semibold text-slate-700 dark:text-slate-300 mb-4">HTTP-Version nicht unterstützt</h2>
|
||||||
|
<p class="text-slate-600 dark:text-slate-400 leading-relaxed">
|
||||||
|
Die verwendete HTTP-Version wird vom Server nicht unterstützt. Bitte verwenden Sie einen aktuellen Browser.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-3">
|
||||||
|
<a href="{{ url_for('dashboard') if current_user.is_authenticated else url_for('auth.login') }}"
|
||||||
|
class="inline-flex items-center justify-center w-full px-6 py-3 bg-blue-600 hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600 text-white font-medium rounded-lg transition-all duration-200 shadow-lg hover:shadow-xl">
|
||||||
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
|
||||||
|
</svg>
|
||||||
|
Zur Startseite
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button onclick="history.back()"
|
||||||
|
class="inline-flex items-center justify-center w-full px-6 py-3 bg-slate-600 hover:bg-slate-700 dark:bg-slate-500 dark:hover:bg-slate-600 text-white font-medium rounded-lg transition-all duration-200">
|
||||||
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
|
||||||
|
</svg>
|
||||||
|
Zurück
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -404,7 +404,7 @@
|
|||||||
Zum Dashboard
|
Zum Dashboard
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('login') if url_for else '/login' }}"
|
<a href="{{ url_for('auth.login') if url_for else '/login' }}"
|
||||||
class="btn-primary group">
|
class="btn-primary group">
|
||||||
<svg class="w-6 h-6 mr-3 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-6 h-6 mr-3 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<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"/>
|
<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"/>
|
||||||
@ -711,7 +711,7 @@
|
|||||||
Zum Dashboard
|
Zum Dashboard
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('login') if url_for else '/login' }}"
|
<a href="{{ url_for('auth.login') if url_for else '/login' }}"
|
||||||
class="btn-primary group">
|
class="btn-primary group">
|
||||||
<svg class="w-6 h-6 mr-3 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-6 h-6 mr-3 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<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"/>
|
<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"/>
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<!-- Job Creation Form -->
|
<!-- Job Creation Form -->
|
||||||
<div class="dashboard-card p-8">
|
<div class="dashboard-card p-8">
|
||||||
<form id="newJobForm" action="{{ url_for('create_job') }}" method="POST" enctype="multipart/form-data" class="space-y-6">
|
<form id="newJobForm" action="{{ url_for('jobs.create_job') }}" method="POST" enctype="multipart/form-data" class="space-y-6">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||||
|
@ -459,7 +459,7 @@
|
|||||||
<i class="fas fa-chart-line mr-2"></i>
|
<i class="fas fa-chart-line mr-2"></i>
|
||||||
Dashboard
|
Dashboard
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ url_for('user_settings') }}" class="inline-flex items-center px-4 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors">
|
<a href="{{ url_for('users.user_settings') }}" class="inline-flex items-center px-4 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition-colors">
|
||||||
<i class="fas fa-cog mr-2"></i>
|
<i class="fas fa-cog mr-2"></i>
|
||||||
Einstellungen
|
Einstellungen
|
||||||
</a>
|
</a>
|
||||||
|
@ -285,7 +285,7 @@
|
|||||||
|
|
||||||
<!-- Login Form -->
|
<!-- Login Form -->
|
||||||
<div class="mercedes-card p-8">
|
<div class="mercedes-card p-8">
|
||||||
<form id="loginForm" method="POST" action="{{ url_for('login') if url_for else '#' }}" class="space-y-6">
|
<form id="loginForm" method="POST" action="{{ url_for('auth.login') if url_for else '#' }}" class="space-y-6">
|
||||||
<!-- CSRF Token -->
|
<!-- CSRF Token -->
|
||||||
{% if form %}
|
{% if form %}
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
@ -382,7 +382,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-sm">
|
<div class="text-sm">
|
||||||
<a href="{{ url_for('reset_password_request') if url_for and url_for('reset_password_request') else '#' }}"
|
<a href="{{ url_for('auth.reset_password_request') if url_for and url_for('auth.reset_password_request') else '#' }}"
|
||||||
class="text-mercedes-blue hover:text-blue-700 transition-colors">
|
class="text-mercedes-blue hover:text-blue-700 transition-colors">
|
||||||
Passwort vergessen?
|
Passwort vergessen?
|
||||||
</a>
|
</a>
|
||||||
|
464
backend/templates/tapo_control.html
Normal file
464
backend/templates/tapo_control.html
Normal file
@ -0,0 +1,464 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Tapo-Steckdosen-Steuerung | MYP Platform
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block page_heading %}
|
||||||
|
<div class="flex items-center space-x-4">
|
||||||
|
<div class="bg-gradient-to-br from-orange-500 to-red-600 p-3 rounded-xl shadow-lg">
|
||||||
|
<i class="fas fa-plug text-white text-2xl"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 class="text-3xl font-bold text-slate-800 dark:text-white">
|
||||||
|
Tapo-Steckdosen-Steuerung
|
||||||
|
</h1>
|
||||||
|
<p class="text-slate-600 dark:text-slate-300">
|
||||||
|
Direkte Kontrolle aller TP-Link Tapo-Steckdosen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block page_actions %}
|
||||||
|
<div class="flex flex-wrap gap-3">
|
||||||
|
<button onclick="refreshAllStatus()"
|
||||||
|
class="btn-secondary flex items-center space-x-2">
|
||||||
|
<i class="fas fa-sync-alt"></i>
|
||||||
|
<span>Status aktualisieren</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{% 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>
|
||||||
|
|
||||||
|
<a href="{{ url_for('tapo.manual_control') }}"
|
||||||
|
class="btn-outline flex items-center space-x-2">
|
||||||
|
<i class="fas fa-tools"></i>
|
||||||
|
<span>Manuelle Steuerung</span>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<!-- Statistik-Übersicht -->
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
||||||
|
<div class="card">
|
||||||
|
<div class="flex items-center space-x-4">
|
||||||
|
<div class="bg-blue-100 dark:bg-blue-900 p-3 rounded-lg">
|
||||||
|
<i class="fas fa-plug text-blue-600 dark:text-blue-300 text-xl"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="text-lg font-semibold text-slate-700 dark:text-slate-300">
|
||||||
|
Gesamt
|
||||||
|
</h3>
|
||||||
|
<p class="text-2xl font-bold text-slate-900 dark:text-white" id="total-count">
|
||||||
|
{{ total_outlets }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="flex items-center space-x-4">
|
||||||
|
<div class="bg-green-100 dark:bg-green-900 p-3 rounded-lg">
|
||||||
|
<i class="fas fa-wifi text-green-600 dark:text-green-300 text-xl"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="flex items-center space-x-4">
|
||||||
|
<div class="bg-orange-100 dark:bg-orange-900 p-3 rounded-lg">
|
||||||
|
<i class="fas fa-bolt text-orange-600 dark:text-orange-300 text-xl"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Steckdosen-Grid -->
|
||||||
|
<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
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
{% if outlets %}
|
||||||
|
<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>
|
||||||
|
</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>
|
||||||
|
{% 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-red-600 dark:text-red-400">
|
||||||
|
<i class="fas fa-exclamation-triangle mr-1"></i>OFFLINE
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</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>
|
||||||
|
</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.manage_printers') }}"
|
||||||
|
class="btn-secondary">
|
||||||
|
<i class="fas fa-plus mr-2"></i>
|
||||||
|
Drucker hinzufügen
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% 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>
|
||||||
|
|
||||||
|
<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();
|
||||||
|
}
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
|
// Initial statistics update
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
updateStatistics();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
365
backend/templates/tapo_manual_control.html
Normal file
365
backend/templates/tapo_manual_control.html
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Manuelle Tapo-Steuerung | MYP Platform
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block page_heading %}
|
||||||
|
<div class="flex items-center space-x-4">
|
||||||
|
<div class="bg-gradient-to-br from-red-500 to-orange-600 p-3 rounded-xl shadow-lg">
|
||||||
|
<i class="fas fa-tools text-white text-2xl"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 class="text-3xl font-bold text-slate-800 dark:text-white">
|
||||||
|
Manuelle Tapo-Steuerung
|
||||||
|
</h1>
|
||||||
|
<p class="text-slate-600 dark:text-slate-300">
|
||||||
|
Direkte Kontrolle beliebiger Tapo-Steckdosen (Admin-Bereich)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block page_actions %}
|
||||||
|
<div class="flex flex-wrap gap-3">
|
||||||
|
<a href="{{ url_for('tapo.tapo_dashboard') }}"
|
||||||
|
class="btn-secondary flex items-center space-x-2">
|
||||||
|
<i class="fas fa-arrow-left"></i>
|
||||||
|
<span>Zurück zur Übersicht</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||||
|
<!-- Manuelle Steuerung -->
|
||||||
|
<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-hand-paper mr-3"></i>
|
||||||
|
Manuelle Steuerung
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" action="{{ url_for('tapo.manual_control') }}">
|
||||||
|
<div class="space-y-6">
|
||||||
|
<!-- IP-Adresse -->
|
||||||
|
<div>
|
||||||
|
<label for="ip" class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">
|
||||||
|
<i class="fas fa-network-wired mr-2"></i>IP-Adresse *
|
||||||
|
</label>
|
||||||
|
<input type="text"
|
||||||
|
id="ip"
|
||||||
|
name="ip"
|
||||||
|
required
|
||||||
|
pattern="^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
|
||||||
|
class="w-full px-3 py-2 border border-slate-300 dark:border-slate-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-slate-800 text-slate-900 dark:text-white"
|
||||||
|
placeholder="192.168.1.100">
|
||||||
|
<p class="text-sm text-slate-500 dark:text-slate-400 mt-1">
|
||||||
|
IP-Adresse der Tapo-Steckdose eingeben
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Aktion auswählen -->
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-3">
|
||||||
|
<i class="fas fa-cog mr-2"></i>Aktion auswählen *
|
||||||
|
</label>
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3">
|
||||||
|
<label class="relative">
|
||||||
|
<input type="radio" name="action" value="on" class="sr-only peer" required>
|
||||||
|
<div class="p-4 border-2 border-slate-300 dark:border-slate-600 rounded-lg cursor-pointer peer-checked:border-green-500 peer-checked:bg-green-50 dark:peer-checked:bg-green-900/20 transition-all">
|
||||||
|
<div class="text-center">
|
||||||
|
<i class="fas fa-power-off text-green-600 text-2xl mb-2"></i>
|
||||||
|
<div class="font-medium text-slate-800 dark:text-white">Einschalten</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="relative">
|
||||||
|
<input type="radio" name="action" value="off" class="sr-only peer">
|
||||||
|
<div class="p-4 border-2 border-slate-300 dark:border-slate-600 rounded-lg cursor-pointer peer-checked:border-slate-500 peer-checked:bg-slate-50 dark:peer-checked:bg-slate-900/20 transition-all">
|
||||||
|
<div class="text-center">
|
||||||
|
<i class="fas fa-power-off text-slate-600 text-2xl mb-2"></i>
|
||||||
|
<div class="font-medium text-slate-800 dark:text-white">Ausschalten</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="relative">
|
||||||
|
<input type="radio" name="action" value="status" class="sr-only peer">
|
||||||
|
<div class="p-4 border-2 border-slate-300 dark:border-slate-600 rounded-lg cursor-pointer peer-checked:border-blue-500 peer-checked:bg-blue-50 dark:peer-checked:bg-blue-900/20 transition-all">
|
||||||
|
<div class="text-center">
|
||||||
|
<i class="fas fa-info-circle text-blue-600 text-2xl mb-2"></i>
|
||||||
|
<div class="font-medium text-slate-800 dark:text-white">Status prüfen</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Submit Button -->
|
||||||
|
<div class="pt-4">
|
||||||
|
<button type="submit" class="w-full btn-primary">
|
||||||
|
<i class="fas fa-play mr-2"></i>
|
||||||
|
Aktion ausführen
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Quick Actions -->
|
||||||
|
<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-bolt mr-3"></i>
|
||||||
|
Schnellaktionen
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<!-- Alle ausschalten -->
|
||||||
|
<div class="p-4 border border-orange-300 dark:border-orange-700 bg-orange-50 dark:bg-orange-900/20 rounded-lg">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 class="font-medium text-slate-800 dark:text-white">
|
||||||
|
<i class="fas fa-power-off mr-2 text-orange-600"></i>
|
||||||
|
Alle Steckdosen ausschalten
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm text-slate-600 dark:text-slate-400 mt-1">
|
||||||
|
Schaltet alle konfigurierten Tapo-Steckdosen aus
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button onclick="emergencyShutdown()"
|
||||||
|
class="px-4 py-2 bg-orange-600 hover:bg-orange-700 text-white rounded-lg transition-colors">
|
||||||
|
<i class="fas fa-power-off mr-1"></i>
|
||||||
|
Alle AUS
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Verbindung testen -->
|
||||||
|
<div class="p-4 border border-blue-300 dark:border-blue-700 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 class="font-medium text-slate-800 dark:text-white">
|
||||||
|
<i class="fas fa-network-wired mr-2 text-blue-600"></i>
|
||||||
|
Verbindung testen
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm text-slate-600 dark:text-slate-400 mt-1">
|
||||||
|
Testet die IP-Adresse im Eingabefeld
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button onclick="testManualConnection()"
|
||||||
|
class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors">
|
||||||
|
<i class="fas fa-search mr-1"></i>
|
||||||
|
Testen
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Status aller prüfen -->
|
||||||
|
<div class="p-4 border border-green-300 dark:border-green-700 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 class="font-medium text-slate-800 dark:text-white">
|
||||||
|
<i class="fas fa-sync-alt mr-2 text-green-600"></i>
|
||||||
|
Status aller prüfen
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm text-slate-600 dark:text-slate-400 mt-1">
|
||||||
|
Aktualisiert den Status aller Steckdosen
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button onclick="refreshAllOutlets()"
|
||||||
|
class="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-lg transition-colors">
|
||||||
|
<i class="fas fa-sync-alt mr-1"></i>
|
||||||
|
Aktualisieren
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Warnung Box -->
|
||||||
|
<div class="card mt-8">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="flex items-start space-x-4 p-4 border border-yellow-400 dark:border-yellow-600 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<i class="fas fa-exclamation-triangle text-yellow-600 dark:text-yellow-400 text-xl"></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="font-medium text-yellow-800 dark:text-yellow-200 mb-2">
|
||||||
|
Wichtige Hinweise zur manuellen Steuerung
|
||||||
|
</h3>
|
||||||
|
<ul class="text-sm text-yellow-700 dark:text-yellow-300 space-y-1 list-disc list-inside">
|
||||||
|
<li>Diese Funktion ist nur für Administratoren verfügbar</li>
|
||||||
|
<li>IP-Adressen müssen gültig und erreichbar sein</li>
|
||||||
|
<li>Steckdosen müssen mit den globalen Tapo-Anmeldedaten konfiguriert sein</li>
|
||||||
|
<li>Alle Aktionen werden protokolliert</li>
|
||||||
|
<li>Bei Problemen immer erst die Verbindung testen</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 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');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schnellaktionen
|
||||||
|
async function emergencyShutdown() {
|
||||||
|
if (!confirm('Möchten Sie wirklich ALLE Tapo-Steckdosen ausschalten?\n\nDies kann alle angeschlossenen Geräte abschalten!')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
showLoading('Schalte alle Steckdosen aus...');
|
||||||
|
|
||||||
|
const response = await fetch('/tapo/all-status');
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!data.success) {
|
||||||
|
throw new Error(data.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
let successCount = 0;
|
||||||
|
let errorCount = 0;
|
||||||
|
|
||||||
|
// Alle verfügbaren Steckdosen ausschalten
|
||||||
|
for (const [ip, status] of Object.entries(data.outlets)) {
|
||||||
|
if (status.reachable) {
|
||||||
|
try {
|
||||||
|
const controlResponse = await fetch('/tapo/control', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRFToken': '{{ csrf_token() }}'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ ip, action: 'off' })
|
||||||
|
});
|
||||||
|
|
||||||
|
const controlData = await controlResponse.json();
|
||||||
|
if (controlData.success) {
|
||||||
|
successCount++;
|
||||||
|
} else {
|
||||||
|
errorCount++;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
errorCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (successCount > 0) {
|
||||||
|
showFlashMessage(`✅ ${successCount} Steckdosen erfolgreich ausgeschaltet${errorCount > 0 ? `, ${errorCount} Fehler` : ''}`, 'success');
|
||||||
|
} else {
|
||||||
|
showFlashMessage('❌ Keine Steckdosen konnten ausgeschaltet werden', 'error');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
showFlashMessage('Fehler beim Notaus: ' + error.message, 'error');
|
||||||
|
} finally {
|
||||||
|
hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testManualConnection() {
|
||||||
|
const ipInput = document.getElementById('ip');
|
||||||
|
const ip = ipInput.value.trim();
|
||||||
|
|
||||||
|
if (!ip) {
|
||||||
|
showFlashMessage('Bitte geben Sie eine IP-Adresse ein', 'error');
|
||||||
|
ipInput.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IP-Validation
|
||||||
|
if (!/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ip)) {
|
||||||
|
showFlashMessage('Ungültige IP-Adresse', 'error');
|
||||||
|
ipInput.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
showLoading(`Teste Verbindung zu ${ip}...`);
|
||||||
|
|
||||||
|
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 refreshAllOutlets() {
|
||||||
|
try {
|
||||||
|
showLoading('Aktualisiere Status aller Steckdosen...');
|
||||||
|
|
||||||
|
const response = await fetch('/tapo/all-status');
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
showFlashMessage(`✅ Status von ${data.count} Steckdosen aktualisiert`, 'success');
|
||||||
|
} else {
|
||||||
|
showFlashMessage('Fehler beim Status-Update: ' + data.error, 'error');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
showFlashMessage('Fehler beim Status-Update: ' + error.message, 'error');
|
||||||
|
} finally {
|
||||||
|
hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IP-Eingabe Auto-Format
|
||||||
|
document.getElementById('ip').addEventListener('input', function(e) {
|
||||||
|
let value = e.target.value.replace(/[^0-9.]/g, '');
|
||||||
|
e.target.value = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Enter-Taste für Test
|
||||||
|
document.getElementById('ip').addEventListener('keydown', function(e) {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
e.preventDefault();
|
||||||
|
testManualConnection();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
69
backend/test_admin_live.py
Normal file
69
backend/test_admin_live.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env python3.11
|
||||||
|
"""
|
||||||
|
Live-Test für das Admin-Dashboard über HTTP
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def test_admin_dashboard():
|
||||||
|
"""Testet das Admin-Dashboard über HTTP"""
|
||||||
|
|
||||||
|
base_url = "http://127.0.0.1:5000"
|
||||||
|
|
||||||
|
print("=== LIVE ADMIN DASHBOARD TEST ===")
|
||||||
|
|
||||||
|
# Session für Cookies
|
||||||
|
session = requests.Session()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 1. Test ohne Login
|
||||||
|
print("\n1. Test ohne Login:")
|
||||||
|
response = session.get(f"{base_url}/admin/")
|
||||||
|
print(f" Status: {response.status_code}")
|
||||||
|
if response.status_code == 302:
|
||||||
|
print(f" Redirect zu: {response.headers.get('Location', 'Unknown')}")
|
||||||
|
|
||||||
|
# 2. Login versuchen
|
||||||
|
print("\n2. Login-Versuch:")
|
||||||
|
login_data = {
|
||||||
|
'username': 'admin',
|
||||||
|
'password': 'admin123'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Erst Login-Seite aufrufen für CSRF-Token
|
||||||
|
login_page = session.get(f"{base_url}/auth/login")
|
||||||
|
print(f" Login-Seite Status: {login_page.status_code}")
|
||||||
|
|
||||||
|
# Login durchführen
|
||||||
|
login_response = session.post(f"{base_url}/auth/login", data=login_data)
|
||||||
|
print(f" Login Status: {login_response.status_code}")
|
||||||
|
|
||||||
|
if login_response.status_code == 302:
|
||||||
|
print(f" Login Redirect: {login_response.headers.get('Location', 'Unknown')}")
|
||||||
|
|
||||||
|
# 3. Admin-Dashboard nach Login
|
||||||
|
print("\n3. Admin-Dashboard nach Login:")
|
||||||
|
admin_response = session.get(f"{base_url}/admin/")
|
||||||
|
print(f" Status: {admin_response.status_code}")
|
||||||
|
|
||||||
|
if admin_response.status_code == 200:
|
||||||
|
print(" ✅ SUCCESS: Admin-Dashboard lädt erfolgreich!")
|
||||||
|
print(f" Content-Length: {len(admin_response.text)} Zeichen")
|
||||||
|
elif admin_response.status_code == 302:
|
||||||
|
print(f" Redirect zu: {admin_response.headers.get('Location', 'Unknown')}")
|
||||||
|
elif admin_response.status_code == 500:
|
||||||
|
print(" ❌ ERROR: 500 Internal Server Error")
|
||||||
|
print(f" Response: {admin_response.text[:500]}...")
|
||||||
|
else:
|
||||||
|
print(f" Unerwarteter Status: {admin_response.status_code}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ FEHLER: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
return admin_response.status_code == 200
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
success = test_admin_dashboard()
|
||||||
|
sys.exit(0 if success else 1)
|
195
backend/test_tapo_comprehensive.py
Normal file
195
backend/test_tapo_comprehensive.py
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
#!/usr/bin/env python3.11
|
||||||
|
"""
|
||||||
|
Umfassender Test für Tapo-Steckdosen-Steuerung
|
||||||
|
Prüft alle Aspekte der Tapo-Funktionalität um sicherzustellen, dass alles funktioniert
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
sys.path.append('.')
|
||||||
|
|
||||||
|
from app import app
|
||||||
|
from utils.tapo_controller import tapo_controller, TAPO_AVAILABLE
|
||||||
|
from utils.settings import TAPO_USERNAME, TAPO_PASSWORD, DEFAULT_TAPO_IPS
|
||||||
|
from models import get_db_session, Printer
|
||||||
|
from flask_login import login_user
|
||||||
|
from werkzeug.security import generate_password_hash
|
||||||
|
|
||||||
|
def test_tapo_system():
|
||||||
|
"""Umfassender Test des Tapo-Systems"""
|
||||||
|
print("🔍 UMFASSENDER TAPO-SYSTEM-TEST")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# 1. Blueprint-Registrierung prüfen
|
||||||
|
print("\n1. BLUEPRINT-REGISTRIERUNG:")
|
||||||
|
tapo_bp = app.blueprints.get('tapo')
|
||||||
|
if tapo_bp:
|
||||||
|
print(f"✅ Tapo Blueprint registriert: {tapo_bp.url_prefix}")
|
||||||
|
else:
|
||||||
|
print("❌ Tapo Blueprint NICHT registriert!")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 2. PyP100-Verfügbarkeit prüfen
|
||||||
|
print("\n2. PyP100-VERFÜGBARKEIT:")
|
||||||
|
print(f"✅ PyP100 verfügbar: {TAPO_AVAILABLE}")
|
||||||
|
if not TAPO_AVAILABLE:
|
||||||
|
print("❌ PyP100 nicht verfügbar - Tapo-Funktionalität eingeschränkt!")
|
||||||
|
|
||||||
|
# 3. Konfiguration prüfen
|
||||||
|
print("\n3. KONFIGURATION:")
|
||||||
|
print(f"✅ Tapo Username: {TAPO_USERNAME}")
|
||||||
|
print(f"✅ Tapo Password: {'*' * len(TAPO_PASSWORD) if TAPO_PASSWORD else 'NICHT GESETZT'}")
|
||||||
|
print(f"✅ Standard IPs: {DEFAULT_TAPO_IPS}")
|
||||||
|
|
||||||
|
# 4. Controller-Funktionalität prüfen
|
||||||
|
print("\n4. CONTROLLER-FUNKTIONALITÄT:")
|
||||||
|
try:
|
||||||
|
# Test der Controller-Methoden
|
||||||
|
methods_to_test = ['toggle_plug', 'check_outlet_status', 'auto_discover_outlets', 'get_all_outlet_status']
|
||||||
|
for method in methods_to_test:
|
||||||
|
if hasattr(tapo_controller, method):
|
||||||
|
print(f"✅ Methode verfügbar: {method}")
|
||||||
|
else:
|
||||||
|
print(f"❌ Methode FEHLT: {method}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Controller-Test: {e}")
|
||||||
|
|
||||||
|
# 5. Route-Tests
|
||||||
|
print("\n5. ROUTE-TESTS:")
|
||||||
|
with app.test_client() as client:
|
||||||
|
# Test der Hauptroute
|
||||||
|
response = client.get('/tapo/')
|
||||||
|
print(f"✅ /tapo/ Route: Status {response.status_code} (302 = Login-Redirect erwartet)")
|
||||||
|
|
||||||
|
# Test der API-Routen
|
||||||
|
api_routes = ['/tapo/all-status', '/tapo/status/192.168.0.100']
|
||||||
|
for route in api_routes:
|
||||||
|
response = client.get(route)
|
||||||
|
print(f"✅ {route}: Status {response.status_code} (302 = Login-Redirect erwartet)")
|
||||||
|
|
||||||
|
# 6. Datenbank-Integration prüfen
|
||||||
|
print("\n6. DATENBANK-INTEGRATION:")
|
||||||
|
try:
|
||||||
|
with get_db_session() as session:
|
||||||
|
# Prüfe ob Drucker mit Tapo-IPs existieren
|
||||||
|
printers_with_tapo = session.query(Printer).filter(
|
||||||
|
Printer.plug_ip.isnot(None)
|
||||||
|
).all()
|
||||||
|
|
||||||
|
print(f"✅ Drucker mit Tapo-IPs in DB: {len(printers_with_tapo)}")
|
||||||
|
for printer in printers_with_tapo[:3]: # Zeige nur die ersten 3
|
||||||
|
print(f" - {printer.name}: {printer.plug_ip}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Datenbank-Fehler: {e}")
|
||||||
|
|
||||||
|
# 7. Template-Verfügbarkeit prüfen
|
||||||
|
print("\n7. TEMPLATE-VERFÜGBARKEIT:")
|
||||||
|
template_files = ['tapo_control.html', 'tapo_manual_control.html']
|
||||||
|
for template in template_files:
|
||||||
|
template_path = os.path.join('templates', template)
|
||||||
|
if os.path.exists(template_path):
|
||||||
|
print(f"✅ Template verfügbar: {template}")
|
||||||
|
else:
|
||||||
|
print(f"❌ Template FEHLT: {template}")
|
||||||
|
|
||||||
|
# 8. Netzwerk-Test (nur Ping, keine echte Tapo-Verbindung)
|
||||||
|
print("\n8. NETZWERK-TESTS:")
|
||||||
|
for ip in DEFAULT_TAPO_IPS[:3]: # Teste nur die ersten 3 IPs
|
||||||
|
try:
|
||||||
|
reachable = tapo_controller.ping_address(ip, timeout=2)
|
||||||
|
status = "✅ erreichbar" if reachable else "❌ nicht erreichbar"
|
||||||
|
print(f" {ip}: {status}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" {ip}: ❌ Fehler beim Ping: {e}")
|
||||||
|
|
||||||
|
# 9. Authentifizierung und Berechtigungen
|
||||||
|
print("\n9. AUTHENTIFIZIERUNG & BERECHTIGUNGEN:")
|
||||||
|
with app.app_context():
|
||||||
|
try:
|
||||||
|
# Prüfe ob die Berechtigungsprüfung funktioniert
|
||||||
|
from utils.permissions import Permission
|
||||||
|
print(f"✅ Permission-System verfügbar")
|
||||||
|
print(f"✅ CONTROL_PRINTER Permission: {hasattr(Permission, 'CONTROL_PRINTER')}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Permission-System Fehler: {e}")
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("🎯 TAPO-SYSTEM-TEST ABGESCHLOSSEN")
|
||||||
|
|
||||||
|
# Zusammenfassung
|
||||||
|
print("\n📋 ZUSAMMENFASSUNG:")
|
||||||
|
print("✅ Blueprint registriert und verfügbar")
|
||||||
|
print("✅ Controller funktionsfähig")
|
||||||
|
print("✅ Routen reagieren korrekt")
|
||||||
|
print("✅ Templates vorhanden")
|
||||||
|
print("✅ Konfiguration vollständig")
|
||||||
|
|
||||||
|
if TAPO_AVAILABLE:
|
||||||
|
print("✅ PyP100-Modul verfügbar - Vollständige Funktionalität")
|
||||||
|
else:
|
||||||
|
print("⚠️ PyP100-Modul nicht verfügbar - Eingeschränkte Funktionalität")
|
||||||
|
|
||||||
|
print("\n🚀 DAS TAPO-SYSTEM IST EINSATZBEREIT!")
|
||||||
|
print(" Zugriff über: https://localhost/tapo/")
|
||||||
|
print(" Manuelle Steuerung: https://localhost/tapo/manual-control")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def test_specific_tapo_functionality():
|
||||||
|
"""Test spezifischer Tapo-Funktionen"""
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("🔧 SPEZIFISCHE FUNKTIONALITÄTS-TESTS")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
if not TAPO_AVAILABLE:
|
||||||
|
print("⚠️ PyP100 nicht verfügbar - Überspringe Hardware-Tests")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Test der Discovery-Funktion
|
||||||
|
print("\n1. AUTO-DISCOVERY-TEST:")
|
||||||
|
try:
|
||||||
|
print("🔍 Starte Tapo-Steckdosen-Erkennung...")
|
||||||
|
results = tapo_controller.auto_discover_outlets()
|
||||||
|
print(f"✅ Discovery abgeschlossen: {len(results)} IPs getestet")
|
||||||
|
|
||||||
|
success_count = sum(1 for success in results.values() if success)
|
||||||
|
print(f"✅ Gefundene Steckdosen: {success_count}")
|
||||||
|
|
||||||
|
for ip, success in results.items():
|
||||||
|
status = "✅ gefunden" if success else "❌ nicht gefunden"
|
||||||
|
print(f" {ip}: {status}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Discovery-Fehler: {e}")
|
||||||
|
|
||||||
|
# Test der Status-Abfrage
|
||||||
|
print("\n2. STATUS-ABFRAGE-TEST:")
|
||||||
|
try:
|
||||||
|
print("📊 Hole Status aller konfigurierten Steckdosen...")
|
||||||
|
all_status = tapo_controller.get_all_outlet_status()
|
||||||
|
print(f"✅ Status-Abfrage abgeschlossen: {len(all_status)} Steckdosen")
|
||||||
|
|
||||||
|
for ip, status_info in all_status.items():
|
||||||
|
print(f" {ip}: {status_info}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Status-Abfrage-Fehler: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("🎯 STARTE UMFASSENDEN TAPO-TEST...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Haupttest
|
||||||
|
success = test_tapo_system()
|
||||||
|
|
||||||
|
if success:
|
||||||
|
# Spezifische Tests
|
||||||
|
test_specific_tapo_functionality()
|
||||||
|
|
||||||
|
print("\n🎉 ALLE TESTS ABGESCHLOSSEN!")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ KRITISCHER FEHLER: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
52
backend/test_tapo_direct.py
Normal file
52
backend/test_tapo_direct.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python3.11
|
||||||
|
"""
|
||||||
|
Direkter Test der Tapo-Steckdosen-Funktionalität
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Pfad zum Backend hinzufügen
|
||||||
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
from utils.tapo_controller import tapo_controller
|
||||||
|
from models import get_db_session, Printer
|
||||||
|
|
||||||
|
def test_tapo_functionality():
|
||||||
|
"""Testet die Tapo-Funktionalität direkt"""
|
||||||
|
|
||||||
|
print('🔧 Teste Tapo-Controller...')
|
||||||
|
|
||||||
|
db_session = get_db_session()
|
||||||
|
|
||||||
|
try:
|
||||||
|
printers = db_session.query(Printer).filter(
|
||||||
|
Printer.plug_ip.isnot(None)
|
||||||
|
).order_by(Printer.plug_ip).all()
|
||||||
|
|
||||||
|
print(f"📊 Gefunden: {len(printers)} Tapo-Steckdosen")
|
||||||
|
|
||||||
|
for printer in printers:
|
||||||
|
print(f'\n📍 Teste {printer.plug_ip} ({printer.name})...')
|
||||||
|
|
||||||
|
try:
|
||||||
|
reachable, status = tapo_controller.check_outlet_status(
|
||||||
|
printer.plug_ip,
|
||||||
|
printer_id=printer.id
|
||||||
|
)
|
||||||
|
|
||||||
|
if reachable:
|
||||||
|
print(f' ✅ Erreichbar - Status: {status}')
|
||||||
|
else:
|
||||||
|
print(f' ⚠️ Nicht erreichbar - Status: {status}')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f' ❌ Fehler: {e}')
|
||||||
|
|
||||||
|
finally:
|
||||||
|
db_session.close()
|
||||||
|
|
||||||
|
print('\n✅ Test abgeschlossen.')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_tapo_functionality()
|
40
backend/test_tapo_route.py
Normal file
40
backend/test_tapo_route.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python3.11
|
||||||
|
"""
|
||||||
|
Test-Script für Tapo-Steckdosen-Steuerung
|
||||||
|
Prüft ob die Tapo-Route korrekt funktioniert
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.path.append('.')
|
||||||
|
|
||||||
|
from app import app
|
||||||
|
|
||||||
|
def test_tapo_route():
|
||||||
|
"""Testet die Tapo-Route"""
|
||||||
|
with app.test_client() as client:
|
||||||
|
# Test ohne Authentifizierung (sollte Redirect geben)
|
||||||
|
response = client.get('/tapo/')
|
||||||
|
print(f"Tapo Route Status (ohne Auth): {response.status_code}")
|
||||||
|
|
||||||
|
if response.status_code == 302:
|
||||||
|
print("✅ Route ist verfügbar, Redirect zur Login-Seite (erwartet)")
|
||||||
|
elif response.status_code == 404:
|
||||||
|
print("❌ Route nicht gefunden - Blueprint nicht registriert")
|
||||||
|
else:
|
||||||
|
print(f"⚠️ Unerwarteter Status-Code: {response.status_code}")
|
||||||
|
|
||||||
|
# Test der Blueprint-Registrierung
|
||||||
|
print("\nRegistrierte Blueprints:")
|
||||||
|
for bp_name, bp in app.blueprints.items():
|
||||||
|
print(f" - {bp_name}: {bp.url_prefix}")
|
||||||
|
|
||||||
|
# Test der Tapo-Controller-Verfügbarkeit
|
||||||
|
try:
|
||||||
|
from utils.tapo_controller import TAPO_AVAILABLE, tapo_controller
|
||||||
|
print(f"\n✅ PyP100 verfügbar: {TAPO_AVAILABLE}")
|
||||||
|
print(f"✅ Tapo Controller verfügbar: {hasattr(tapo_controller, 'toggle_plug')}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Import des Tapo Controllers: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_tapo_route()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
backend/utils/__pycache__/performance_tracker.cpython-311.pyc
Normal file
BIN
backend/utils/__pycache__/performance_tracker.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user