""" Drucker-Blueprint für MYP Platform Enthält alle Routen und Funktionen zur Druckerverwaltung, Statusüberwachung und Steuerung. """ import os import json import time from datetime import datetime, timedelta from flask import Blueprint, request, jsonify, current_app, abort, Response from flask_login import login_required, current_user from werkzeug.utils import secure_filename from werkzeug.exceptions import NotFound, BadRequest from sqlalchemy import func, desc, asc from sqlalchemy.exc import SQLAlchemyError 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.permissions import require_permission, Permission, check_permission from utils.printer_monitor import printer_monitor # Logger initialisieren printers_logger = get_logger("printers") # Blueprint erstellen printers_blueprint = Blueprint("printers", __name__, url_prefix="/api/printers") @printers_blueprint.route("/monitor/live-status", methods=["GET"]) @login_required @measure_execution_time(logger=printers_logger, task_name="API-Live-Drucker-Status-Abfrage") def get_live_printer_status(): """ Liefert den aktuellen Live-Status aller Drucker. Query-Parameter: - use_cache: ob Cache verwendet werden soll (default: true) Returns: JSON mit Live-Status aller Drucker """ printers_logger.info(f"🔄 Live-Status-Abfrage von Benutzer {current_user.name} (ID: {current_user.id})") # Parameter auslesen use_cache_param = request.args.get("use_cache", "true").lower() use_cache = use_cache_param == "true" try: # Live-Status über den PrinterMonitor abrufen status_data = printer_monitor.get_live_printer_status(use_session_cache=use_cache) # Zusammenfassung der Druckerstatus erstellen summary = printer_monitor.get_printer_summary() # Antwort mit Status und Zusammenfassung response = { "success": True, "status": status_data, "summary": summary, "timestamp": datetime.now().isoformat(), "cache_used": use_cache } printers_logger.info(f"✅ Live-Status-Abfrage erfolgreich: {len(status_data)} Drucker") return jsonify(response) except Exception as e: printers_logger.error(f"❌ Fehler bei Live-Status-Abfrage: {str(e)}") return jsonify({ "success": False, "error": "Fehler bei Abfrage des Druckerstatus", "message": str(e) }), 500 @printers_blueprint.route("/control//power", methods=["POST"]) @login_required @require_permission(Permission.CONTROL_PRINTER) # Verwende die bereits vorhandene Berechtigung @measure_execution_time(logger=printers_logger, task_name="API-Drucker-Stromversorgung-Steuerung") def control_printer_power(printer_id): """ Steuert die Stromversorgung eines Druckers (ein-/ausschalten). Args: printer_id: ID des zu steuernden Druckers JSON-Parameter: - action: "on" oder "off" Returns: JSON mit Ergebnis der Steuerungsaktion """ printers_logger.info(f"🔌 Stromsteuerung für Drucker {printer_id} von Benutzer {current_user.name}") # Parameter validieren data = request.get_json() if not data or "action" not in data: return jsonify({ "success": False, "error": "Parameter 'action' fehlt" }), 400 action = data["action"] if action not in ["on", "off"]: return jsonify({ "success": False, "error": "Ungültige Aktion. Erlaubt sind 'on' oder 'off'." }), 400 try: # Drucker aus Datenbank holen db_session = get_db_session() printer = db_session.query(Printer).filter(Printer.id == printer_id).first() if not printer: db_session.close() return jsonify({ "success": False, "error": f"Drucker mit ID {printer_id} nicht gefunden" }), 404 # Prüfen, ob Drucker eine Steckdose konfiguriert hat if not printer.plug_ip or not printer.plug_username or not printer.plug_password: db_session.close() return jsonify({ "success": False, "error": f"Drucker {printer.name} hat keine Steckdose konfiguriert" }), 400 # Steckdose steuern from PyP100 import PyP110 try: # TP-Link Tapo P110 Verbindung herstellen p110 = PyP110.P110(printer.plug_ip, printer.plug_username, printer.plug_password) p110.handshake() # Authentifizierung p110.login() # Login # Steckdose ein- oder ausschalten if action == "on": p110.turnOn() success = True message = "Steckdose erfolgreich eingeschaltet" printer.status = "starting" # Status aktualisieren else: p110.turnOff() success = True message = "Steckdose erfolgreich ausgeschaltet" printer.status = "offline" # Status aktualisieren # Zeitpunkt der letzten Prüfung aktualisieren printer.last_checked = datetime.now() db_session.commit() # Cache leeren, damit neue Status-Abfragen aktuell sind printer_monitor.clear_all_caches() printers_logger.info(f"✅ {action.upper()}: Drucker {printer.name} erfolgreich {message}") except Exception as e: printers_logger.error(f"❌ Fehler bei Steckdosensteuerung für {printer.name}: {str(e)}") db_session.close() return jsonify({ "success": False, "error": f"Fehler bei Steckdosensteuerung: {str(e)}" }), 500 db_session.close() return jsonify({ "success": True, "message": message, "printer_id": printer_id, "printer_name": printer.name, "action": action, "timestamp": datetime.now().isoformat() }) except Exception as e: printers_logger.error(f"❌ Allgemeiner Fehler bei Stromsteuerung: {str(e)}") return jsonify({ "success": False, "error": f"Allgemeiner Fehler: {str(e)}" }), 500