2025-05-31 22:40:29 +02:00

181 lines
6.5 KiB
Python

"""
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/<int:printer_id>/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