From b87d43c64e8466474fad37f534c4f7bf1b818d03 Mon Sep 17 00:00:00 2001 From: Manuel Weiser Date: Tue, 25 Feb 2025 16:24:22 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20f=C3=BCge=20Unterst=C3=BCtzung=20f?= =?UTF-8?q?=C3=BCr=20Spoolman-Einstellungen=20hinzu=20und=20aktualisiere?= =?UTF-8?q?=20die=20Benutzeroberfl=C3=A4che?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/rfid.js | 46 ++++++++++++++++++++++++++++++++++++++ html/set_spoolman.png | Bin 0 -> 9444 bytes html/style.css | 5 ++++- src/api.cpp | 50 ++++++++++++++++++++++++++++++++++++++++-- src/api.h | 1 + src/website.cpp | 18 +++++++++++++++ 6 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 html/set_spoolman.png diff --git a/html/rfid.js b/html/rfid.js index ccc9097..cece33f 100644 --- a/html/rfid.js +++ b/html/rfid.js @@ -150,6 +150,13 @@ function initWebSocket() { ramStatus.textContent = `${data.freeHeap}k`; } } + else if (data.type === 'setSpoolmanSettings') { + if (data.payload == 'success') { + showNotification(`Spoolman Settings set successfully`, true); + } else { + showNotification(`Error setting Spoolman Settings`, false); + } + } }; } catch (error) { isConnected = false; @@ -285,6 +292,14 @@ function displayAmsData(amsData) { Spool In `; + const spoolmanButtonHtml = ` + `; + if (!hasAnyContent) { return `
@@ -348,6 +363,7 @@ function displayAmsData(amsData) { ${trayDetails} ${tempHTML} ${(ams.ams_id === 255 && tray.tray_type !== '') ? outButtonHtml : ''} + ${(tray.setting_id != "" && tray.setting_id != "null") ? spoolmanButtonHtml : ''}
`; @@ -373,6 +389,36 @@ function updateSpoolButtons(show) { }); } +function handleSpoolmanSettings(tray_info_idx, setting_id, cali_idx, nozzle_temp_min, nozzle_temp_max) { + // Hole das ausgewählte Filament + const selectedText = document.getElementById("selected-filament").textContent; + + // Finde die ausgewählte Spule in den Daten + const selectedSpool = spoolsData.find(spool => + `${spool.id} | ${spool.filament.name} (${spool.filament.material})` === selectedText + ); + + const payload = { + type: 'setSpoolmanSettings', + payload: { + filament_id: selectedSpool.filament.id, + tray_info_idx: tray_info_idx, + setting_id: setting_id, + cali_idx: cali_idx, + temp_min: nozzle_temp_min, + temp_max: nozzle_temp_max + } + }; + + try { + socket.send(JSON.stringify(payload)); + showNotification(`Setting send to Spoolman`, true); + } catch (error) { + console.error("Error while sending settings to Spoolman:", error); + showNotification("Error while sending!", false); + } +} + function handleSpoolOut() { // Erstelle Payload const payload = { diff --git a/html/set_spoolman.png b/html/set_spoolman.png new file mode 100644 index 0000000000000000000000000000000000000000..2ec6c22f1a9c87861c9cd1493a1664693ba2abbe GIT binary patch literal 9444 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 qaQQxre(); + Serial.print("Update Spule mit URL: "); + Serial.println(spoolsUrl); + + JsonDocument updateDoc; + updateDoc["extra"]["bambu_setting_id"] = "\"" + doc["setting_id"].as() + "\""; + updateDoc["extra"]["bambu_cali_id"] = "\"" + doc["cali_idx"].as() + "\""; + updateDoc["extra"]["bambu_idx"] = "\"" + doc["tray_info_idx"].as() + "\""; + updateDoc["extra"]["nozzle_temperature"] = "[" + doc["temp_min"].as() + "," + doc["temp_max"].as() + "]"; + + String updatePayload; + serializeJson(updateDoc, updatePayload); + Serial.print("Update Payload: "); + Serial.println(updatePayload); + + SendToApiParams* params = new SendToApiParams(); + if (params == nullptr) { + Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren."); + return false; + } + params->httpType = "PATCH"; + params->spoolsUrl = spoolsUrl; + params->updatePayload = updatePayload; + + // Erstelle die Task + BaseType_t result = xTaskCreate( + sendToApi, // Task-Funktion + "SendToApiTask", // Task-Name + 4096, // Stackgröße in Bytes + (void*)params, // Parameter + 0, // Priorität + NULL // Task-Handle (nicht benötigt) + ); + + return true; +} + // #### Spoolman init bool checkSpoolmanExtraFields() { HTTPClient http; diff --git a/src/api.h b/src/api.h index 4132b0a..da9562a 100644 --- a/src/api.h +++ b/src/api.h @@ -18,5 +18,6 @@ JsonDocument fetchSingleSpoolInfo(int spoolId); // API-Funktion für die Webseit bool updateSpoolTagId(String uidString, const char* payload); // Neue Funktion zum Aktualisieren eines Spools uint8_t updateSpoolWeight(String spoolId, uint16_t weight); // Neue Funktion zum Aktualisieren des Gewichts bool initSpoolman(); // Neue Funktion zum Initialisieren von Spoolman +bool updateSpoolBambuData(String payload); // Neue Funktion zum Aktualisieren der Bambu-Daten #endif diff --git a/src/website.cpp b/src/website.cpp index 296bdaa..5098394 100644 --- a/src/website.cpp +++ b/src/website.cpp @@ -95,6 +95,15 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp setBambuSpool(doc["payload"]); } + else if (doc["type"] == "setSpoolmanSettings") { + Serial.println(doc["payload"].as()); + if (updateSpoolBambuData(doc["payload"].as())) { + ws.textAll("{\"type\":\"setSpoolmanSettings\",\"payload\":\"success\"}"); + } else { + ws.textAll("{\"type\":\"setSpoolmanSettings\",\"payload\":\"error\"}"); + } + } + else { Serial.println("Unbekannter WebSocket-Typ: " + doc["type"].as()); } @@ -346,6 +355,15 @@ void setupWebserver(AsyncWebServer &server) { Serial.println("spool_in.png gesendet"); }); + // Route für set_spoolman.png + server.on("/set_spoolman.png", HTTP_GET, [](AsyncWebServerRequest *request){ + AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/set_spoolman.png.gz", "image/png"); + response->addHeader("Content-Encoding", "gzip"); + response->addHeader("Cache-Control", CACHE_CONTROL); + request->send(response); + Serial.println("set_spoolman.png gesendet"); + }); + // Route für JavaScript Dateien server.on("/spoolman.js", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println("Anfrage für /spoolman.js erhalten");