From c39595382c2d01bc4c9456293ba2d658a180a8e8 Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Tue, 27 May 2025 11:05:10 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Erweiterung=20der=20Drucker-API=20und?= =?UTF-8?q?=20Verbesserung=20der=20Benutzeroberfl=C3=A4che=20durch=20Statu?= =?UTF-8?q?s-Checks.=20Neue=20Drucker=20sind=20standardm=C3=A4=C3=9Fig=20a?= =?UTF-8?q?ktiv,=20und=20ein=20zus=C3=A4tzlicher=20Endpunkt=20zum=20Hinzuf?= =?UTF-8?q?=C3=BCgen=20von=20Druckern=20wurde=20implementiert.=20Die=20Dru?= =?UTF-8?q?cker-Templates=20wurden=20aktualisiert,=20um=20verf=C3=BCgbare?= =?UTF-8?q?=20Drucker=20mit=20Status-Indikatoren=20anzuzeigen=20und=20Fall?= =?UTF-8?q?back-Mechanismen=20bei=20Ladefehlern=20zu=20integrieren.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/add_test_printers.py | 178 +++++++++++++++++++++++++++++ backend/app/app.py | 18 ++- backend/app/templates/jobs.html | 80 ++++++++++++- backend/app/templates/new_job.html | 47 ++++++-- 4 files changed, 309 insertions(+), 14 deletions(-) create mode 100644 backend/app/add_test_printers.py diff --git a/backend/app/add_test_printers.py b/backend/app/add_test_printers.py new file mode 100644 index 000000000..d7232e25b --- /dev/null +++ b/backend/app/add_test_printers.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Skript zum Hinzufügen von Testdruckern zur Datenbank +""" + +import sys +import os +from datetime import datetime + +# Füge das Anwendungsverzeichnis zum Python-Pfad hinzu +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + +from models import get_db_session, Printer + +def add_test_printers(): + """Fügt Testdrucker zur Datenbank hinzu""" + + test_printers = [ + { + "name": "Prusa i3 MK3S+", + "model": "Prusa i3 MK3S+", + "location": "Labor A - Arbeitsplatz 1", + "mac_address": "AA:BB:CC:DD:EE:01", + "plug_ip": "192.168.1.101", + "status": "available", + "active": True + }, + { + "name": "Ender 3 V2", + "model": "Creality Ender 3 V2", + "location": "Labor A - Arbeitsplatz 2", + "mac_address": "AA:BB:CC:DD:EE:02", + "plug_ip": "192.168.1.102", + "status": "available", + "active": True + }, + { + "name": "Ultimaker S3", + "model": "Ultimaker S3", + "location": "Labor B - Arbeitsplatz 1", + "mac_address": "AA:BB:CC:DD:EE:03", + "plug_ip": "192.168.1.103", + "status": "available", + "active": True + }, + { + "name": "Bambu Lab X1 Carbon", + "model": "Bambu Lab X1 Carbon", + "location": "Labor B - Arbeitsplatz 2", + "mac_address": "AA:BB:CC:DD:EE:04", + "plug_ip": "192.168.1.104", + "status": "available", + "active": True + }, + { + "name": "Formlabs Form 3", + "model": "Formlabs Form 3", + "location": "Labor C - Harz-Bereich", + "mac_address": "AA:BB:CC:DD:EE:05", + "plug_ip": "192.168.1.105", + "status": "offline", + "active": False + } + ] + + db_session = get_db_session() + + try: + added_count = 0 + + for printer_data in test_printers: + # Prüfen, ob Drucker bereits existiert + existing = db_session.query(Printer).filter( + Printer.name == printer_data["name"] + ).first() + + if existing: + print(f"⚠️ Drucker '{printer_data['name']}' existiert bereits - überspringe") + continue + + # Neuen Drucker erstellen + new_printer = Printer( + name=printer_data["name"], + model=printer_data["model"], + location=printer_data["location"], + mac_address=printer_data["mac_address"], + plug_ip=printer_data["plug_ip"], + status=printer_data["status"], + active=printer_data["active"], + created_at=datetime.now() + ) + + db_session.add(new_printer) + added_count += 1 + print(f"✅ Drucker '{printer_data['name']}' hinzugefügt") + + if added_count > 0: + db_session.commit() + print(f"\n🎉 {added_count} Testdrucker erfolgreich zur Datenbank hinzugefügt!") + else: + print("\n📋 Alle Testdrucker existieren bereits in der Datenbank") + + # Zeige alle Drucker in der Datenbank + all_printers = db_session.query(Printer).all() + print(f"\n📊 Gesamt {len(all_printers)} Drucker in der Datenbank:") + print("-" * 80) + print(f"{'ID':<4} {'Name':<20} {'Modell':<20} {'Status':<12} {'Aktiv':<6}") + print("-" * 80) + + for printer in all_printers: + active_str = "✅" if printer.active else "❌" + print(f"{printer.id:<4} {printer.name[:19]:<20} {(printer.model or 'Unbekannt')[:19]:<20} {printer.status:<12} {active_str:<6}") + + db_session.close() + + except Exception as e: + db_session.rollback() + db_session.close() + print(f"❌ Fehler beim Hinzufügen der Testdrucker: {str(e)}") + return False + + return True + +def remove_test_printers(): + """Entfernt alle Testdrucker aus der Datenbank""" + + test_printer_names = [ + "Prusa i3 MK3S+", + "Ender 3 V2", + "Ultimaker S3", + "Bambu Lab X1 Carbon", + "Formlabs Form 3" + ] + + db_session = get_db_session() + + try: + removed_count = 0 + + for name in test_printer_names: + printer = db_session.query(Printer).filter(Printer.name == name).first() + if printer: + db_session.delete(printer) + removed_count += 1 + print(f"🗑️ Drucker '{name}' entfernt") + + if removed_count > 0: + db_session.commit() + print(f"\n🧹 {removed_count} Testdrucker erfolgreich entfernt!") + else: + print("\n📋 Keine Testdrucker zum Entfernen gefunden") + + db_session.close() + + except Exception as e: + db_session.rollback() + db_session.close() + print(f"❌ Fehler beim Entfernen der Testdrucker: {str(e)}") + return False + + return True + +if __name__ == "__main__": + print("=== MYP Druckerverwaltung - Testdrucker-Verwaltung ===") + print() + + if len(sys.argv) > 1 and sys.argv[1] == "--remove": + print("Entferne Testdrucker...") + remove_test_printers() + else: + print("Füge Testdrucker hinzu...") + print("(Verwende --remove um Testdrucker zu entfernen)") + print() + add_test_printers() + + print("\nFertig! 🚀") \ No newline at end of file diff --git a/backend/app/app.py b/backend/app/app.py index 185b37da1..8f826d3b8 100644 --- a/backend/app/app.py +++ b/backend/app/app.py @@ -1975,12 +1975,21 @@ def create_printer(): mac_address=data.get("mac_address", ""), plug_ip=data["plug_ip"], status="offline", + active=True, # Neue Drucker sind standardmäßig aktiv created_at=datetime.now() ) db_session.add(new_printer) db_session.commit() + # Sofortiger Status-Check für den neuen Drucker + ip_to_check = new_printer.plug_ip + if ip_to_check: + status, active = check_printer_status(ip_to_check) + new_printer.status = "available" if status == "online" else "offline" + new_printer.active = active + db_session.commit() + printer_data = { "id": new_printer.id, "name": new_printer.name, @@ -1989,18 +1998,25 @@ def create_printer(): "mac_address": new_printer.mac_address, "plug_ip": new_printer.plug_ip, "status": new_printer.status, + "active": new_printer.active, "created_at": new_printer.created_at.isoformat() } db_session.close() printers_logger.info(f"Neuer Drucker '{new_printer.name}' erstellt von Admin {current_user.id}") - return jsonify({"printer": printer_data}), 201 + return jsonify({"printer": printer_data, "message": "Drucker erfolgreich erstellt"}), 201 except Exception as e: printers_logger.error(f"Fehler beim Erstellen eines Druckers: {str(e)}") return jsonify({"error": "Interner Serverfehler"}), 500 +@app.route("/api/printers/add", methods=["POST"]) +@login_required +def add_printer(): + """Alternativer Endpunkt zum Hinzufügen von Druckern (für Frontend-Kompatibilität).""" + return create_printer() + @app.route("/api/printers/", methods=["PUT"]) @login_required def update_printer(printer_id): diff --git a/backend/app/templates/jobs.html b/backend/app/templates/jobs.html index a1fd081d4..94cdf3c03 100644 --- a/backend/app/templates/jobs.html +++ b/backend/app/templates/jobs.html @@ -253,23 +253,93 @@ function refreshJobs() { // Laden der Drucker für das Dropdown function loadPrinters() { - fetch('/api/printers') + // Lade Drucker mit Status-Check für bessere Verfügbarkeitsprüfung + fetch('/api/printers/status') .then(response => response.json()) .then(data => { const printerSelect = document.getElementById('printer_id'); printerSelect.innerHTML = ''; - // Nur aktive Drucker hinzufügen - data.printers.filter(printer => printer.active).forEach(printer => { + // Prüfe ob data ein Array ist (direkte Antwort) oder ein Objekt mit printers-Property + const printers = Array.isArray(data) ? data : (data.printers || []); + + console.log('Geladene Drucker:', printers); + + // Filtere verfügbare Drucker (status: 'available' oder active: true) + const availablePrinters = printers.filter(printer => { + return printer.status === 'available' || printer.active === true; + }); + + console.log('Verfügbare Drucker:', availablePrinters); + + if (availablePrinters.length === 0) { + // Fallback: Lade alle Drucker ohne Status-Check + return fetch('/api/printers') + .then(response => response.json()) + .then(fallbackData => { + const fallbackPrinters = fallbackData.printers || []; + console.log('Fallback Drucker:', fallbackPrinters); + + if (fallbackPrinters.length === 0) { + printerSelect.innerHTML = ''; + showNotification('Keine Drucker in der Datenbank gefunden', 'warning'); + return; + } + + // Zeige alle Drucker an, auch wenn Status unbekannt + fallbackPrinters.forEach(printer => { + const option = document.createElement('option'); + option.value = printer.id; + option.textContent = `${printer.name} (${printer.model || 'Unbekanntes Modell'}) - Status unbekannt`; + printerSelect.appendChild(option); + }); + + showNotification(`${fallbackPrinters.length} Drucker geladen (Status unbekannt)`, 'info'); + }); + } + + // Füge verfügbare Drucker hinzu + availablePrinters.forEach(printer => { const option = document.createElement('option'); option.value = printer.id; - option.textContent = `${printer.name} (${printer.model || 'Unbekanntes Modell'})`; + + // Status-Indikator hinzufügen + const statusText = printer.status === 'available' ? '✅ Verfügbar' : '⚠️ Status unbekannt'; + option.textContent = `${printer.name} (${printer.model || 'Unbekanntes Modell'}) - ${statusText}`; printerSelect.appendChild(option); }); + + showNotification(`${availablePrinters.length} verfügbare Drucker geladen`, 'success'); }) .catch(error => { console.error('Fehler beim Laden der Drucker:', error); - showNotification('Fehler beim Laden der Drucker', 'error'); + + // Fallback: Versuche normale Drucker-API + fetch('/api/printers') + .then(response => response.json()) + .then(data => { + const printerSelect = document.getElementById('printer_id'); + const printers = data.printers || []; + + if (printers.length === 0) { + printerSelect.innerHTML = ''; + showNotification('Keine Drucker gefunden', 'error'); + return; + } + + printers.forEach(printer => { + const option = document.createElement('option'); + option.value = printer.id; + option.textContent = `${printer.name} (${printer.model || 'Unbekanntes Modell'}) - Status unbekannt`; + printerSelect.appendChild(option); + }); + + showNotification(`${printers.length} Drucker geladen (ohne Status-Check)`, 'warning'); + }) + .catch(fallbackError => { + console.error('Auch Fallback-API fehlgeschlagen:', fallbackError); + showNotification('Fehler beim Laden der Drucker', 'error'); + }); }); } diff --git a/backend/app/templates/new_job.html b/backend/app/templates/new_job.html index 9d6ed430e..3a1e04fea 100644 --- a/backend/app/templates/new_job.html +++ b/backend/app/templates/new_job.html @@ -187,29 +187,60 @@ // Load available printers async function loadPrinters() { try { - const response = await apiCall('/api/printers'); - printers = response.printers || []; + // Versuche zuerst Status-Check API für bessere Verfügbarkeitsprüfung + let response; + try { + response = await apiCall('/api/printers/status'); + printers = Array.isArray(response) ? response : (response.printers || []); + } catch (statusError) { + console.log('Status-API fehlgeschlagen, verwende normale API:', statusError); + response = await apiCall('/api/printers'); + printers = response.printers || []; + } const select = document.getElementById('printer-select'); select.innerHTML = ''; - // Only show available printers - const availablePrinters = printers.filter(p => p.status === 'available'); + console.log('Geladene Drucker:', printers); + + // Filtere verfügbare Drucker (status: 'available' oder active: true) + const availablePrinters = printers.filter(p => { + return p.status === 'available' || p.active === true; + }); + + console.log('Verfügbare Drucker:', availablePrinters); if (availablePrinters.length === 0) { - select.innerHTML = ''; - select.disabled = true; - showFlashMessage('Derzeit sind keine Drucker verfügbar', 'warning'); + // Zeige alle Drucker an, falls keine als verfügbar markiert sind + if (printers.length > 0) { + printers.forEach(printer => { + const option = document.createElement('option'); + option.value = printer.id; + option.textContent = `${printer.name} (${printer.location || printer.model || 'Unbekanntes Modell'}) - Status unbekannt`; + select.appendChild(option); + }); + showFlashMessage(`${printers.length} Drucker geladen (Status unbekannt)`, 'warning'); + } else { + select.innerHTML = ''; + select.disabled = true; + showFlashMessage('Keine Drucker in der Datenbank gefunden', 'error'); + } return; } availablePrinters.forEach(printer => { const option = document.createElement('option'); option.value = printer.id; - option.textContent = `${printer.name} (${printer.location})`; + + // Status-Indikator hinzufügen + const statusText = printer.status === 'available' ? '✅ Verfügbar' : '⚠️ Status unbekannt'; + const location = printer.location || printer.model || 'Unbekanntes Modell'; + option.textContent = `${printer.name} (${location}) - ${statusText}`; select.appendChild(option); }); + showFlashMessage(`${availablePrinters.length} verfügbare Drucker geladen`, 'success'); + } catch (error) { console.error('Error loading printers:', error); showFlashMessage('Fehler beim Laden der Drucker', 'error');