add OctoPrint integration with configurable fields and update functionality
This commit is contained in:
parent
eb2a8dc128
commit
7a2c9d6d17
@ -52,11 +52,18 @@
|
|||||||
if (spoolmanUrl && spoolmanUrl.trim() !== "") {
|
if (spoolmanUrl && spoolmanUrl.trim() !== "") {
|
||||||
document.getElementById('spoolmanUrl').value = spoolmanUrl;
|
document.getElementById('spoolmanUrl').value = spoolmanUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize OctoPrint fields visibility
|
||||||
|
toggleOctoFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
function checkSpoolmanInstance() {
|
function checkSpoolmanInstance() {
|
||||||
const url = document.getElementById('spoolmanUrl').value;
|
const url = document.getElementById('spoolmanUrl').value;
|
||||||
fetch(`/api/checkSpoolman?url=${encodeURIComponent(url)}`)
|
const spoolmanOctoEnabled = document.getElementById('spoolmanOctoEnabled').checked;
|
||||||
|
const spoolmanOctoUrl = document.getElementById('spoolmanOctoUrl').value;
|
||||||
|
const spoolmanOctoToken = document.getElementById('spoolmanOctoToken').value;
|
||||||
|
|
||||||
|
fetch(`/api/checkSpoolman?url=${encodeURIComponent(url)}&octoEnabled=${spoolmanOctoEnabled}&octoUrl=${spoolmanOctoUrl}&octoToken=${spoolmanOctoToken}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.healthy) {
|
if (data.healthy) {
|
||||||
@ -90,6 +97,15 @@
|
|||||||
document.getElementById('bambuStatusMessage').innerText = 'Error while saving: ' + error.message;
|
document.getElementById('bambuStatusMessage').innerText = 'Error while saving: ' + error.message;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls visibility of OctoPrint configuration fields based on checkbox state
|
||||||
|
* Called on page load and when checkbox changes
|
||||||
|
*/
|
||||||
|
function toggleOctoFields() {
|
||||||
|
const octoEnabled = document.getElementById('spoolmanOctoEnabled').checked;
|
||||||
|
document.getElementById('octoFields').style.display = octoEnabled ? 'block' : 'none';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
var spoolmanUrl = "{{spoolmanUrl}}";
|
var spoolmanUrl = "{{spoolmanUrl}}";
|
||||||
@ -102,6 +118,17 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">Set URL/IP to your Spoolman-Instanz</h5>
|
<h5 class="card-title">Set URL/IP to your Spoolman-Instanz</h5>
|
||||||
<input type="text" id="spoolmanUrl" placeholder="http://ip-or-url-of-your-spoolman-instanz:port">
|
<input type="text" id="spoolmanUrl" placeholder="http://ip-or-url-of-your-spoolman-instanz:port">
|
||||||
|
<h5 class="card-title">If you want to enable sending Spool to Spoolman Octoprint Plugin:</h5>
|
||||||
|
<p>
|
||||||
|
<input type="checkbox" id="spoolmanOctoEnabled" {{spoolmanOctoEnabled}} onchange="toggleOctoFields()"> Send to Octo-Plugin
|
||||||
|
</p>
|
||||||
|
<div id="octoFields" style="display: none;">
|
||||||
|
<p>
|
||||||
|
<input type="text" id="spoolmanOctoUrl" placeholder="http://ip-or-url-of-your-octoprint-instanz:port" value="{{spoolmanOctoUrl}}">
|
||||||
|
<input type="text" id="spoolmanOctoToken" placeholder="Your Octoprint Token" value="{{spoolmanOctoToken}}">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button onclick="checkSpoolmanInstance()">Save Spoolman URL</button>
|
<button onclick="checkSpoolmanInstance()">Save Spoolman URL</button>
|
||||||
<p id="statusMessage"></p>
|
<p id="statusMessage"></p>
|
||||||
</div>
|
</div>
|
||||||
|
65
src/api.cpp
65
src/api.cpp
@ -5,11 +5,15 @@
|
|||||||
|
|
||||||
bool spoolman_connected = false;
|
bool spoolman_connected = false;
|
||||||
String spoolmanUrl = "";
|
String spoolmanUrl = "";
|
||||||
|
bool octoEnabled = false;
|
||||||
|
String octoUrl = "";
|
||||||
|
String octoToken = "";
|
||||||
|
|
||||||
struct SendToApiParams {
|
struct SendToApiParams {
|
||||||
String httpType;
|
String httpType;
|
||||||
String spoolsUrl;
|
String spoolsUrl;
|
||||||
String updatePayload;
|
String updatePayload;
|
||||||
|
String octoToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
JsonDocument fetchSingleSpoolInfo(int spoolId) {
|
JsonDocument fetchSingleSpoolInfo(int spoolId) {
|
||||||
@ -87,14 +91,16 @@ void sendToApi(void *parameter) {
|
|||||||
String httpType = params->httpType;
|
String httpType = params->httpType;
|
||||||
String spoolsUrl = params->spoolsUrl;
|
String spoolsUrl = params->spoolsUrl;
|
||||||
String updatePayload = params->updatePayload;
|
String updatePayload = params->updatePayload;
|
||||||
|
String octoToken = params->octoToken;
|
||||||
|
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
http.begin(spoolsUrl);
|
http.begin(spoolsUrl);
|
||||||
http.addHeader("Content-Type", "application/json");
|
http.addHeader("Content-Type", "application/json");
|
||||||
|
if (octoEnabled && octoToken != "") http.addHeader("X-Api-Key", octoToken);
|
||||||
|
|
||||||
int httpCode = http.PUT(updatePayload);
|
int httpCode = http.PUT(updatePayload);
|
||||||
if (httpType == "PATCH") httpCode = http.PATCH(updatePayload);
|
if (httpType == "PATCH") httpCode = http.PATCH(updatePayload);
|
||||||
|
if (httpType == "POST") httpCode = http.POST(updatePayload);
|
||||||
|
|
||||||
if (httpCode == HTTP_CODE_OK) {
|
if (httpCode == HTTP_CODE_OK) {
|
||||||
Serial.println("Spoolman erfolgreich aktualisiert");
|
Serial.println("Spoolman erfolgreich aktualisiert");
|
||||||
@ -198,6 +204,43 @@ uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool updateSpoolOcto(int spoolId) {
|
||||||
|
String spoolsUrl = octoUrl + "/plugin/Spoolman/selectSpool";
|
||||||
|
Serial.print("Update Spule in Octoprint mit URL: ");
|
||||||
|
Serial.println(spoolsUrl);
|
||||||
|
|
||||||
|
JsonDocument updateDoc;
|
||||||
|
updateDoc["spool_id"] = spoolId;
|
||||||
|
updateDoc["tool"] = "tool0";
|
||||||
|
|
||||||
|
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 = "POST";
|
||||||
|
params->spoolsUrl = spoolsUrl;
|
||||||
|
params->updatePayload = updatePayload;
|
||||||
|
params->octoToken = octoToken;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
bool updateSpoolBambuData(String payload) {
|
bool updateSpoolBambuData(String payload) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
DeserializationError error = deserializeJson(doc, payload);
|
DeserializationError error = deserializeJson(doc, payload);
|
||||||
@ -435,17 +478,24 @@ bool checkSpoolmanInstance(const String& url) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool saveSpoolmanUrl(const String& url) {
|
bool saveSpoolmanUrl(const String& url, bool octoOn, const String& octoWh, const String& octoTk) {
|
||||||
if (!checkSpoolmanInstance(url)) return false;
|
if (!checkSpoolmanInstance(url)) return false;
|
||||||
|
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc["url"] = url;
|
doc["url"] = url;
|
||||||
Serial.print("Speichere URL in Datei: ");
|
doc["octoEnabled"] = octoOn;
|
||||||
Serial.println(url);
|
doc["octoUrl"] = octoWh;
|
||||||
|
doc["octoToken"] = octoTk;
|
||||||
|
Serial.print("Speichere Spoolman Data in Datei: ");
|
||||||
|
Serial.println(doc.as<String>());
|
||||||
if (!saveJsonValue("/spoolman_url.json", doc)) {
|
if (!saveJsonValue("/spoolman_url.json", doc)) {
|
||||||
Serial.println("Fehler beim Speichern der Spoolman-URL.");
|
Serial.println("Fehler beim Speichern der Spoolman-URL.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
spoolmanUrl = url;
|
spoolmanUrl = url;
|
||||||
|
octoEnabled = octoOn;
|
||||||
|
octoUrl = octoWh;
|
||||||
|
octoToken = octoTk;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -453,6 +503,13 @@ bool saveSpoolmanUrl(const String& url) {
|
|||||||
String loadSpoolmanUrl() {
|
String loadSpoolmanUrl() {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
if (loadJsonValue("/spoolman_url.json", doc) && doc["url"].is<String>()) {
|
if (loadJsonValue("/spoolman_url.json", doc) && doc["url"].is<String>()) {
|
||||||
|
octoEnabled = (doc["octoEnabled"].is<bool>()) ? doc["octoEnabled"].as<bool>() : false;
|
||||||
|
if (octoEnabled && doc["octoToken"].is<String>() && doc["octoUrl"].is<String>())
|
||||||
|
{
|
||||||
|
octoUrl = doc["octoUrl"].as<String>();
|
||||||
|
octoToken = doc["octoToken"].as<String>();
|
||||||
|
}
|
||||||
|
|
||||||
return doc["url"].as<String>();
|
return doc["url"].as<String>();
|
||||||
}
|
}
|
||||||
Serial.println("Keine gültige Spoolman-URL gefunden.");
|
Serial.println("Keine gültige Spoolman-URL gefunden.");
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
|
|
||||||
extern bool spoolman_connected;
|
extern bool spoolman_connected;
|
||||||
extern String spoolmanUrl;
|
extern String spoolmanUrl;
|
||||||
|
extern bool octoEnabled;
|
||||||
|
extern String octoUrl;
|
||||||
|
extern String octoToken;
|
||||||
|
|
||||||
bool checkSpoolmanInstance(const String& url);
|
bool checkSpoolmanInstance(const String& url);
|
||||||
bool saveSpoolmanUrl(const String& url);
|
bool saveSpoolmanUrl(const String& url, bool octoOn, const String& octoWh, const String& octoTk);
|
||||||
String loadSpoolmanUrl(); // Neue Funktion zum Laden der URL
|
String loadSpoolmanUrl(); // Neue Funktion zum Laden der URL
|
||||||
bool checkSpoolmanExtraFields(); // Neue Funktion zum Überprüfen der Extrafelder
|
bool checkSpoolmanExtraFields(); // Neue Funktion zum Überprüfen der Extrafelder
|
||||||
JsonDocument fetchSingleSpoolInfo(int spoolId); // API-Funktion für die Webseite
|
JsonDocument fetchSingleSpoolInfo(int spoolId); // API-Funktion für die Webseite
|
||||||
@ -19,5 +22,6 @@ bool updateSpoolTagId(String uidString, const char* payload); // Neue Funktion z
|
|||||||
uint8_t updateSpoolWeight(String spoolId, uint16_t weight); // Neue Funktion zum Aktualisieren des Gewichts
|
uint8_t updateSpoolWeight(String spoolId, uint16_t weight); // Neue Funktion zum Aktualisieren des Gewichts
|
||||||
bool initSpoolman(); // Neue Funktion zum Initialisieren von Spoolman
|
bool initSpoolman(); // Neue Funktion zum Initialisieren von Spoolman
|
||||||
bool updateSpoolBambuData(String payload); // Neue Funktion zum Aktualisieren der Bambu-Daten
|
bool updateSpoolBambuData(String payload); // Neue Funktion zum Aktualisieren der Bambu-Daten
|
||||||
|
bool updateSpoolOcto(int spoolId); // Neue Funktion zum Aktualisieren der Octo-Daten
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,6 +197,11 @@ void loop() {
|
|||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
weightSend = 1;
|
weightSend = 1;
|
||||||
autoSetToBambuSpoolId = spoolId.toInt();
|
autoSetToBambuSpoolId = spoolId.toInt();
|
||||||
|
|
||||||
|
if (octoEnabled)
|
||||||
|
{
|
||||||
|
updateSpoolOcto(autoSetToBambuSpoolId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -239,7 +239,10 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
server.on("/spoolman", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/spoolman", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
Serial.println("Anfrage für /spoolman erhalten");
|
Serial.println("Anfrage für /spoolman erhalten");
|
||||||
String html = loadHtmlWithHeader("/spoolman.html");
|
String html = loadHtmlWithHeader("/spoolman.html");
|
||||||
html.replace("{{spoolmanUrl}}", spoolmanUrl);
|
html.replace("{{spoolmanUrl}}", (spoolmanUrl != "") ? spoolmanUrl : "");
|
||||||
|
html.replace("{{spoolmanOctoEnabled}}", octoEnabled ? "checked" : "");
|
||||||
|
html.replace("{{spoolmanOctoUrl}}", (octoUrl != "") ? octoUrl : "");
|
||||||
|
html.replace("{{spoolmanOctoToken}}", (octoToken != "") ? octoToken : "");
|
||||||
|
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
if (loadJsonValue("/bambu_credentials.json", doc) && doc["bambu_ip"].is<String>())
|
if (loadJsonValue("/bambu_credentials.json", doc) && doc["bambu_ip"].is<String>())
|
||||||
@ -277,10 +280,21 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = request->getParam("url")->value();
|
if (request->getParam("octoEnabled")->value() == "true" && (!request->hasParam("octoUrl") || !request->hasParam("octoToken"))) {
|
||||||
url.trim();
|
request->send(400, "application/json", "{\"success\": false, \"error\": \"Missing OctoPrint URL or Token parameter\"}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool healthy = saveSpoolmanUrl(url);
|
String url = request->getParam("url")->value();
|
||||||
|
bool octoEnabled = (request->getParam("octoEnabled")->value() == "true") ? true : false;
|
||||||
|
String octoUrl = request->getParam("octoUrl")->value();
|
||||||
|
String octoToken = (request->getParam("octoToken")->value() != "") ? request->getParam("octoToken")->value() : "";
|
||||||
|
|
||||||
|
url.trim();
|
||||||
|
octoUrl.trim();
|
||||||
|
octoToken.trim();
|
||||||
|
|
||||||
|
bool healthy = saveSpoolmanUrl(url, octoEnabled, octoUrl, octoToken);
|
||||||
String jsonResponse = "{\"healthy\": " + String(healthy ? "true" : "false") + "}";
|
String jsonResponse = "{\"healthy\": " + String(healthy ? "true" : "false") + "}";
|
||||||
|
|
||||||
request->send(200, "application/json", jsonResponse);
|
request->send(200, "application/json", jsonResponse);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user