diff --git a/html/spoolman.html b/html/spoolman.html
index fd3420c..ddcb430 100644
--- a/html/spoolman.html
+++ b/html/spoolman.html
@@ -74,8 +74,9 @@
const ip = document.getElementById('bambuIp').value;
const serial = document.getElementById('bambuSerial').value;
const code = document.getElementById('bambuCode').value;
+ const autoSend = document.getElementById('autoSend').checked;
- fetch(`/api/bambu?bambu_ip=${encodeURIComponent(ip)}&bambu_serialnr=${encodeURIComponent(serial)}&bambu_accesscode=${encodeURIComponent(code)}`)
+ fetch(`/api/bambu?bambu_ip=${encodeURIComponent(ip)}&bambu_serialnr=${encodeURIComponent(serial)}&bambu_accesscode=${encodeURIComponent(code)}&autoSend=${autoSend}`)
.then(response => response.json())
.then(data => {
if (data.healthy) {
@@ -121,6 +122,12 @@
+
+ If activated, FilaMan will automatically update the next filled tray with the last scanned and weighed spool.
+
+
+
+
diff --git a/src/api.cpp b/src/api.cpp
index e3b13ef..5289f32 100644
--- a/src/api.cpp
+++ b/src/api.cpp
@@ -37,9 +37,9 @@ struct SendToApiParams {
}
*/
-JsonDocument fetchSpoolsForWebsite() {
+JsonDocument fetchSingleSpoolInfo(int spoolId) {
HTTPClient http;
- String spoolsUrl = spoolmanUrl + apiUrl + "/spool";
+ String spoolsUrl = spoolmanUrl + apiUrl + "/spool/" + spoolId;
Serial.print("Rufe Spool-Daten von: ");
Serial.println(spoolsUrl);
@@ -56,84 +56,45 @@ JsonDocument fetchSpoolsForWebsite() {
Serial.print("Fehler beim Parsen der JSON-Antwort: ");
Serial.println(error.c_str());
} else {
- JsonArray spools = doc.as();
- JsonArray filteredSpools = filteredDoc.to();
+ String filamentType = doc["filament"]["material"].as();
+ String filamentBrand = doc["filament"]["vendor"]["name"].as();
- for (JsonObject spool : spools) {
- JsonObject filteredSpool = filteredSpools.add();
- filteredSpool["extra"]["nfc_id"] = spool["extra"]["nfc_id"];
+ int nozzle_temp_min = 0;
+ int nozzle_temp_max = 0;
+ if (doc["filament"]["extra"]["nozzle_temperature"].is()) {
+ String tempString = doc["filament"]["extra"]["nozzle_temperature"].as();
+ tempString.replace("[", "");
+ tempString.replace("]", "");
+ int commaIndex = tempString.indexOf(',');
+
+ if (commaIndex != -1) {
+ nozzle_temp_min = tempString.substring(0, commaIndex).toInt();
+ nozzle_temp_max = tempString.substring(commaIndex + 1).toInt();
+ }
+ }
- JsonObject filament = filteredSpool["filament"].to();
- filament["sm_id"] = spool["id"];
- filament["id"] = spool["filament"]["id"];
- filament["name"] = spool["filament"]["name"];
- filament["material"] = spool["filament"]["material"];
- filament["color_hex"] = spool["filament"]["color_hex"];
- filament["nozzle_temperature"] = spool["filament"]["extra"]["nozzle_temperature"]; // [190,230]
- filament["price_meter"] = spool["filament"]["extra"]["price_meter"];
- filament["price_gramm"] = spool["filament"]["extra"]["price_gramm"];
+ String filamentColor = doc["filament"]["color_hex"].as();
+ filamentColor.toUpperCase();
- JsonObject vendor = filament["vendor"].to();
- vendor["id"] = spool["filament"]["vendor"]["id"];
- vendor["name"] = spool["filament"]["vendor"]["name"];
- }
- }
- } else {
- Serial.print("Fehler beim Abrufen der Spool-Daten. HTTP-Code: ");
- Serial.println(httpCode);
- }
+ String tray_info_idx = doc["filament"]["extra"]["bambu_idx"].as();
+ tray_info_idx.replace("\"", "");
+
+ String cali_idx = doc["filament"]["extra"]["bambu_cali_id"].as(); // "\"153\""
+ cali_idx.replace("\"", "");
+
+ String bambu_setting_id = doc["filament"]["extra"]["bambu_setting_id"].as(); // "\"PFUSf40e9953b40d3d\""
+ bambu_setting_id.replace("\"", "");
- http.end();
- return filteredDoc;
-}
+ doc.clear();
-JsonDocument fetchAllSpoolsInfo() {
- HTTPClient http;
- String spoolsUrl = spoolmanUrl + apiUrl + "/spool";
-
- Serial.print("Rufe Spool-Daten von: ");
- Serial.println(spoolsUrl);
-
- http.begin(spoolsUrl);
- int httpCode = http.GET();
-
- JsonDocument filteredDoc;
- if (httpCode == HTTP_CODE_OK) {
- String payload = http.getString();
- JsonDocument doc;
- DeserializationError error = deserializeJson(doc, payload);
- if (error) {
- Serial.print("Fehler beim Parsen der JSON-Antwort: ");
- Serial.println(error.c_str());
- } else {
- JsonArray spools = doc.as();
- JsonArray filteredSpools = filteredDoc.to();
-
- for (JsonObject spool : spools) {
- JsonObject filteredSpool = filteredSpools.add();
- filteredSpool["price"] = spool["price"];
- filteredSpool["remaining_weight"] = spool["remaining_weight"];
- filteredSpool["used_weight"] = spool["used_weight"];
- filteredSpool["extra"]["nfc_id"] = spool["extra"]["nfc_id"];
-
- JsonObject filament = filteredSpool["filament"].to();
- filament["id"] = spool["filament"]["id"];
- filament["name"] = spool["filament"]["name"];
- filament["material"] = spool["filament"]["material"];
- filament["density"] = spool["filament"]["density"];
- filament["diameter"] = spool["filament"]["diameter"];
- filament["spool_weight"] = spool["filament"]["spool_weight"];
- filament["color_hex"] = spool["filament"]["color_hex"];
-
- JsonObject vendor = filament["vendor"].to();
- vendor["id"] = spool["filament"]["vendor"]["id"];
- vendor["name"] = spool["filament"]["vendor"]["name"];
-
- JsonObject extra = filament["extra"].to();
- extra["nozzle_temperature"] = spool["filament"]["extra"]["nozzle_temperature"];
- extra["price_gramm"] = spool["filament"]["extra"]["price_gramm"];
- extra["price_meter"] = spool["filament"]["extra"]["price_meter"];
- }
+ filteredDoc["color"] = filamentColor;
+ filteredDoc["type"] = filamentType;
+ filteredDoc["nozzle_temp_min"] = nozzle_temp_min;
+ filteredDoc["nozzle_temp_max"] = nozzle_temp_max;
+ filteredDoc["brand"] = filamentBrand;
+ filteredDoc["tray_info_idx"] = tray_info_idx;
+ filteredDoc["cali_idx"] = cali_idx;
+ filteredDoc["bambu_setting_id"] = bambu_setting_id;
}
} else {
Serial.print("Fehler beim Abrufen der Spool-Daten. HTTP-Code: ");
diff --git a/src/api.h b/src/api.h
index 3b80c93..7a5a5cb 100644
--- a/src/api.h
+++ b/src/api.h
@@ -14,8 +14,7 @@ bool checkSpoolmanInstance(const String& url);
bool saveSpoolmanUrl(const String& url);
String loadSpoolmanUrl(); // Neue Funktion zum Laden der URL
bool checkSpoolmanExtraFields(); // Neue Funktion zum Überprüfen der Extrafelder
-JsonDocument fetchSpoolsForWebsite(); // API-Funktion für die Webseite
-JsonDocument fetchAllSpoolsInfo();
+JsonDocument fetchSingleSpoolInfo(int spoolId); // API-Funktion für die Webseite
void sendAmsData(AsyncWebSocketClient *client); // Neue Funktion zum Senden von AMS-Daten
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
diff --git a/src/bambu.cpp b/src/bambu.cpp
index e86f63e..8736f30 100644
--- a/src/bambu.cpp
+++ b/src/bambu.cpp
@@ -24,13 +24,15 @@ const char* bambu_ip = nullptr;
const char* bambu_accesscode = nullptr;
const char* bambu_serialnr = nullptr;
bool bambu_connected = false;
+bool autoSendToBambu = false;
+int autoSetToBambuSpoolId = 0;
// Globale Variablen für AMS-Daten
int ams_count = 0;
String amsJsonData; // Speichert das fertige JSON für WebSocket-Clients
-AMSData ams_data[MAX_AMS]; // Definition des Arrays
+AMSData ams_data[MAX_AMS]; // Definition des Arrays;
-bool saveBambuCredentials(const String& ip, const String& serialnr, const String& accesscode) {
+bool saveBambuCredentials(const String& ip, const String& serialnr, const String& accesscode, bool autoSend) {
if (BambuMqttTask) {
vTaskDelete(BambuMqttTask);
}
@@ -39,6 +41,7 @@ bool saveBambuCredentials(const String& ip, const String& serialnr, const String
doc["bambu_ip"] = ip;
doc["bambu_accesscode"] = accesscode;
doc["bambu_serialnr"] = serialnr;
+ doc["autoSendToBambu"] = autoSend;
if (!saveJsonValue("/bambu_credentials.json", doc)) {
Serial.println("Fehler beim Speichern der Bambu-Credentials.");
@@ -49,6 +52,7 @@ bool saveBambuCredentials(const String& ip, const String& serialnr, const String
bambu_ip = ip.c_str();
bambu_accesscode = accesscode.c_str();
bambu_serialnr = serialnr.c_str();
+ autoSendToBambu = autoSend;
vTaskDelay(100 / portTICK_PERIOD_MS);
if (!setupMqtt()) return false;
@@ -63,6 +67,7 @@ bool loadBambuCredentials() {
String ip = doc["bambu_ip"].as();
String code = doc["bambu_accesscode"].as();
String serial = doc["bambu_serialnr"].as();
+ autoSendToBambu = doc["autoSendToBambu"].as();
ip.trim();
code.trim();
@@ -256,6 +261,26 @@ bool setBambuSpool(String payload) {
return true;
}
+void autoSetSpool(int spoolId, uint8_t trayId) {
+ // wenn neue spule erkannt und autoSetToBambu > 0
+ JsonDocument spoolInfo = fetchSingleSpoolInfo(spoolId);
+
+ if (!spoolInfo.isNull())
+ {
+ // AMS und TRAY id ergänzen
+ spoolInfo["amsId"] = 0;
+ spoolInfo["trayId"] = trayId;
+
+ Serial.println("Auto set spool");
+ Serial.println(spoolInfo.as());
+
+ setBambuSpool(spoolInfo.as());
+ }
+
+ // id wieder zurücksetzen damit abgeschlossen
+ autoSetToBambuSpoolId = 0;
+}
+
// init
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
String message;
@@ -267,16 +292,27 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
// JSON-Dokument parsen
JsonDocument doc;
DeserializationError error = deserializeJson(doc, message);
- if (error) {
+ if (error)
+ {
Serial.print("Fehler beim Parsen des JSON: ");
Serial.println(error.c_str());
return;
}
+ // Wenn bambu auto set spool aktiv und eine spule erkannt und mqtt meldung das neue spule im ams
+ if (autoSendToBambu && autoSetToBambuSpoolId > 0 &&
+ doc["print"]["command"].as() == "push_status" && doc["print"]["ams"]["tray_pre"].as()
+ && !doc["print"]["ams"]["ams"].as())
+ {
+ autoSetSpool(autoSetToBambuSpoolId, doc["print"]["ams"]["tray_pre"].as());
+ }
+
// Prüfen, ob "print->upgrade_state" und "print.ams.ams" existieren
- if (doc["print"]["upgrade_state"].is()) {
+ if (doc["print"]["upgrade_state"].is())
+ {
// Prüfen ob AMS-Daten vorhanden sind
- if (!doc["print"]["ams"].is() || !doc["print"]["ams"]["ams"].is()) {
+ if (!doc["print"]["ams"].is() || !doc["print"]["ams"]["ams"].is())
+ {
return;
}
@@ -470,7 +506,7 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
- Serial.print("Attempting MQTT connection...");
+ Serial.println("Attempting MQTT connection...");
bambu_connected = false;
oledShowTopRow();
diff --git a/src/bambu.h b/src/bambu.h
index 6584bff..61f68fa 100644
--- a/src/bambu.h
+++ b/src/bambu.h
@@ -28,9 +28,11 @@ extern bool bambu_connected;
extern int ams_count;
extern AMSData ams_data[MAX_AMS];
+extern bool autoSendToBambu;
+extern int autoSetToBambuSpoolId;
bool loadBambuCredentials();
-bool saveBambuCredentials(const String& bambu_ip, const String& bambu_serialnr, const String& bambu_accesscode);
+bool saveBambuCredentials(const String& bambu_ip, const String& bambu_serialnr, const String& bambu_accesscode, const bool autoSend);
bool setupMqtt();
void mqtt_loop(void * parameter);
bool setBambuSpool(String payload);
diff --git a/src/config.cpp b/src/config.cpp
index 6b50d42..8c6e814 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -40,6 +40,10 @@ const uint8_t webserverPort = 80;
const char* apiUrl = "/api/v1";
// ***** API
+// ***** Bambu Auto Set Spool
+uint8_t autoSetBambuAmsCounter = 60;
+// ***** Bambu Auto Set Spool
+
// ***** Task Prios
uint8_t rfidTaskCore = 1;
uint8_t rfidTaskPrio = 1;
diff --git a/src/config.h b/src/config.h
index 8cb867e..822ff8d 100644
--- a/src/config.h
+++ b/src/config.h
@@ -23,6 +23,8 @@ extern const uint8_t OLED_DATA_END;
extern const char* apiUrl;
extern const uint8_t webserverPort;
+extern uint8_t autoSetBambuAmsCounter;
+
extern const unsigned char wifi_on[];
extern const unsigned char wifi_off[];
extern const unsigned char cloud_on[];
diff --git a/src/main.cpp b/src/main.cpp
index d089ad6..57841f1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -90,6 +90,10 @@ void setup() {
unsigned long lastWeightReadTime = 0;
const unsigned long weightReadInterval = 1000; // 1 second
+unsigned long lastAutoSetBambuAmsTime = 0;
+const unsigned long autoSetBambuAmsInterval = 1000; // 1 second
+uint8_t autoAmsCounter = 0;
+
unsigned long lastAmsSendTime = 0;
const unsigned long amsSendInterval = 60000; // 1 minute
@@ -108,6 +112,22 @@ void loop() {
sendAmsData(nullptr);
}
+ // Wenn Bambu auto set Spool aktiv
+ if (autoSendToBambu && autoSetToBambuSpoolId > 0 && currentMillis - lastAutoSetBambuAmsTime >= autoSetBambuAmsInterval)
+ {
+ lastAutoSetBambuAmsTime = currentMillis;
+ oledShowMessage("Auto Set " + String(autoSetBambuAmsCounter - autoAmsCounter) + "s");
+ autoAmsCounter++;
+
+ if (autoAmsCounter >= autoSetBambuAmsCounter)
+ {
+ autoSetToBambuSpoolId = 0;
+ autoAmsCounter = 0;
+ oledShowWeight(weight);
+ }
+ }
+
+
// Wenn Waage nicht Kalibriert
if (scaleCalibrated == 3)
{
@@ -120,7 +140,7 @@ void loop() {
}
// Ausgabe der Waage auf Display
- if (pauseMainTask == 0 && weight != lastWeight && hasReadRfidTag == 0)
+ if (pauseMainTask == 0 && weight != lastWeight && hasReadRfidTag == 0 && (!autoSendToBambu || autoSetToBambuSpoolId == 0))
{
(weight < 2) ? ((weight < -2) ? oledShowMessage("!! -0") : oledShowWeight(0)) : oledShowWeight(weight);
}
@@ -169,6 +189,7 @@ void loop() {
oledShowIcon("success");
vTaskDelay(2000 / portTICK_PERIOD_MS);
weightSend = 1;
+ autoSetToBambuSpoolId = spoolId.toInt();
}
else
{
diff --git a/src/website.cpp b/src/website.cpp
index 9fd9d64..8e5d221 100644
--- a/src/website.cpp
+++ b/src/website.cpp
@@ -351,17 +351,6 @@ void setupWebserver(AsyncWebServer &server) {
Serial.println("RFID-Seite gesendet");
});
- /*
- // Neue API-Route für das Abrufen der Spool-Daten
- server.on("/api/spools", HTTP_GET, [](AsyncWebServerRequest *request){
- Serial.println("API-Aufruf: /api/spools");
- JsonDocument spoolsData = fetchSpoolsForWebsite();
- String response;
- serializeJson(spoolsData, response);
- request->send(200, "application/json", response);
- });
- */
-
server.on("/api/url", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("API-Aufruf: /api/url");
String jsonResponse = "{\"spoolman_url\": \"" + String(spoolmanUrl) + "\"}";
@@ -389,6 +378,7 @@ void setupWebserver(AsyncWebServer &server) {
String bambuIp = doc["bambu_ip"].as();
String bambuSerial = doc["bambu_serialnr"].as();
String bambuCode = doc["bambu_accesscode"].as();
+ autoSendToBambu = doc["autoSendToBambu"].as();
bambuIp.trim();
bambuSerial.trim();
bambuCode.trim();
@@ -396,12 +386,14 @@ void setupWebserver(AsyncWebServer &server) {
html.replace("{{bambuIp}}", bambuIp ? bambuIp : "");
html.replace("{{bambuSerial}}", bambuSerial ? bambuSerial : "");
html.replace("{{bambuCode}}", bambuCode ? bambuCode : "");
+ html.replace("{{autoSendToBambu}}", autoSendToBambu ? "checked" : "");
}
else
{
html.replace("{{bambuIp}}", "");
html.replace("{{bambuSerial}}", "");
html.replace("{{bambuCode}}", "");
+ html.replace("{{autoSendToBambu}}", "");
}
request->send(200, "text/html", html);
@@ -433,6 +425,8 @@ void setupWebserver(AsyncWebServer &server) {
String bambu_ip = request->getParam("bambu_ip")->value();
String bambu_serialnr = request->getParam("bambu_serialnr")->value();
String bambu_accesscode = request->getParam("bambu_accesscode")->value();
+ bool autoSend = (request->getParam("autoSend")->value() == "true") ? true : false;
+ Serial.println(autoSend);
bambu_ip.trim();
bambu_serialnr.trim();
bambu_accesscode.trim();
@@ -442,7 +436,7 @@ void setupWebserver(AsyncWebServer &server) {
return;
}
- bool success = saveBambuCredentials(bambu_ip, bambu_serialnr, bambu_accesscode);
+ bool success = saveBambuCredentials(bambu_ip, bambu_serialnr, bambu_accesscode, autoSend);
request->send(200, "application/json", "{\"healthy\": " + String(success ? "true" : "false") + "}");
});