Die Dateien wurden geändert oder hinzugefügt:
This commit is contained in:
@ -1823,4 +1823,656 @@ def get_status_color(status):
|
||||
'disconnected': '#ef4444', # Rot
|
||||
'unknown': '#6b7280' # Grau
|
||||
}
|
||||
return status_colors.get(status, '#6b7280')
|
||||
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
|
Reference in New Issue
Block a user