diff --git a/backend/app.py b/backend/app.py index 54612e0c8..fe4fd0e5f 100644 --- a/backend/app.py +++ b/backend/app.py @@ -691,6 +691,16 @@ def inject_now(): """Injiziert die aktuelle Zeit in alle Templates""" return {'now': datetime.now} +@app.context_processor +def inject_current_route(): + """ + Stellt current_route für alle Templates bereit. + + Verhindert Template-Fehler wenn request.endpoint None ist (z.B. bei 404-Fehlern). + """ + current_route = getattr(request, 'endpoint', None) or '' + return {'current_route': current_route} + @app.template_filter('format_datetime') def format_datetime_filter(value, format='%d.%m.%Y %H:%M'): """Template-Filter für Datums-Formatierung""" @@ -1093,7 +1103,8 @@ def api_stats(): try: from models import get_db_session, User, Printer, Job - with get_cached_session() as db_session: + db_session = get_db_session() + try: # Grundlegende Counts total_users = db_session.query(User).count() total_printers = db_session.query(Printer).count() @@ -1116,6 +1127,8 @@ def api_stats(): online_printers = db_session.query(Printer).filter( Printer.active == True ).count() + finally: + db_session.close() stats = { 'total_users': total_users, @@ -1199,7 +1212,13 @@ def forbidden_error(error): "message": "Sie haben keine Berechtigung für diese Aktion", "status_code": 403 }), 403 - return render_template('errors/403.html'), 403 + + try: + return render_template('errors/403.html'), 403 + except Exception as template_error: + # Fallback bei Template-Fehlern + app_logger.error(f"Template-Fehler in 403-Handler: {str(template_error)}") + return f"
Sie haben keine Berechtigung für diese Aktion.
", 403 @app.errorhandler(404) def not_found_error(error): @@ -1211,7 +1230,13 @@ def not_found_error(error): "message": "Die angeforderte Ressource wurde nicht gefunden", "status_code": 404 }), 404 - return render_template('errors/404.html'), 404 + + try: + return render_template('errors/404.html'), 404 + except Exception as template_error: + # Fallback bei Template-Fehlern + app_logger.error(f"Template-Fehler in 404-Handler: {str(template_error)}") + return f"Die angeforderte Seite wurde nicht gefunden.
", 404 @app.errorhandler(405) def method_not_allowed_error(error): @@ -1271,7 +1296,12 @@ def internal_error(error): "status_code": 500 }), 500 - return render_template('errors/500.html', error_id=error_id), 500 + try: + return render_template('errors/500.html', error_id=error_id), 500 + except Exception as template_error: + # Fallback bei Template-Fehlern + app_logger.error(f"Template-Fehler in 500-Handler: {str(template_error)}") + return f"Ein unerwarteter Fehler ist aufgetreten. Fehler-ID: {error_id}
", 500 @app.errorhandler(502) def bad_gateway_error(error): @@ -1338,7 +1368,12 @@ def handle_exception(error): "status_code": 500 }), 500 - return render_template('errors/500.html', error_id=error_id), 500 + try: + return render_template('errors/500.html', error_id=error_id), 500 + except Exception as template_error: + # Fallback bei Template-Fehlern + app_logger.error(f"Template-Fehler im Exception-Handler: {str(template_error)}") + return f"Ein unerwarteter Fehler ist aufgetreten. Fehler-ID: {error_id}
", 500 # ===== HAUPTFUNKTION ===== def main(): @@ -1506,5 +1541,17 @@ def production_info(): """Stellt Production-Informationen für Templates bereit""" return get_production_info() +# Nach der Initialisierung der Blueprints und vor dem App-Start +try: + # Admin-Berechtigungen beim Start korrigieren + from utils.permissions import fix_all_admin_permissions + result = fix_all_admin_permissions() + if result['success']: + app_logger.info(f"Admin-Berechtigungen beim Start korrigiert: {result['created']} erstellt, {result['corrected']} aktualisiert") + else: + app_logger.warning(f"Fehler beim Korrigieren der Admin-Berechtigungen: {result.get('error', 'Unbekannter Fehler')}") +except Exception as e: + app_logger.error(f"Fehler beim Korrigieren der Admin-Berechtigungen beim Start: {str(e)}") + if __name__ == "__main__": main() \ No newline at end of file diff --git a/backend/backend/database/myp.db b/backend/backend/database/myp.db index e9ce12da7..60d10e0a1 100644 Binary files a/backend/backend/database/myp.db and b/backend/backend/database/myp.db differ diff --git a/backend/blueprints/__pycache__/admin_unified.cpython-313.pyc b/backend/blueprints/__pycache__/admin_unified.cpython-313.pyc index 01a1a6a5c..4d80a3e4f 100644 Binary files a/backend/blueprints/__pycache__/admin_unified.cpython-313.pyc and b/backend/blueprints/__pycache__/admin_unified.cpython-313.pyc differ diff --git a/backend/blueprints/__pycache__/api.cpython-313.pyc b/backend/blueprints/__pycache__/api.cpython-313.pyc index e284af6ee..e96193ad7 100644 Binary files a/backend/blueprints/__pycache__/api.cpython-313.pyc and b/backend/blueprints/__pycache__/api.cpython-313.pyc differ diff --git a/backend/blueprints/__pycache__/guest.cpython-313.pyc b/backend/blueprints/__pycache__/guest.cpython-313.pyc index 54da915b4..8b892b4b5 100644 Binary files a/backend/blueprints/__pycache__/guest.cpython-313.pyc and b/backend/blueprints/__pycache__/guest.cpython-313.pyc differ diff --git a/backend/blueprints/__pycache__/printers.cpython-313.pyc b/backend/blueprints/__pycache__/printers.cpython-313.pyc index 8386c32e0..31fed3585 100644 Binary files a/backend/blueprints/__pycache__/printers.cpython-313.pyc and b/backend/blueprints/__pycache__/printers.cpython-313.pyc differ diff --git a/backend/blueprints/admin_unified.py b/backend/blueprints/admin_unified.py index a126ccdcc..8faf52415 100644 --- a/backend/blueprints/admin_unified.py +++ b/backend/blueprints/admin_unified.py @@ -1823,4 +1823,656 @@ def get_status_color(status): 'disconnected': '#ef4444', # Rot 'unknown': '#6b7280' # Grau } - return status_colors.get(status, '#6b7280') \ No newline at end of file + return status_colors.get(status, '#6b7280') + +# ===== FEHLENDE API-ROUTEN HINZUFÜGEN ===== + +@admin_api_blueprint.route('/system-health', methods=['GET']) +@admin_required +def api_admin_system_health_alias(): + """ + Alias-Route für system-health (Kompatibilität mit Frontend). + + Leitet Anfragen an die bestehende system/health Route weiter. + """ + return api_admin_system_health() + +@admin_api_blueprint.route('/error-recovery/status', methods=['GET']) +@admin_required +def api_admin_error_recovery_status(): + """ + API-Endpunkt für Error-Recovery-Status. + + Gibt Informationen über das Error-Recovery-System zurück, + einschließlich Status, Statistiken und letzter Aktionen. + """ + try: + admin_api_logger.info(f"Error-Recovery-Status angefordert von {current_user.username}") + + # Error-Recovery-Basis-Status sammeln + recovery_status = { + 'enabled': True, # Error-Recovery ist standardmäßig aktiviert + 'last_check': datetime.now().isoformat(), + 'status': 'active', + 'errors_detected': 0, + 'errors_recovered': 0, + 'last_recovery_action': None, + 'monitoring_active': True, + 'recovery_methods': [ + 'automatic_restart', + 'service_health_check', + 'database_recovery', + 'cache_cleanup' + ] + } + + # Versuche Log-Informationen zu sammeln + try: + # Prüfe auf kürzliche Fehler in System-Logs + with get_cached_session() as db_session: + # Letzte Stunde nach Error-Logs suchen + last_hour = datetime.now() - timedelta(hours=1) + + error_logs = db_session.query(SystemLog).filter( + SystemLog.level == 'ERROR', + SystemLog.timestamp >= last_hour + ).count() + + recovery_logs = db_session.query(SystemLog).filter( + SystemLog.message.like('%Recovery%'), + SystemLog.timestamp >= last_hour + ).count() + + recovery_status['errors_detected'] = error_logs + recovery_status['errors_recovered'] = recovery_logs + + # Letzten Recovery-Eintrag finden + last_recovery = db_session.query(SystemLog).filter( + SystemLog.message.like('%Recovery%') + ).order_by(SystemLog.timestamp.desc()).first() + + if last_recovery: + recovery_status['last_recovery_action'] = { + 'timestamp': last_recovery.timestamp.isoformat(), + 'action': 'system_log_recovery', + 'message': last_recovery.message, + 'module': last_recovery.module + } + + except Exception as log_error: + admin_api_logger.warning(f"Log-Analyse für Error-Recovery fehlgeschlagen: {str(log_error)}") + recovery_status['errors_detected'] = 0 + recovery_status['errors_recovered'] = 0 + + # System-Load als Indikator für potenzielle Probleme + try: + import psutil + cpu_percent = psutil.cpu_percent(interval=1) + memory_percent = psutil.virtual_memory().percent + + # Hohe System-Last kann auf Probleme hindeuten + if cpu_percent > 80 or memory_percent > 85: + recovery_status['status'] = 'warning' + recovery_status['last_recovery_action'] = { + 'timestamp': datetime.now().isoformat(), + 'action': 'system_load_warning', + 'details': { + 'cpu_percent': cpu_percent, + 'memory_percent': memory_percent + } + } + + # System-Performance-Daten hinzufügen + recovery_status['system_performance'] = { + 'cpu_percent': cpu_percent, + 'memory_percent': memory_percent, + 'status': 'normal' if cpu_percent < 80 and memory_percent < 85 else 'high_load' + } + + except ImportError: + admin_api_logger.info("psutil nicht verfügbar für Error-Recovery-Monitoring") + recovery_status['system_performance'] = { + 'available': False, + 'message': 'psutil-Bibliothek nicht installiert' + } + except Exception as system_error: + admin_api_logger.warning(f"System-Load-Check für Error-Recovery fehlgeschlagen: {str(system_error)}") + recovery_status['system_performance'] = { + 'available': False, + 'error': str(system_error) + } + + # Datenbank-Gesundheit als Recovery-Indikator + try: + with get_cached_session() as db_session: + # Einfacher DB-Test + db_session.execute("SELECT 1") + recovery_status['database_health'] = 'healthy' + except Exception as db_error: + recovery_status['database_health'] = 'unhealthy' + recovery_status['status'] = 'critical' + admin_api_logger.error(f"Datenbank-Health-Check für Error-Recovery fehlgeschlagen: {str(db_error)}") + + admin_api_logger.info(f"Error-Recovery-Status abgerufen: {recovery_status['status']}") + + return jsonify({ + 'success': True, + 'error_recovery': recovery_status, + 'message': f"Error-Recovery-Status: {recovery_status['status']}" + }) + + except Exception as e: + admin_api_logger.error(f"Fehler beim Abrufen des Error-Recovery-Status: {str(e)}") + return jsonify({ + 'success': False, + 'error': 'Error-Recovery-Status nicht verfügbar', + 'details': str(e), + 'error_recovery': { + 'status': 'error', + 'enabled': False, + 'last_check': datetime.now().isoformat() + } + }), 500 + +# ===== ERWEITERTE TAPO-STECKDOSEN-VERWALTUNG ===== + +@admin_blueprint.route("/tapo-monitoring") +@admin_required +def tapo_monitoring(): + """ + Erweiterte Tapo-Steckdosen-Überwachung für Administratoren. + Bietet Real-Time-Monitoring aller Drucker-Steckdosen mit automatischer Überprüfung. + """ + admin_logger.info(f"Tapo-Monitoring aufgerufen von {current_user.username}") + + try: + with get_cached_session() as db_session: + # Alle Drucker mit konfigurierten Steckdosen laden + printers_with_plugs = db_session.query(Printer).filter( + Printer.plug_ip.isnot(None), + Printer.active == True + ).all() + + # Grundlegende Statistiken + total_printers = db_session.query(Printer).count() + printers_with_tapo = len(printers_with_plugs) + + # Aktueller Status aller Tapo-Steckdosen abrufen + try: + from utils.hardware_integration import tapo_controller + tapo_available = True + + # Status für jeden Drucker mit Tapo-Steckdose abrufen + printer_status = [] + online_count = 0 + offline_count = 0 + error_count = 0 + + for printer in printers_with_plugs: + try: + reachable, status = tapo_controller.check_outlet_status( + printer.plug_ip, + printer_id=printer.id + ) + + if reachable: + if status == 'on': + online_count += 1 + status_class = 'success' + else: + offline_count += 1 + status_class = 'secondary' + else: + error_count += 1 + status_class = 'danger' + status = 'unreachable' + + # Aktuelle Jobs für diesen Drucker prüfen + active_jobs = db_session.query(Job).filter( + Job.printer_id == printer.id, + Job.status.in_(['running', 'printing', 'active', 'scheduled']) + ).count() + + printer_info = { + 'id': printer.id, + 'name': printer.name, + 'model': printer.model, + 'location': printer.location, + 'plug_ip': printer.plug_ip, + 'plug_status': status, + 'plug_reachable': reachable, + 'status_class': status_class, + 'active_jobs': active_jobs, + 'last_checked': datetime.now(), + 'has_issues': not reachable or active_jobs > 0 + } + + printer_status.append(printer_info) + + except Exception as e: + admin_logger.error(f"Fehler beim Status-Check für {printer.name}: {str(e)}") + error_count += 1 + printer_status.append({ + 'id': printer.id, + 'name': printer.name, + 'model': printer.model, + 'location': printer.location, + 'plug_ip': printer.plug_ip, + 'plug_status': 'error', + 'plug_reachable': False, + 'status_class': 'danger', + 'active_jobs': 0, + 'last_checked': datetime.now(), + 'has_issues': True, + 'error': str(e) + }) + + except Exception as e: + admin_logger.error(f"Tapo-Controller nicht verfügbar: {str(e)}") + tapo_available = False + printer_status = [] + online_count = offline_count = error_count = 0 + + # Statistiken zusammenstellen + monitoring_stats = { + 'total_printers': total_printers, + 'printers_with_tapo': printers_with_tapo, + 'tapo_available': tapo_available, + 'online_count': online_count, + 'offline_count': offline_count, + 'error_count': error_count, + 'coverage_percentage': round((printers_with_tapo / total_printers * 100), 1) if total_printers > 0 else 0 + } + + admin_logger.info(f"Tapo-Monitoring geladen: {printers_with_tapo} Steckdosen, {online_count} online") + + return render_template('admin_tapo_monitoring.html', + printer_status=printer_status, + stats=monitoring_stats, + page_title="Tapo-Steckdosen-Monitoring", + breadcrumb=[ + {"name": "Admin-Dashboard", "url": url_for("admin.admin_dashboard")}, + {"name": "Tapo-Monitoring", "url": "#"} + ]) + + except Exception as e: + admin_logger.error(f"Fehler beim Laden des Tapo-Monitorings: {str(e)}") + flash("Fehler beim Laden der Tapo-Monitoring-Daten.", "error") + return redirect(url_for("admin.admin_dashboard")) + +@admin_api_blueprint.route('/tapo/bulk-control', methods=['POST']) +@admin_required +def api_admin_bulk_tapo_control(): + """ + API-Endpunkt für Massensteuerung von Tapo-Steckdosen. + Ermöglicht das gleichzeitige Ein-/Ausschalten mehrerer Steckdosen. + """ + admin_api_logger.info(f"Bulk-Tapo-Steuerung von {current_user.username}") + + try: + data = request.get_json() + action = data.get('action') # 'on', 'off', 'status' + printer_ids = data.get('printer_ids', []) + + if not action or not printer_ids: + return jsonify({ + 'success': False, + 'error': 'Aktion und Drucker-IDs sind erforderlich' + }), 400 + + if action not in ['on', 'off', 'status']: + return jsonify({ + 'success': False, + 'error': 'Ungültige Aktion. Erlaubt: on, off, status' + }), 400 + + # Tapo-Controller laden + try: + from utils.hardware_integration import tapo_controller + except Exception as e: + return jsonify({ + 'success': False, + 'error': f'Tapo-Controller nicht verfügbar: {str(e)}' + }), 500 + + results = [] + success_count = 0 + error_count = 0 + + with get_cached_session() as db_session: + for printer_id in printer_ids: + try: + printer = db_session.query(Printer).filter(Printer.id == printer_id).first() + + if not printer: + results.append({ + 'printer_id': printer_id, + 'success': False, + 'error': 'Drucker nicht gefunden' + }) + error_count += 1 + continue + + if not printer.plug_ip: + results.append({ + 'printer_id': printer_id, + 'printer_name': printer.name, + 'success': False, + 'error': 'Keine Steckdose konfiguriert' + }) + error_count += 1 + continue + + # Aktion ausführen + if action == 'status': + reachable, status = tapo_controller.check_outlet_status( + printer.plug_ip, + printer_id=printer_id + ) + results.append({ + 'printer_id': printer_id, + 'printer_name': printer.name, + 'success': True, + 'status': status, + 'reachable': reachable + }) + success_count += 1 + else: + # Ein- oder Ausschalten + state = action == 'on' + success = tapo_controller.toggle_plug(printer.plug_ip, state) + + if success: + # Drucker-Status in DB aktualisieren + printer.status = 'starting' if state else 'offline' + printer.last_checked = datetime.now() + + results.append({ + 'printer_id': printer_id, + 'printer_name': printer.name, + 'success': True, + 'action': action, + 'message': f'Steckdose erfolgreich {"ein" if state else "aus"}geschaltet' + }) + success_count += 1 + else: + results.append({ + 'printer_id': printer_id, + 'printer_name': printer.name, + 'success': False, + 'error': f'Steckdose konnte nicht {"ein" if state else "aus"}geschaltet werden' + }) + error_count += 1 + + except Exception as e: + admin_api_logger.error(f"Fehler bei Bulk-Steuerung für Drucker {printer_id}: {str(e)}") + results.append({ + 'printer_id': printer_id, + 'success': False, + 'error': str(e) + }) + error_count += 1 + + # Änderungen speichern + if action in ['on', 'off']: + db_session.commit() + + admin_api_logger.info(f"Bulk-Tapo-Steuerung abgeschlossen: {success_count} erfolgreich, {error_count} Fehler") + + return jsonify({ + 'success': True, + 'results': results, + 'summary': { + 'total': len(printer_ids), + 'success': success_count, + 'errors': error_count + }, + 'timestamp': datetime.now().isoformat() + }) + + except Exception as e: + admin_api_logger.error(f"Unerwarteter Fehler bei Bulk-Tapo-Steuerung: {str(e)}") + return jsonify({ + 'success': False, + 'error': f'Systemfehler: {str(e)}' + }), 500 + +@admin_api_blueprint.route('/tapo/health-check', methods=['POST']) +@admin_required +def api_admin_tapo_health_check(): + """ + Führt eine umfassende Gesundheitsüberprüfung aller Tapo-Steckdosen durch. + Testet Konnektivität, Authentifizierung und Funktionsfähigkeit. + """ + admin_api_logger.info(f"Tapo-Gesundheitscheck von {current_user.username}") + + try: + # Tapo-Controller laden + try: + from utils.hardware_integration import tapo_controller + tapo_available = True + except Exception as e: + return jsonify({ + 'success': False, + 'error': f'Tapo-Controller nicht verfügbar: {str(e)}', + 'tapo_available': False + }), 500 + + health_results = { + 'overall_status': 'healthy', + 'tapo_available': tapo_available, + 'timestamp': datetime.now().isoformat(), + 'printers': [], + 'summary': { + 'total': 0, + 'healthy': 0, + 'warning': 0, + 'critical': 0 + }, + 'recommendations': [] + } + + with get_cached_session() as db_session: + # Alle Drucker mit Steckdosen laden + printers_with_plugs = db_session.query(Printer).filter( + Printer.plug_ip.isnot(None) + ).all() + + health_results['summary']['total'] = len(printers_with_plugs) + + for printer in printers_with_plugs: + printer_health = { + 'id': printer.id, + 'name': printer.name, + 'plug_ip': printer.plug_ip, + 'status': 'unknown', + 'issues': [], + 'checks': { + 'connectivity': False, + 'authentication': False, + 'functionality': False + } + } + + try: + # Check 1: Konnektivität (Ping) + ping_success = tapo_controller.ping_address(printer.plug_ip, timeout=3) + printer_health['checks']['connectivity'] = ping_success + + if not ping_success: + printer_health['issues'].append('Netzwerkverbindung fehlgeschlagen') + + # Check 2: Authentifizierung und Geräteinformationen + if ping_success: + try: + test_result = tapo_controller.test_connection(printer.plug_ip) + printer_health['checks']['authentication'] = test_result['success'] + + if not test_result['success']: + printer_health['issues'].append(f'Authentifizierung fehlgeschlagen: {test_result.get("error", "Unbekannt")}') + except Exception as auth_error: + printer_health['issues'].append(f'Authentifizierungstest fehlgeschlagen: {str(auth_error)}') + + # Check 3: Funktionalität (Status abrufen) + if printer_health['checks']['authentication']: + try: + reachable, status = tapo_controller.check_outlet_status( + printer.plug_ip, + printer_id=printer.id + ) + printer_health['checks']['functionality'] = reachable + printer_health['current_status'] = status + + if not reachable: + printer_health['issues'].append('Status-Abfrage fehlgeschlagen') + except Exception as func_error: + printer_health['issues'].append(f'Funktionstest fehlgeschlagen: {str(func_error)}') + + # Gesamtstatus bewerten + if len(printer_health['issues']) == 0: + printer_health['status'] = 'healthy' + health_results['summary']['healthy'] += 1 + elif len(printer_health['issues']) <= 1: + printer_health['status'] = 'warning' + health_results['summary']['warning'] += 1 + else: + printer_health['status'] = 'critical' + health_results['summary']['critical'] += 1 + + # Aktuelle Jobs prüfen (für Sicherheitswarnungen) + active_jobs = db_session.query(Job).filter( + Job.printer_id == printer.id, + Job.status.in_(['running', 'printing', 'active']) + ).count() + + if active_jobs > 0: + printer_health['active_jobs'] = active_jobs + printer_health['issues'].append(f'{active_jobs} aktive(r) Job(s) - Vorsicht bei Steckdosen-Änderungen') + + except Exception as e: + admin_api_logger.error(f"Fehler beim Gesundheitscheck für {printer.name}: {str(e)}") + printer_health['status'] = 'critical' + printer_health['issues'].append(f'Systemfehler: {str(e)}') + health_results['summary']['critical'] += 1 + + health_results['printers'].append(printer_health) + + # Gesamtstatus und Empfehlungen bestimmen + if health_results['summary']['critical'] > 0: + health_results['overall_status'] = 'critical' + health_results['recommendations'].append('Kritische Probleme bei Tapo-Steckdosen beheben') + elif health_results['summary']['warning'] > 0: + health_results['overall_status'] = 'warning' + health_results['recommendations'].append('Warnungen bei Tapo-Steckdosen überprüfen') + + # Zusätzliche Empfehlungen + coverage = (len(printers_with_plugs) / db_session.query(Printer).count()) * 100 if db_session.query(Printer).count() > 0 else 0 + if coverage < 80: + health_results['recommendations'].append(f'Tapo-Abdeckung nur {coverage:.1f}% - weitere Steckdosen konfigurieren') + + admin_api_logger.info(f"Tapo-Gesundheitscheck abgeschlossen: {health_results['summary']}") + + return jsonify(health_results) + + except Exception as e: + admin_api_logger.error(f"Unerwarteter Fehler beim Tapo-Gesundheitscheck: {str(e)}") + return jsonify({ + 'success': False, + 'error': 'Fehler beim Health-Check', + 'message': str(e), + 'health': { + 'overall': 'error', + 'timestamp': datetime.now().isoformat() + } + }), 500 + +@admin_api_blueprint.route('/printers/tapo-configure', methods=['POST']) +@admin_required +def api_admin_configure_printer_tapo(): + """ + Konfiguriert oder aktualisiert die Tapo-Steckdosen-Einstellungen für einen Drucker. + """ + admin_api_logger.info(f"Tapo-Konfiguration von {current_user.username}") + + try: + data = request.get_json() + printer_id = data.get('printer_id') + plug_ip = data.get('plug_ip') + plug_username = data.get('plug_username') + plug_password = data.get('plug_password') + test_connection = data.get('test_connection', True) + + if not printer_id: + return jsonify({ + 'success': False, + 'error': 'Drucker-ID ist erforderlich' + }), 400 + + with get_cached_session() as db_session: + printer = db_session.query(Printer).filter(Printer.id == printer_id).first() + + if not printer: + return jsonify({ + 'success': False, + 'error': 'Drucker nicht gefunden' + }), 404 + + # Tapo-Einstellungen aktualisieren + if plug_ip: + try: + import ipaddress + ipaddress.ip_address(plug_ip) + printer.plug_ip = plug_ip + except ValueError: + return jsonify({ + 'success': False, + 'error': 'Ungültige IP-Adresse' + }), 400 + + if plug_username: + printer.plug_username = plug_username + + if plug_password: + printer.plug_password = plug_password + + # Verbindung testen falls gewünscht + test_result = None + if test_connection and printer.plug_ip: + try: + from utils.hardware_integration import tapo_controller + test_result = tapo_controller.test_connection( + printer.plug_ip, + username=printer.plug_username, + password=printer.plug_password + ) + + if test_result['success']: + printer.last_checked = datetime.now() + printer.status = 'online' + else: + admin_api_logger.warning(f"Tapo-Test für {printer.name} fehlgeschlagen: {test_result.get('error')}") + + except Exception as e: + test_result = { + 'success': False, + 'error': f'Test fehlgeschlagen: {str(e)}' + } + + db_session.commit() + + admin_api_logger.info(f"Tapo-Konfiguration für {printer.name} aktualisiert") + + return jsonify({ + 'success': True, + 'message': f'Tapo-Einstellungen für {printer.name} erfolgreich aktualisiert', + 'printer_id': printer_id, + 'test_result': test_result, + 'timestamp': datetime.now().isoformat() + }) + + except Exception as e: + admin_api_logger.error(f"Fehler bei Tapo-Konfiguration: {str(e)}") + return jsonify({ + 'success': False, + 'error': f'Systemfehler: {str(e)}' + }), 500 \ No newline at end of file diff --git a/backend/blueprints/api.py b/backend/blueprints/api.py index 32622523e..d155cdf7a 100644 --- a/backend/blueprints/api.py +++ b/backend/blueprints/api.py @@ -519,4 +519,40 @@ def get_error_recovery_status(): 'success': False, 'error': 'Fehler beim Laden des Wiederherstellungs-Status', 'message': str(e) + }), 500 + +@api_blueprint.route('/admin/fix-permissions', methods=['POST']) +@admin_required +def fix_admin_permissions(): + """ + Korrigiert die Admin-Berechtigungen im System. + + Nur für Administratoren zugänglich. + """ + try: + from utils.permissions import fix_all_admin_permissions + + result = fix_all_admin_permissions() + + if result['success']: + api_logger.info(f"Admin-Berechtigungen korrigiert von {current_user.username}: {result['created']} erstellt, {result['corrected']} aktualisiert") + return jsonify({ + 'success': True, + 'message': 'Admin-Berechtigungen erfolgreich korrigiert', + 'details': result + }) + else: + api_logger.error(f"Fehler beim Korrigieren der Admin-Berechtigungen: {result['error']}") + return jsonify({ + 'success': False, + 'error': 'Fehler beim Korrigieren der Berechtigungen', + 'message': result['error'] + }), 500 + + except Exception as e: + api_logger.error(f"Fehler beim Korrigieren der Admin-Berechtigungen: {str(e)}") + return jsonify({ + 'success': False, + 'error': 'Fehler beim Korrigieren der Berechtigungen', + 'message': str(e) }), 500 \ No newline at end of file diff --git a/backend/blueprints/guest.py b/backend/blueprints/guest.py index affec09b6..e9730feed 100644 --- a/backend/blueprints/guest.py +++ b/backend/blueprints/guest.py @@ -32,23 +32,8 @@ class GuestRequestForm(FlaskForm): '3D-Dateien sind erlaubt!')]) # Hilfsfunktionen -def can_approve_jobs(user_id): - """Prüft, ob ein Benutzer Anfragen genehmigen darf.""" - with get_cached_session() as db_session: - permission = db_session.query(UserPermission).filter_by(user_id=user_id).first() - if not permission: - return False - return permission.can_approve_jobs - -def approver_required(f): - """Decorator zur Prüfung der Genehmigungsberechtigung.""" - @wraps(f) - @login_required - def decorated_function(*args, **kwargs): - if not can_approve_jobs(current_user.id): - abort(403, "Keine Berechtigung zum Genehmigen von Anfragen") - return f(*args, **kwargs) - return decorated_function +# Importiere Berechtigungsfunktionen aus utils.permissions +from utils.permissions import can_approve_jobs, approver_required # Gast-Routen @guest_blueprint.route('/request', methods=['GET', 'POST']) diff --git a/backend/blueprints/printers.py b/backend/blueprints/printers.py index 43f9c529d..2387d6bed 100644 --- a/backend/blueprints/printers.py +++ b/backend/blueprints/printers.py @@ -18,7 +18,7 @@ from typing import Dict, List, Tuple, Any, Optional from models import Printer, User, Job, get_db_session from utils.logging_config import get_logger, measure_execution_time from utils.security_suite import require_permission, Permission, check_permission -from utils.hardware_integration import printer_monitor +from utils.hardware_integration import printer_monitor, tapo_controller from utils.drag_drop_system import drag_drop_manager # Logger initialisieren @@ -1047,4 +1047,527 @@ def get_drag_drop_config(): # ============================================================================= # ENDE DRAG & DROP API -# ============================================================================= \ No newline at end of file +# ============================================================================= + +@printers_blueprint.route("/tapo/status-check", methods=["POST"]) +@login_required +@require_permission(Permission.CONTROL_PRINTER) +@measure_execution_time(logger=printers_logger, task_name="API-Massenhafte-Tapo-Status-Prüfung") +def mass_tapo_status_check(): + """ + Führt eine vollständige Tapo-Status-Überprüfung für alle Drucker durch. + + Returns: + JSON mit detailliertem Status aller Tapo-Steckdosen + """ + printers_logger.info(f"Massenhafte Tapo-Status-Prüfung von Benutzer {current_user.name}") + + try: + db_session = get_db_session() + + # Alle Drucker laden + all_printers = db_session.query(Printer).all() + + # Tapo-Controller laden + try: + from utils.hardware_integration import tapo_controller + tapo_available = True + except Exception as e: + db_session.close() + return jsonify({ + "success": False, + "error": f"Tapo-Controller nicht verfügbar: {str(e)}", + "tapo_available": False + }), 500 + + printer_status = [] + summary = { + "total_printers": len(all_printers), + "printers_with_tapo": 0, + "printers_without_tapo": 0, + "tapo_online": 0, + "tapo_offline": 0, + "tapo_unreachable": 0, + "configuration_issues": 0 + } + + for printer in all_printers: + printer_info = { + "id": printer.id, + "name": printer.name, + "model": printer.model, + "location": printer.location, + "active": printer.active, + "has_tapo_config": bool(printer.plug_ip), + "plug_ip": printer.plug_ip, + "last_checked": datetime.now() + } + + if not printer.plug_ip: + # Drucker ohne Tapo-Konfiguration + summary["printers_without_tapo"] += 1 + printer_info.update({ + "tapo_status": "not_configured", + "tapo_reachable": False, + "power_status": None, + "recommendations": ["Tapo-Steckdose konfigurieren für automatische Steuerung"] + }) + else: + # Drucker mit Tapo-Konfiguration + summary["printers_with_tapo"] += 1 + + # Konfigurationsprüfung + config_issues = [] + if not printer.plug_username: + config_issues.append("Tapo-Benutzername fehlt") + if not printer.plug_password: + config_issues.append("Tapo-Passwort fehlt") + + if config_issues: + summary["configuration_issues"] += 1 + printer_info.update({ + "tapo_status": "configuration_error", + "tapo_reachable": False, + "power_status": None, + "config_issues": config_issues, + "recommendations": ["Tapo-Anmeldedaten vervollständigen"] + }) + else: + # Vollständige Konfiguration - Status prüfen + try: + reachable, status = tapo_controller.check_outlet_status( + printer.plug_ip, + printer_id=printer.id + ) + + if reachable: + if status == "on": + summary["tapo_online"] += 1 + status_type = "online" + recommendations = [] + else: + summary["tapo_offline"] += 1 + status_type = "offline" + recommendations = ["Steckdose kann bei Bedarf eingeschaltet werden"] + else: + summary["tapo_unreachable"] += 1 + status_type = "unreachable" + recommendations = ["Netzwerkverbindung prüfen", "IP-Adresse überprüfen"] + + printer_info.update({ + "tapo_status": status_type, + "tapo_reachable": reachable, + "power_status": status, + "recommendations": recommendations + }) + + # Drucker-Status in DB aktualisieren + if reachable: + printer.last_checked = datetime.now() + if status == "on": + printer.status = "online" + else: + printer.status = "offline" + else: + printer.status = "unreachable" + + except Exception as tapo_error: + summary["tapo_unreachable"] += 1 + printer_info.update({ + "tapo_status": "error", + "tapo_reachable": False, + "power_status": None, + "error": str(tapo_error), + "recommendations": ["Tapo-Verbindung prüfen", "Anmeldedaten überprüfen"] + }) + printers_logger.warning(f"Tapo-Fehler für {printer.name}: {str(tapo_error)}") + + # Aktuelle Jobs für zusätzliche Info + active_jobs = db_session.query(Job).filter( + Job.printer_id == printer.id, + Job.status.in_(["running", "printing", "active", "scheduled"]) + ).count() + + printer_info["active_jobs"] = active_jobs + if active_jobs > 0: + printer_info.setdefault("recommendations", []).append( + f"Vorsicht: {active_jobs} aktive Job(s) bei Steckdosen-Änderungen" + ) + + printer_status.append(printer_info) + + # Änderungen in DB speichern + db_session.commit() + db_session.close() + + # Übersicht der Ergebnisse + coverage_percentage = (summary["printers_with_tapo"] / summary["total_printers"] * 100) if summary["total_printers"] > 0 else 0 + health_score = ((summary["tapo_online"] + summary["tapo_offline"]) / summary["printers_with_tapo"] * 100) if summary["printers_with_tapo"] > 0 else 0 + + printers_logger.info(f"Tapo-Status-Check abgeschlossen: {summary['printers_with_tapo']} konfiguriert, " + f"{summary['tapo_online']} online, {summary['tapo_unreachable']} nicht erreichbar") + + return jsonify({ + "success": True, + "tapo_available": tapo_available, + "printers": printer_status, + "summary": summary, + "metrics": { + "coverage_percentage": round(coverage_percentage, 1), + "health_score": round(health_score, 1), + "needs_attention": summary["configuration_issues"] + summary["tapo_unreachable"] + }, + "timestamp": datetime.now().isoformat() + }) + + except Exception as e: + printers_logger.error(f"Unerwarteter Fehler bei Massenhafte-Tapo-Status-Prüfung: {str(e)}") + if 'db_session' in locals(): + db_session.close() + return jsonify({ + "success": False, + "error": f"Systemfehler: {str(e)}" + }), 500 + +@printers_blueprint.route("/tapo/configuration-wizard", methods=["POST"]) +@login_required +@require_permission(Permission.ADMIN) +@measure_execution_time(logger=printers_logger, task_name="API-Tapo-Konfigurationsassistent") +def tapo_configuration_wizard(): + """ + Automatischer Konfigurationsassistent für Tapo-Steckdosen. + Versucht automatisch verfügbare Steckdosen zu erkennen und zu konfigurieren. + """ + printers_logger.info(f"Tapo-Konfigurationsassistent von Admin {current_user.name}") + + try: + data = request.get_json() + auto_configure = data.get('auto_configure', True) + test_ips = data.get('test_ips', []) + + # Tapo-Controller laden + try: + from utils.hardware_integration import tapo_controller + except Exception as e: + return jsonify({ + "success": False, + "error": f"Tapo-Controller nicht verfügbar: {str(e)}" + }), 500 + + db_session = get_db_session() + + # Standard-IP-Bereich für Mercedes-Benz TBA (normalerweise 192.168.1.201-206) + if not test_ips: + test_ips = [f"192.168.1.{i}" for i in range(201, 207)] # 6 Standard-Arbeitsplätze + + discovery_results = { + "tested_ips": test_ips, + "discovered_devices": [], + "configured_printers": [], + "errors": [] + } + + printers_logger.info(f"Teste {len(test_ips)} IP-Adressen auf Tapo-Geräte...") + + # Discovery für jede IP-Adresse + for ip in test_ips: + try: + printers_logger.debug(f"Teste IP: {ip}") + + # Ping-Test + if not tapo_controller.ping_address(ip, timeout=3): + discovery_results["errors"].append(f"{ip}: Nicht erreichbar (Ping fehlgeschlagen)") + continue + + # Tapo-Verbindungstest + test_result = tapo_controller.test_connection(ip) + + if test_result["success"]: + device_info = test_result.get("device_info", {}) + + discovered_device = { + "ip": ip, + "device_info": device_info, + "nickname": device_info.get("nickname", f"Tapo Device {ip}"), + "model": device_info.get("model", "Unknown"), + "device_on": device_info.get("device_on", False) + } + + discovery_results["discovered_devices"].append(discovered_device) + printers_logger.info(f"✅ Tapo-Gerät gefunden: {ip} - {discovered_device['nickname']}") + + # Auto-Konfiguration wenn gewünscht + if auto_configure: + # Suche nach Drucker ohne Tapo-Konfiguration + unconfigured_printer = db_session.query(Printer).filter( + Printer.plug_ip.is_(None), + Printer.active == True + ).first() + + if unconfigured_printer: + # Konfiguriere den ersten verfügbaren Drucker + unconfigured_printer.plug_ip = ip + unconfigured_printer.plug_username = "admin" # Standard für Tapo + unconfigured_printer.plug_password = "admin" # Standard für Tapo + unconfigured_printer.last_checked = datetime.now() + + configured_info = { + "printer_id": unconfigured_printer.id, + "printer_name": unconfigured_printer.name, + "tapo_ip": ip, + "tapo_nickname": discovered_device['nickname'] + } + + discovery_results["configured_printers"].append(configured_info) + printers_logger.info(f"✅ Drucker '{unconfigured_printer.name}' automatisch mit {ip} verknüpft") + else: + discovery_results["errors"].append(f"{ip}: Tapo-Gerät gefunden, aber kein unkonfigurierter Drucker verfügbar") + + else: + discovery_results["errors"].append(f"{ip}: Erreichbar, aber kein Tapo-Gerät oder Authentifizierung fehlgeschlagen") + + except Exception as ip_error: + discovery_results["errors"].append(f"{ip}: Fehler beim Test - {str(ip_error)}") + printers_logger.warning(f"Fehler beim Testen von {ip}: {str(ip_error)}") + + # Änderungen speichern + db_session.commit() + db_session.close() + + # Zusammenfassung + summary = { + "tested_ips": len(test_ips), + "discovered_devices": len(discovery_results["discovered_devices"]), + "configured_printers": len(discovery_results["configured_printers"]), + "errors": len(discovery_results["errors"]) + } + + printers_logger.info(f"Tapo-Konfigurationsassistent abgeschlossen: {summary}") + + return jsonify({ + "success": True, + "message": f"Discovery abgeschlossen: {summary['discovered_devices']} Geräte gefunden, " + f"{summary['configured_printers']} Drucker konfiguriert", + "results": discovery_results, + "summary": summary, + "timestamp": datetime.now().isoformat() + }) + + except Exception as e: + printers_logger.error(f"Fehler beim Tapo-Konfigurationsassistent: {str(e)}") + if 'db_session' in locals(): + db_session.close() + return jsonify({ + "success": False, + "error": f"Systemfehler: {str(e)}" + }), 500 + +@printers_blueprint.route("/tapo/validate-configuration/{{ stats.total_users }}
+ + File "C:\Users\TTOMCZA.EMEA\AppData\Roaming\Python\Python313\site-packages\jinja2\environment.py", line 490, in getattr + return getattr(obj, attribute) +jinja2.exceptions.UndefinedError: 'stats' is undefined + +2025-06-13 07:14:02 - [app] app - [INFO] INFO - Locating template 'errors/500.html': + 1: trying loader of application '__main__' + class: jinja2.loaders.FileSystemLoader + encoding: 'utf-8' + followlinks: False + searchpath: + - C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates + -> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\errors\\500.html') +2025-06-13 07:14:02 - [app] app - [DEBUG] DEBUG - Response: 500 +2025-06-13 07:14:11 - [app] app - [DEBUG] DEBUG - Request: GET /user/settings +2025-06-13 07:14:11 - [app] app - [INFO] INFO - Locating template 'settings.html': + 1: trying loader of application '__main__' + class: jinja2.loaders.FileSystemLoader + encoding: 'utf-8' + followlinks: False + searchpath: + - C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates + -> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\settings.html') +2025-06-13 07:14:11 - [app] app - [DEBUG] DEBUG - Response: 200 +2025-06-13 07:14:11 - [app] app - [DEBUG] DEBUG - Request: GET /api/user/settings +2025-06-13 07:14:11 - [app] app - [DEBUG] DEBUG - Response: 200 +2025-06-13 07:14:16 - [app] app - [DEBUG] DEBUG - Request: PATCH /api/user/setting +2025-06-13 07:14:16 - [app] app - [INFO] INFO - Not Found (404): http://127.0.0.1:5000/api/user/setting +2025-06-13 07:14:16 - [app] app - [DEBUG] DEBUG - Response: 404 +2025-06-13 07:14:28 - [app] app - [DEBUG] DEBUG - Request: GET /admin/ +2025-06-13 07:14:28 - [app] app - [INFO] INFO - Locating template 'admin.html': + 1: trying loader of application '__main__' + class: jinja2.loaders.FileSystemLoader + encoding: 'utf-8' + followlinks: False + searchpath: + - C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates + -> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\admin.html') +2025-06-13 07:14:28 - [app] app - [DEBUG] DEBUG - Response: 200 +2025-06-13 07:14:28 - [app] app - [DEBUG] DEBUG - Request: GET /api/stats +2025-06-13 07:14:28 - [app] app - [DEBUG] DEBUG - Response: 200 +2025-06-13 07:14:28 - [app] app - [DEBUG] DEBUG - Request: GET /api/admin/system-health +2025-06-13 07:14:28 - [app] app - [ERROR] ERROR - Datenbank-Transaktion fehlgeschlagen: Textual SQL expression 'SELECT 1' should be explicitly declared as text('SELECT 1') +2025-06-13 07:14:28 - [app] app - [DEBUG] DEBUG - Response: 200 +2025-06-13 07:14:31 - [app] app - [DEBUG] DEBUG - Request: GET /admin/tapo-monitoring +2025-06-13 07:14:44 - [app] app - [INFO] INFO - Locating template 'admin_tapo_monitoring.html': + 1: trying loader of application '__main__' + class: jinja2.loaders.FileSystemLoader + encoding: 'utf-8' + followlinks: False + searchpath: + - C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\templates + -> found ('C:\\Users\\TTOMCZA.EMEA\\Dev\\Projektarbeit-MYP\\backend\\templates\\admin_tapo_monitoring.html') +2025-06-13 07:14:44 - [app] app - [DEBUG] DEBUG - Response: 200 +2025-06-13 07:14:50 - [app] app - [DEBUG] DEBUG - Request: GET /dashboard +2025-06-13 07:14:50 - [app] app - [DEBUG] DEBUG - Response: 200 diff --git a/backend/logs/calendar/calendar.log b/backend/logs/calendar/calendar.log index 7882b0746..565598399 100644 --- a/backend/logs/calendar/calendar.log +++ b/backend/logs/calendar/calendar.log @@ -3,3 +3,5 @@ 2025-06-12 09:43:22 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-07 22:00:00+00:00 bis 2025-06-14 22:00:00+00:00 2025-06-12 20:59:54 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-07 22:00:00+00:00 bis 2025-06-14 22:00:00+00:00 2025-06-12 21:01:17 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-07 22:00:00+00:00 bis 2025-06-14 22:00:00+00:00 +2025-06-13 07:12:59 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-07 22:00:00+00:00 bis 2025-06-14 22:00:00+00:00 +2025-06-13 07:13:06 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 44 Einträge für Zeitraum 2025-06-07 22:00:00+00:00 bis 2025-06-14 22:00:00+00:00 diff --git a/backend/logs/core_system/core_system.log b/backend/logs/core_system/core_system.log index e8ba748ea..f3b2a1e87 100644 --- a/backend/logs/core_system/core_system.log +++ b/backend/logs/core_system/core_system.log @@ -170,3 +170,7 @@ 2025-06-13 06:49:43 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion) 2025-06-13 06:57:16 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert 2025-06-13 06:57:16 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion) +2025-06-13 07:12:33 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert +2025-06-13 07:12:33 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion) +2025-06-13 07:12:36 - [core_system] core_system - [INFO] INFO - ✅ Core System Management Module erfolgreich initialisiert +2025-06-13 07:12:36 - [core_system] core_system - [INFO] INFO - 📊 Massive Konsolidierung: 6 Dateien → 1 Datei (88% Reduktion) diff --git a/backend/logs/data_management/data_management.log b/backend/logs/data_management/data_management.log index 6a8e6604e..6c94a6420 100644 --- a/backend/logs/data_management/data_management.log +++ b/backend/logs/data_management/data_management.log @@ -194,3 +194,7 @@ 2025-06-13 06:49:44 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) 2025-06-13 06:57:17 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert 2025-06-13 06:57:17 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) +2025-06-13 07:12:33 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert +2025-06-13 07:12:33 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) +2025-06-13 07:12:36 - [data_management] data_management - [INFO] INFO - ✅ Data Management Module initialisiert +2025-06-13 07:12:36 - [data_management] data_management - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) diff --git a/backend/logs/energy_monitoring/energy_monitoring.log b/backend/logs/energy_monitoring/energy_monitoring.log index 8adf5932f..e5d2389c9 100644 --- a/backend/logs/energy_monitoring/energy_monitoring.log +++ b/backend/logs/energy_monitoring/energy_monitoring.log @@ -30,3 +30,13 @@ 2025-06-13 06:49:42 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert 2025-06-13 06:49:45 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert 2025-06-13 06:57:20 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert +2025-06-13 07:12:34 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert +2025-06-13 07:12:37 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiemonitoring-Blueprint initialisiert +2025-06-13 07:13:12 - [energy_monitoring] energy_monitoring - [INFO] INFO - 🔋 Energiemonitoring-Dashboard aufgerufen von admin +2025-06-13 07:13:12 - [energy_monitoring] energy_monitoring - [INFO] INFO - 📈 API-Energiestatistiken (today) von admin +2025-06-13 07:13:12 - [energy_monitoring] energy_monitoring - [INFO] INFO - 📊 API-Energiemonitoring-Dashboard von admin +2025-06-13 07:13:12 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Energiestatistiken erfolgreich erstellt für Zeitraum: today +2025-06-13 07:13:12 - [energy_monitoring] energy_monitoring - [INFO] INFO - [OK] API-Energiestatistiken 'api_energy_statistics' erfolgreich in 5.61ms +2025-06-13 07:13:12 - [energy_monitoring] energy_monitoring - [INFO] INFO - ✅ Dashboard-Daten erfolgreich erstellt: 0 Geräte online +2025-06-13 07:13:12 - [energy_monitoring] energy_monitoring - [INFO] INFO - [OK] API-Energiemonitoring-Dashboard 'api_energy_dashboard' erfolgreich in 7.50ms +2025-06-13 07:13:12 - [energy_monitoring] energy_monitoring - [INFO] INFO - [OK] API-Live-Energiedaten 'api_live_energy_data' erfolgreich in 5.26ms diff --git a/backend/logs/guest/guest.log b/backend/logs/guest/guest.log index b35fe9f34..d93215ae3 100644 --- a/backend/logs/guest/guest.log +++ b/backend/logs/guest/guest.log @@ -30,3 +30,7 @@ WHERE user_permissions.can_approve_jobs = 1] 2025-06-12 15:24:59 - [guest] guest - [ERROR] ERROR - Fehler beim Abrufen der Benachrichtigungen: Entity namespace for "notifications" has no property "read" 2025-06-12 15:25:29 - [guest] guest - [ERROR] ERROR - Fehler beim Abrufen der Benachrichtigungen: Entity namespace for "notifications" has no property "read" 2025-06-13 06:57:05 - [guest] guest - [INFO] INFO - Neue Gastanfrage erstellt: ID 1, Name: Till Tomczaktet, OTP generiert +2025-06-13 07:13:42 - [guest] guest - [ERROR] ERROR - Fehler beim Erstellen der Gastanfrage: (sqlite3.OperationalError) table notifications has no column named title +[SQL: INSERT INTO notifications (user_id, title, message, type, payload, created_at, is_read, read_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)] +[parameters: (1, None, None, 'guest_request', '{"request_id": 2, "name": "Till Tomczaktet", "created_at": "2025-06-13T07:13:42.749201", "status": "pending"}', '2025-06-13 07:13:42.954291', 0, None)] +(Background on this error at: https://sqlalche.me/e/20/e3q8) diff --git a/backend/logs/hardware_integration/hardware_integration.log b/backend/logs/hardware_integration/hardware_integration.log index f59fb6e3e..2e0a7688a 100644 --- a/backend/logs/hardware_integration/hardware_integration.log +++ b/backend/logs/hardware_integration/hardware_integration.log @@ -470,3 +470,47 @@ 2025-06-13 06:57:17 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert 2025-06-13 06:57:17 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert 2025-06-13 06:57:17 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion) +2025-06-13 07:12:33 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar +2025-06-13 07:12:33 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert +2025-06-13 07:12:33 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert +2025-06-13 07:12:33 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion) +2025-06-13 07:12:36 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ PyP100 (TP-Link Tapo) verfügbar +2025-06-13 07:12:36 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Printer Monitor initialisiert +2025-06-13 07:12:36 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Hardware Integration Module initialisiert +2025-06-13 07:12:36 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Massive Konsolidierung: 2 Dateien → 1 Datei (50% Reduktion) +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - 🔋 Sammle Energiestatistiken von allen P110 Steckdosen... +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 1 - Halle A nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 2 - Halle A nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 3 - Halle B nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 4 - Halle B nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 5 - Labor nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 6 - Werkstatt nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Energiestatistiken erfolgreich gesammelt: 0/6 Geräte online +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Gesamtverbrauch: 0.0W aktuell, 0.0Wh heute +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - 🔋 Sammle Energiestatistiken von allen P110 Steckdosen... +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - 🔋 Sammle Energiestatistiken von allen P110 Steckdosen... +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - 🔋 Sammle Energiestatistiken von allen P110 Steckdosen... +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 1 - Halle A nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 2 - Halle A nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 3 - Halle B nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 4 - Halle B nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 5 - Labor nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 6 - Werkstatt nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Energiestatistiken erfolgreich gesammelt: 0/6 Geräte online +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 1 - Halle A nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 1 - Halle A nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Gesamtverbrauch: 0.0W aktuell, 0.0Wh heute +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 2 - Halle A nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 2 - Halle A nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 3 - Halle B nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 3 - Halle B nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 4 - Halle B nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 4 - Halle B nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 5 - Labor nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 5 - Labor nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 6 - Werkstatt nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [WARNING] WARNING - ⚠️ Konnte Energiedaten für 3D-Drucker 6 - Werkstatt nicht abrufen: module 'PyP100.PyP100' has no attribute 'P110' +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Energiestatistiken erfolgreich gesammelt: 0/6 Geräte online +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - ✅ Energiestatistiken erfolgreich gesammelt: 0/6 Geräte online +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Gesamtverbrauch: 0.0W aktuell, 0.0Wh heute +2025-06-13 07:13:12 - [hardware_integration] hardware_integration - [INFO] INFO - 📊 Gesamtverbrauch: 0.0W aktuell, 0.0Wh heute diff --git a/backend/logs/job_queue_system/job_queue_system.log b/backend/logs/job_queue_system/job_queue_system.log index 47eaf37cb..b4ca7fd51 100644 --- a/backend/logs/job_queue_system/job_queue_system.log +++ b/backend/logs/job_queue_system/job_queue_system.log @@ -370,3 +370,11 @@ 2025-06-13 06:57:20 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität) 2025-06-13 06:59:55 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität) 2025-06-13 06:59:55 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität) +2025-06-13 07:12:33 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert +2025-06-13 07:12:33 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion) +2025-06-13 07:12:35 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität) +2025-06-13 07:12:36 - [job_queue_system] job_queue_system - [INFO] INFO - ✅ Job & Queue System Module initialisiert +2025-06-13 07:12:36 - [job_queue_system] job_queue_system - [INFO] INFO - 📊 MASSIVE Konsolidierung: 4 Dateien → 1 Datei (75% Reduktion) +2025-06-13 07:12:37 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestartet (Legacy-Kompatibilität) +2025-06-13 07:14:55 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität) +2025-06-13 07:14:55 - [job_queue_system] job_queue_system - [INFO] INFO - Queue Manager gestoppt (Legacy-Kompatibilität) diff --git a/backend/logs/jobs/jobs.log b/backend/logs/jobs/jobs.log index cac9853c5..27d6a2264 100644 --- a/backend/logs/jobs/jobs.log +++ b/backend/logs/jobs/jobs.log @@ -565,3 +565,5 @@ IndexError: tuple index out of range 2025-06-12 21:00:27 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1) 2025-06-12 21:12:23 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True) 2025-06-12 21:12:23 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1) +2025-06-13 07:12:54 - [jobs] jobs - [INFO] INFO - 📋 Jobs-Abfrage gestartet von Benutzer 1 (Admin: True) +2025-06-13 07:12:54 - [jobs] jobs - [INFO] INFO - ✅ Jobs erfolgreich abgerufen: 0 von 0 (Seite 1) diff --git a/backend/logs/monitoring_analytics/monitoring_analytics.log b/backend/logs/monitoring_analytics/monitoring_analytics.log index 4c9fd6754..ce81668f1 100644 --- a/backend/logs/monitoring_analytics/monitoring_analytics.log +++ b/backend/logs/monitoring_analytics/monitoring_analytics.log @@ -194,3 +194,7 @@ 2025-06-13 06:49:45 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) 2025-06-13 06:57:20 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert 2025-06-13 06:57:20 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) +2025-06-13 07:12:34 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert +2025-06-13 07:12:34 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) +2025-06-13 07:12:37 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - ✅ Monitoring & Analytics Module initialisiert +2025-06-13 07:12:37 - [monitoring_analytics] monitoring_analytics - [INFO] INFO - 📊 MASSIVE Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) diff --git a/backend/logs/permissions/permissions.log b/backend/logs/permissions/permissions.log new file mode 100644 index 000000000..c310890de --- /dev/null +++ b/backend/logs/permissions/permissions.log @@ -0,0 +1,3 @@ +2025-06-13 07:12:34 - [permissions] permissions - [INFO] INFO - UserPermission für Admin admin (ID: 1) erstellt +2025-06-13 07:12:34 - [permissions] permissions - [INFO] INFO - Admin-Berechtigungen korrigiert: 1 erstellt, 0 aktualisiert +2025-06-13 07:12:37 - [permissions] permissions - [INFO] INFO - Admin-Berechtigungen korrigiert: 0 erstellt, 0 aktualisiert diff --git a/backend/logs/scheduler/scheduler.log b/backend/logs/scheduler/scheduler.log index 5c00ee813..f8aa76d5c 100644 --- a/backend/logs/scheduler/scheduler.log +++ b/backend/logs/scheduler/scheduler.log @@ -272,3 +272,9 @@ 2025-06-13 06:57:17 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True 2025-06-13 06:57:20 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet 2025-06-13 06:57:20 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet +2025-06-13 07:12:33 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-13 07:12:35 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet +2025-06-13 07:12:35 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet +2025-06-13 07:12:36 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True +2025-06-13 07:12:37 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet +2025-06-13 07:12:37 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet diff --git a/backend/logs/security_suite/security_suite.log b/backend/logs/security_suite/security_suite.log index ace16fb79..18218c6fd 100644 --- a/backend/logs/security_suite/security_suite.log +++ b/backend/logs/security_suite/security_suite.log @@ -293,3 +293,9 @@ 2025-06-13 06:57:17 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert 2025-06-13 06:57:17 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) 2025-06-13 06:57:20 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert +2025-06-13 07:12:33 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert +2025-06-13 07:12:33 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) +2025-06-13 07:12:34 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert +2025-06-13 07:12:36 - [security_suite] security_suite - [INFO] INFO - ✅ Security Suite Module initialisiert +2025-06-13 07:12:36 - [security_suite] security_suite - [INFO] INFO - 📊 Massive Konsolidierung: 3 Dateien → 1 Datei (67% Reduktion) +2025-06-13 07:12:37 - [security_suite] security_suite - [INFO] INFO - 🔒 Security Suite initialisiert diff --git a/backend/logs/startup/startup.log b/backend/logs/startup/startup.log index e21e420e1..507221fcc 100644 --- a/backend/logs/startup/startup.log +++ b/backend/logs/startup/startup.log @@ -856,3 +856,21 @@ 2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert 2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert 2025-06-13 06:57:20 - [startup] startup - [INFO] INFO - ================================================== +2025-06-13 07:12:34 - [startup] startup - [INFO] INFO - ================================================== +2025-06-13 07:12:34 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet... +2025-06-13 07:12:34 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] +2025-06-13 07:12:34 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-13 07:12:34 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-13 07:12:34 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-13T07:12:34.859970 +2025-06-13 07:12:34 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-13 07:12:34 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-13 07:12:34 - [startup] startup - [INFO] INFO - ================================================== +2025-06-13 07:12:37 - [startup] startup - [INFO] INFO - ================================================== +2025-06-13 07:12:37 - [startup] startup - [INFO] INFO - [START] MYP Platform Backend wird gestartet... +2025-06-13 07:12:37 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] +2025-06-13 07:12:37 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32) +2025-06-13 07:12:37 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend +2025-06-13 07:12:37 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-13T07:12:37.315577 +2025-06-13 07:12:37 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert +2025-06-13 07:12:37 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert +2025-06-13 07:12:37 - [startup] startup - [INFO] INFO - ================================================== diff --git a/backend/logs/tapo_control/tapo_control.log b/backend/logs/tapo_control/tapo_control.log index d83a6e4df..d4dde6a90 100644 --- a/backend/logs/tapo_control/tapo_control.log +++ b/backend/logs/tapo_control/tapo_control.log @@ -69,3 +69,11 @@ 2025-06-12 21:12:37 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Steckdose 5 (192.168.1.205) nicht erreichbar 2025-06-12 21:12:39 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Steckdose 6 (192.168.1.206) nicht erreichbar 2025-06-12 21:12:39 - [tapo_control] tapo_control - [INFO] INFO - Dashboard geladen: 6 Steckdosen konfiguriert, 0 online +2025-06-13 07:13:21 - [tapo_control] tapo_control - [INFO] INFO - Tapo Dashboard aufgerufen von Benutzer: Administrator +2025-06-13 07:13:23 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Steckdose 1 (192.168.1.201) nicht erreichbar +2025-06-13 07:13:25 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Steckdose 2 (192.168.1.202) nicht erreichbar +2025-06-13 07:13:27 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Steckdose 3 (192.168.1.203) nicht erreichbar +2025-06-13 07:13:29 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Steckdose 4 (192.168.1.204) nicht erreichbar +2025-06-13 07:13:31 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Steckdose 5 (192.168.1.205) nicht erreichbar +2025-06-13 07:13:33 - [tapo_control] tapo_control - [WARNING] WARNING - ⚠️ Steckdose 6 (192.168.1.206) nicht erreichbar +2025-06-13 07:13:33 - [tapo_control] tapo_control - [INFO] INFO - Dashboard geladen: 6 Steckdosen konfiguriert, 0 online diff --git a/backend/logs/tapo_controller/tapo_controller.log b/backend/logs/tapo_controller/tapo_controller.log index cdd7c9943..0e5470f1e 100644 --- a/backend/logs/tapo_controller/tapo_controller.log +++ b/backend/logs/tapo_controller/tapo_controller.log @@ -98,3 +98,5 @@ 2025-06-13 06:49:37 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert 2025-06-13 06:49:44 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert 2025-06-13 06:57:17 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert +2025-06-13 07:12:33 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert +2025-06-13 07:12:36 - [tapo_controller] tapo_controller - [INFO] INFO - ✅ tapo controller initialisiert diff --git a/backend/logs/tapo_status_manager/tapo_status_manager.log b/backend/logs/tapo_status_manager/tapo_status_manager.log index 796fce71a..609521608 100644 --- a/backend/logs/tapo_status_manager/tapo_status_manager.log +++ b/backend/logs/tapo_status_manager/tapo_status_manager.log @@ -55,3 +55,5 @@ 2025-06-13 06:49:37 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert 2025-06-13 06:49:44 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert 2025-06-13 06:57:17 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert +2025-06-13 07:12:33 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert +2025-06-13 07:12:36 - [tapo_status_manager] tapo_status_manager - [INFO] INFO - TapoStatusManager initialisiert diff --git a/backend/logs/user/user.log b/backend/logs/user/user.log index 0aa43ba29..421dd3603 100644 --- a/backend/logs/user/user.log +++ b/backend/logs/user/user.log @@ -82,3 +82,5 @@ 2025-06-12 21:00:49 - [user] user - [INFO] INFO - User admin accessed settings page 2025-06-12 21:00:49 - [user] user - [INFO] INFO - User admin retrieved settings via API 2025-06-12 21:01:00 - [user] user - [INFO] INFO - User admin updated settings via API +2025-06-13 07:14:11 - [user] user - [INFO] INFO - User admin accessed settings page +2025-06-13 07:14:11 - [user] user - [INFO] INFO - User admin retrieved settings via API diff --git a/backend/logs/utilities_collection/utilities_collection.log b/backend/logs/utilities_collection/utilities_collection.log index e4617289e..c05dad037 100644 --- a/backend/logs/utilities_collection/utilities_collection.log +++ b/backend/logs/utilities_collection/utilities_collection.log @@ -204,3 +204,7 @@ 2025-06-13 06:49:43 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion) 2025-06-13 06:57:16 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert 2025-06-13 06:57:16 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion) +2025-06-13 07:12:33 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert +2025-06-13 07:12:33 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion) +2025-06-13 07:12:36 - [utilities_collection] utilities_collection - [INFO] INFO - ✅ Utilities Collection initialisiert +2025-06-13 07:12:36 - [utilities_collection] utilities_collection - [INFO] INFO - 🚨 ALLERLETZTE MEGA-Konsolidierung: 12+ Dateien → 1 Datei (90%+ Reduktion) diff --git a/backend/logs/windows_fixes/windows_fixes.log b/backend/logs/windows_fixes/windows_fixes.log index 262637f04..106228fa9 100644 --- a/backend/logs/windows_fixes/windows_fixes.log +++ b/backend/logs/windows_fixes/windows_fixes.log @@ -173,3 +173,7 @@ 2025-06-13 06:49:43 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet 2025-06-13 06:57:16 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... 2025-06-13 06:57:16 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-13 07:12:33 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-13 07:12:33 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet +2025-06-13 07:12:36 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an... +2025-06-13 07:12:36 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet diff --git a/backend/templates/admin.html b/backend/templates/admin.html index c18b63351..274d4c7d5 100644 --- a/backend/templates/admin.html +++ b/backend/templates/admin.html @@ -278,6 +278,14 @@ document.addEventListener('DOMContentLoaded', function() { TBA-Anträge + + + + Tapo-Monitoring + diff --git a/backend/templates/admin_tapo_monitoring.html b/backend/templates/admin_tapo_monitoring.html new file mode 100644 index 000000000..bde62c6c7 --- /dev/null +++ b/backend/templates/admin_tapo_monitoring.html @@ -0,0 +1,585 @@ +{% extends "base.html" %} + +{% block title %}Tapo-Steckdosen-Monitoring - Admin | MYP Platform{% endblock %} + +{% block head %} +{{ super() }} + + + + + + + +{% endblock %} + +{% block content %} + + + + ++ Real-Time-Überwachung und Verwaltung aller TP-Link Tapo Smart Plugs im TBA Mercedes-Benz System +
+ + ++ Live-Status aller konfigurierten Tapo-Steckdosen (automatische Aktualisierung alle 30 Sekunden) +
+{{ printer.model }}
+Achtung:
++ Es wurden noch keine Drucker mit Tapo-Steckdosen eingerichtet. +
+ + + Drucker konfigurieren + +Mercedes-Benz
- Professionelles 3D-Druck Management + 3D-Druck Management
diff --git a/backend/utils/__pycache__/permissions.cpython-313.pyc b/backend/utils/__pycache__/permissions.cpython-313.pyc index c468647fd..ea5e21653 100644 Binary files a/backend/utils/__pycache__/permissions.cpython-313.pyc and b/backend/utils/__pycache__/permissions.cpython-313.pyc differ