Compare commits

...

22 Commits

Author SHA1 Message Date
d490b116b9 docs: update changelog and header for version v1.5.4
All checks were successful
Release Workflow / detect-provider (push) Successful in 1m10s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m52s
2025-07-22 06:36:16 +02:00
5bc6192b6f docs: update platformio.ini for version v1.5.4 2025-07-22 06:36:16 +02:00
2202d9a1aa Merge branch 'main' of github.com:ManuelW77/Filaman 2025-07-22 06:35:13 +02:00
7dbca0ab87 Merge pull request #39 from janecker/location_tags
Adds new feature to write and read location tags
2025-07-22 06:32:44 +02:00
24b3521f83 Merge pull request #38 from janecker/scale_debouncing
Adds slight debouncing to the scale loop weight logic
2025-07-22 06:32:31 +02:00
6c9f290bac fix: uncomment monitor_port configuration in platformio.ini 2025-07-22 06:31:51 +02:00
Jan Philipp Ecker
eab937d6ca Adds new feature to write and read location tags
Location tags can be written via the website. If a location tag is read after reading a spool tag, the location of the spool will be updated in spoolman to the location from the tag.
2025-07-21 21:03:55 +02:00
Jan Philipp Ecker
27ef8399e4 Adds slight debouncing to the scale loop weight logic
Adds slight debouncing to the scale loop to prevent jitter of the
weight displayed on the screen.
2025-06-19 10:08:15 +02:00
2920159f32 add loadcell desc. 2025-05-02 16:44:57 +02:00
2e19bccfa9 docs: update changelog and header for version v1.5.3
All checks were successful
Release Workflow / detect-provider (push) Successful in 1m10s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m25s
2025-04-25 15:52:56 +02:00
859e89431e docs: update platformio.ini for version v1.5.3 2025-04-25 15:52:56 +02:00
6dc26ca51f fix: update spool weight conditionally based on NFC ID 2025-04-25 15:52:38 +02:00
0becae7ed6 Affiliate Links 2025-04-25 09:41:02 +02:00
3d31833f50 docs: update changelog and header for version v1.5.2
All checks were successful
Release Workflow / detect-provider (push) Successful in 1m21s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m9s
2025-04-23 17:47:40 +02:00
599cc47443 docs: update platformio.ini for version v1.5.2 2025-04-23 17:47:40 +02:00
b1f7923770 feat: implement multi-color filament display and styles for dropdown options 2025-04-23 17:47:02 +02:00
c78c20979d fix: add remaining weight logging for PUT requests and improve error reporting in sendToApi function 2025-04-23 14:51:31 +02:00
e79c522e46 fix: add remaining weight logging and display after successful spool update 2025-04-23 11:33:07 +02:00
cf8cce72a5 fix: update weight field in update payload to only include values greater than 10 2025-04-23 11:08:32 +02:00
0b356609d1 fix: add weight field to update payload in updateSpoolTagId function 2025-04-23 11:07:30 +02:00
01f1e123ac fix: increase stack size for sendToApi task to improve stability 2025-04-15 16:38:16 +02:00
012f91851e fix: adjust tare weight tolerance to ignore deviations of 2g 2025-03-31 10:59:54 +02:00
14 changed files with 402 additions and 47 deletions

View File

@@ -1,5 +1,47 @@
# Changelog
## [1.5.4] - 2025-07-22
### Added
- Adds new feature to write and read location tags
- Adds slight debouncing to the scale loop weight logic
- add loadcell desc.
### Changed
- update platformio.ini for version v1.5.4
- Merge branch 'main' of github.com:ManuelW77/Filaman
- Merge pull request #39 from janecker/location_tags
- Merge pull request #38 from janecker/scale_debouncing
### Fixed
- uncomment monitor_port configuration in platformio.ini
## [1.5.3] - 2025-04-25
### Changed
- update platformio.ini for version v1.5.3
- Affiliate Links
### Fixed
- update spool weight conditionally based on NFC ID
## [1.5.2] - 2025-04-23
### Added
- implement multi-color filament display and styles for dropdown options
- add remaining weight logging for PUT requests and improve error reporting in sendToApi function
- add remaining weight logging and display after successful spool update
- add weight field to update payload in updateSpoolTagId function
### Changed
- update platformio.ini for version v1.5.2
### Fixed
- update weight field in update payload to only include values greater than 10
- increase stack size for sendToApi task to improve stability
- adjust tare weight tolerance to ignore deviations of 2g
- improve weight stability check before sending to API
## [1.5.1] - 2025-03-30
### Changed
- update version to 1.5.1 and improve OTA update handling with task management

View File

@@ -54,7 +54,7 @@ Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
## Hardware-Anforderungen
### Komponenten
### Komponenten (Affiliate Links)
- **ESP32 Development Board:** Any ESP32 variant.
[Amazon Link](https://amzn.to/3FHea6D)
- **HX711 5kg Load Cell Amplifier:** For weight measurement.
@@ -90,6 +90,12 @@ Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
![myWiring](./img/IMG_2589.jpeg)
![myWiring](./img/IMG_2590.jpeg)
*Die Wägezelle wird bei den meisten HX711 Modulen folgendermaßen verkabelt:
E+ rot
E- schwarz
A- weiß
A+ grün*
## Software-Abhängigkeiten
### ESP32-Bibliotheken

View File

@@ -58,7 +58,7 @@ Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
## Hardware Requirements
### Components
### Components (Affiliate Links)
- **ESP32 Development Board:** Any ESP32 variant.
[Amazon Link](https://amzn.to/3FHea6D)
- **HX711 5kg Load Cell Amplifier:** For weight measurement.
@@ -94,6 +94,12 @@ Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
![myWiring](./img/IMG_2589.jpeg)
![myWiring](./img/IMG_2590.jpeg)
*The load cell is connected to most HX711 modules as follows:
E+ red
E- black
A- white
A+ green*
## Software Dependencies
### ESP32 Libraries

View File

@@ -139,6 +139,18 @@
<p id="nfcInfo" class="nfc-status"></p>
<button id="writeNfcButton" class="btn btn-primary hidden" onclick="writeNfcTag()">Write Tag</button>
</div>
<div class="feature-box">
<h2>Spoolman Locations</h2>
<label for="locationSelect">Location:</label>
<div style="display: flex; justify-content: space-between; align-items: center;">
<select id="locationSelect" class="styled-select">
<option value="">Please choose...</option>
</select>
</div>
<p id="nfcInfoLocation" class="nfc-status"></p>
<button id="writeLocationNfcButton" class="btn btn-primary hidden" onclick="writeLocationNfcTag()">Write Location Tag</button>
</div>
</div>
</div>

View File

@@ -215,20 +215,6 @@ document.addEventListener('filamentSelected', function (event) {
updateSpoolButtons(selectedText !== "Please choose...");
});
// Hilfsfunktion für kontrastreiche Textfarbe
function getContrastColor(hexcolor) {
// Konvertiere Hex zu RGB
const r = parseInt(hexcolor.substr(0,2),16);
const g = parseInt(hexcolor.substr(2,2),16);
const b = parseInt(hexcolor.substr(4,2),16);
// Berechne Helligkeit (YIQ Formel)
const yiq = ((r*299)+(g*587)+(b*114))/1000;
// Return schwarz oder weiß basierend auf Helligkeit
return (yiq >= 128) ? '#000000' : '#FFFFFF';
}
function updateNfcInfo() {
const selectedText = document.getElementById("selected-filament").textContent;
const nfcInfo = document.getElementById("nfcInfo");
@@ -640,11 +626,11 @@ function writeNfcTag() {
// Erstelle das NFC-Datenpaket mit korrekten Datentypen
const nfcData = {
color_hex: selectedSpool.filament.color_hex || "FFFFFF",
type: selectedSpool.filament.material,
min_temp: minTemp,
max_temp: maxTemp,
brand: selectedSpool.filament.vendor.name,
//color_hex: selectedSpool.filament.color_hex || "FFFFFF",
//type: selectedSpool.filament.material,
//min_temp: minTemp,
//max_temp: maxTemp,
//brand: selectedSpool.filament.vendor.name,
sm_id: String(selectedSpool.id) // Konvertiere zu String
};
@@ -661,16 +647,56 @@ function writeNfcTag() {
}
}
function writeLocationNfcTag() {
const selectedText = document.getElementById("locationSelect").value;
if (selectedText === "Please choose...") {
alert('Please select a location first.');
return;
}
// Erstelle das NFC-Datenpaket mit korrekten Datentypen
const nfcData = {
location: String(selectedText)
};
if (socket?.readyState === WebSocket.OPEN) {
const writeButton = document.getElementById("writeLocationNfcButton");
writeButton.classList.add("writing");
writeButton.textContent = "Writing";
socket.send(JSON.stringify({
type: 'writeNfcTag',
payload: nfcData
}));
} else {
alert('Not connected to Server. Please check connection.');
}
}
function handleWriteNfcTagResponse(success) {
const writeButton = document.getElementById("writeNfcButton");
writeButton.classList.remove("writing");
writeButton.classList.add(success ? "success" : "error");
writeButton.textContent = success ? "Write success" : "Write failed";
const writeLocationButton = document.getElementById("writeLocationNfcButton");
if(writeButton.classList.contains("writing")){
writeButton.classList.remove("writing");
writeButton.classList.add(success ? "success" : "error");
writeButton.textContent = success ? "Write success" : "Write failed";
setTimeout(() => {
writeButton.classList.remove("success", "error");
writeButton.textContent = "Write Tag";
}, 5000);
setTimeout(() => {
writeButton.classList.remove("success", "error");
writeButton.textContent = "Write Tag";
}, 5000);
}
if(writeLocationButton.classList.contains("writing")){
writeLocationButton.classList.remove("writing");
writeLocationButton.classList.add(success ? "success" : "error");
writeLocationButton.textContent = success ? "Write success" : "Write failed";
setTimeout(() => {
writeLocationButton.classList.remove("success", "error");
writeLocationButton.textContent = "Write Location Tag";
}, 5000);
}
}
function showNotification(message, isSuccess) {

View File

@@ -1,6 +1,7 @@
// Globale Variablen
let spoolmanUrl = '';
let spoolsData = [];
let locationData = [];
// Hilfsfunktionen für Datenmanipulation
function processSpoolData(data) {
@@ -133,6 +134,26 @@ function populateVendorDropdown(data, selectedSmId = null) {
}
}
// Dropdown-Funktionen
function populateLocationDropdown(data) {
const locationSelect = document.getElementById("locationSelect");
if (!locationSelect) {
console.error('locationSelect Element nicht gefunden');
return;
}
locationSelect.innerHTML = '<option value="">Bitte wählen...</option>';
// Dropdown mit gefilterten Herstellern befüllen - alphabetisch sortiert
Object.entries(data)
.sort(([, nameA], [, nameB]) => nameA.localeCompare(nameB)) // Sort vendors alphabetically by name
.forEach(([id, name]) => {
const option = document.createElement("option");
option.value = name;
option.textContent = name;
locationSelect.appendChild(option);
});
}
function updateFilamentDropdown(selectedSmId = null) {
const vendorId = document.getElementById("vendorSelect").value;
const dropdownContentInner = document.getElementById("filament-dropdown-content");
@@ -169,9 +190,32 @@ function updateFilamentDropdown(selectedSmId = null) {
option.setAttribute("data-value", spool.filament.id);
option.setAttribute("data-nfc-id", spool.extra.nfc_id || "");
const colorHex = spool.filament.color_hex || 'FFFFFF';
// Generate color representation based on filament type (single or multi color)
let colorHTML = '';
// Check if this is a multicolor filament
if (spool.filament.multi_color_hexes) {
// Parse multi color hexes from comma-separated string
const colors = spool.filament.multi_color_hexes.replace(/#/g, '').split(',');
// Determine the display style based on direction
const direction = spool.filament.multi_color_direction || 'coaxial';
// Generate color circles for each color
colorHTML = '<div class="option-colors">';
colors.forEach(color => {
colorHTML += `<div class="option-color multi-color ${direction}" style="background-color: #${color}"></div>`;
});
colorHTML += '</div>';
} else {
// Single color filament
const colorHex = spool.filament.color_hex || 'FFFFFF';
colorHTML = `<div class="option-color" style="background-color: #${colorHex}"></div>`;
}
option.innerHTML = `
<div class="option-color" style="background-color: #${colorHex}"></div>
${colorHTML}
<span>${spool.id} | ${spool.filament.name} (${spool.filament.material})</span>
`;
@@ -185,12 +229,41 @@ function updateFilamentDropdown(selectedSmId = null) {
}
}
function updateLocationSelect(){
const writeLocationNfcButton = document.getElementById('writeLocationNfcButton');
if(writeLocationNfcButton){
writeLocationNfcButton.classList.remove("hidden");
}
}
function selectFilament(spool) {
const selectedColor = document.getElementById("selected-color");
const selectedText = document.getElementById("selected-filament");
const dropdownContent = document.getElementById("filament-dropdown-content");
selectedColor.style.backgroundColor = `#${spool.filament.color_hex || 'FFFFFF'}`;
// Update the selected color display
if (spool.filament.multi_color_hexes) {
// Handle multicolor filament display in the selection header
const colors = spool.filament.multi_color_hexes.replace(/#/g, '').split(',');
const direction = spool.filament.multi_color_direction || 'coaxial';
// Replace the single color div with multiple color divs
selectedColor.innerHTML = '';
colors.forEach(color => {
const colorDiv = document.createElement('div');
colorDiv.className = `color-segment multi-color ${direction}`;
colorDiv.style.backgroundColor = `#${color}`;
selectedColor.appendChild(colorDiv);
});
// Add multiple color class to the container
selectedColor.classList.add('multi-color-container');
} else {
// Single color filament - reset to default display
selectedColor.innerHTML = '';
selectedColor.classList.remove('multi-color-container');
selectedColor.style.backgroundColor = `#${spool.filament.color_hex || 'FFFFFF'}`;
}
selectedText.textContent = `${spool.id} | ${spool.filament.name} (${spool.filament.material})`;
dropdownContent.classList.remove("show");
@@ -216,10 +289,18 @@ async function initSpoolman() {
const fetchedData = await fetchSpoolData();
spoolsData = processSpoolData(fetchedData);
document.dispatchEvent(new CustomEvent('spoolDataLoaded', {
detail: spoolsData
}));
locationData = await fetchLocationData();
document.dispatchEvent(new CustomEvent('locationDataLoaded', {
detail: locationData
}));
} catch (error) {
console.error('Fehler beim Initialisieren von Spoolman:', error);
document.dispatchEvent(new CustomEvent('spoolmanError', {
@@ -247,6 +328,25 @@ async function fetchSpoolData() {
}
}
async function fetchLocationData() {
try {
if (!spoolmanUrl) {
throw new Error('Spoolman URL ist nicht initialisiert');
}
const response = await fetch(`${spoolmanUrl}/api/v1/location`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Fehler beim Abrufen der Location-Daten:', error);
return [];
}
}
// Event Listener
document.addEventListener('DOMContentLoaded', () => {
initSpoolman();
@@ -255,6 +355,11 @@ document.addEventListener('DOMContentLoaded', () => {
if (vendorSelect) {
vendorSelect.addEventListener('change', () => updateFilamentDropdown());
}
const locationSelect = document.getElementById('locationSelect');
if (locationSelect) {
locationSelect.addEventListener('change', () => updateLocationSelect());
}
const onlyWithoutSmId = document.getElementById('onlyWithoutSmId');
if (onlyWithoutSmId) {
@@ -267,6 +372,10 @@ document.addEventListener('DOMContentLoaded', () => {
document.addEventListener('spoolDataLoaded', (event) => {
populateVendorDropdown(event.detail);
});
document.addEventListener('locationDataLoaded', (event) => {
populateLocationDropdown(event.detail);
});
window.onclick = function(event) {
if (!event.target.closest('.custom-dropdown')) {
@@ -297,6 +406,7 @@ window.getSpoolData = () => spoolsData;
window.setSpoolData = (data) => { spoolsData = data; };
window.reloadSpoolData = initSpoolman;
window.populateVendorDropdown = populateVendorDropdown;
window.populateLocationDropdown = populateLocationDropdown;
window.updateFilamentDropdown = updateFilamentDropdown;
window.toggleFilamentDropdown = () => {
const content = document.getElementById("filament-dropdown-content");

View File

@@ -759,6 +759,50 @@ a:hover {
flex-shrink: 0;
}
/* Multi-color filament styles */
.option-colors {
display: flex;
flex-shrink: 0;
gap: 2px;
}
.multi-color {
width: 14px;
height: 14px;
border-radius: 50%;
border: 1px solid #333;
}
/* Coaxial pattern (horizontal stripes) */
.multi-color.coaxial {
border-radius: 50%;
position: relative;
}
/* Longitudinal pattern (vertical stripes) */
.multi-color.longitudinal {
border-radius: 50%;
position: relative;
}
/* Container for multiple colors in selected display */
.multi-color-container {
display: flex !important;
background: none !important;
border: none !important;
gap: 2px;
align-items: center;
justify-content: flex-start;
width: auto !important;
}
.color-segment {
width: 16px;
height: 16px;
border-radius: 50%;
border: 1px solid #333;
}
.notification {
position: fixed;
top: 20px;
@@ -927,31 +971,35 @@ input[type="submit"]:disabled,
}
/* Schreib-Button */
#writeNfcButton {
#writeNfcButton, #writeLocationNfcButton {
background-color: #007bff;
color: white;
transition: background-color 0.3s, color 0.3s;
width: 160px;
}
#writeNfcButton.writing {
#writeNfcButton.writing, #writeLocationNfcButton.writing {
background-color: #ffc107;
color: black;
width: 160px;
}
#writeNfcButton.success {
#writeNfcButton.success, #writeLocationNfcButton.success {
background-color: #28a745;
color: white;
width: 160px;
}
#writeNfcButton.error {
#writeNfcButton.error, #writeLocationNfcButton.error {
background-color: #dc3545;
color: white;
width: 160px;
}
#writeLocationNfcButton{
width: 250px;
}
@keyframes dots {
0% { content: ""; }
33% { content: "."; }
@@ -959,7 +1007,7 @@ input[type="submit"]:disabled,
100% { content: "..."; }
}
#writeNfcButton.writing::after {
#writeNfcButton.writing::after, #writeLocationNfcButton.writing::after {
content: "...";
animation: dots 1s steps(3, end) infinite;
}

View File

@@ -9,7 +9,7 @@
; https://docs.platformio.org/page/projectconf.html
[common]
version = "1.5.1"
version = "1.5.4"
to_old_version = "1.5.0"
##
@@ -18,6 +18,7 @@ platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
#monitor_port = /dev/cu.usbmodem01
lib_deps =
tzapu/WiFiManager @ ^2.0.17

View File

@@ -11,6 +11,7 @@ String octoUrl = "";
String octoToken = "";
struct SendToApiParams {
SpoolmanApiRequestType requestType;
String httpType;
String spoolsUrl;
String updatePayload;
@@ -90,6 +91,7 @@ void sendToApi(void *parameter) {
SendToApiParams* params = (SendToApiParams*)parameter;
// Extrahiere die Werte
SpoolmanApiRequestType requestType = params->requestType;
String httpType = params->httpType;
String spoolsUrl = params->spoolsUrl;
String updatePayload = params->updatePayload;
@@ -109,8 +111,31 @@ void sendToApi(void *parameter) {
if (httpCode == HTTP_CODE_OK) {
Serial.println("Spoolman erfolgreich aktualisiert");
// Restgewicht der Spule auslesen
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 {
if (requestType == API_REQUEST_SPOOL_WEIGHT_UPDATE) {
uint16_t remaining_weight = doc["remaining_weight"].as<float>();
Serial.print("Aktuelles Gewicht: ");
Serial.println(remaining_weight);
oledShowMessage("Remaining: " + String(remaining_weight) + "g");
}
else if ( requestType == API_REQUEST_SPOOL_LOCATION_UPDATE) {
oledShowMessage("Location updated!");
}
vTaskDelay(3000 / portTICK_PERIOD_MS);
doc.clear();
}
} else {
Serial.println("Fehler beim Senden an Spoolman!");
Serial.println("Fehler beim Senden an Spoolman! HTTP Code: " + String(httpCode));
oledShowMessage("Spoolman update failed");
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
@@ -158,6 +183,7 @@ bool updateSpoolTagId(String uidString, const char* payload) {
Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren.");
return false;
}
params->requestType = API_REQUEST_SPOOL_TAG_ID_UPDATE;
params->httpType = "PATCH";
params->spoolsUrl = spoolsUrl;
params->updatePayload = updatePayload;
@@ -166,7 +192,7 @@ bool updateSpoolTagId(String uidString, const char* payload) {
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
4096, // Stackgröße in Bytes
6144, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
@@ -174,6 +200,9 @@ bool updateSpoolTagId(String uidString, const char* payload) {
updateDoc.clear();
// Update Spool weight
if (weight > 10) updateSpoolWeight(doc["sm_id"].as<String>(), weight);
return true;
}
@@ -196,6 +225,7 @@ uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren.");
return 0;
}
params->requestType = API_REQUEST_SPOOL_WEIGHT_UPDATE;
params->httpType = "PUT";
params->spoolsUrl = spoolsUrl;
params->updatePayload = updatePayload;
@@ -204,7 +234,46 @@ uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
4096, // Stackgröße in Bytes
6144, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
);
updateDoc.clear();
return 1;
}
uint8_t updateSpoolLocation(String spoolId, String location){
String spoolsUrl = spoolmanUrl + apiUrl + "/spool/" + spoolId;
Serial.print("Update Spule mit URL: ");
Serial.println(spoolsUrl);
// Update Payload erstellen
JsonDocument updateDoc;
updateDoc["location"] = location;
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 0;
}
params->requestType = API_REQUEST_SPOOL_LOCATION_UPDATE;
params->httpType = "PATCH";
params->spoolsUrl = spoolsUrl;
params->updatePayload = updatePayload;
// Erstelle die Task
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
6144, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
@@ -234,6 +303,7 @@ bool updateSpoolOcto(int spoolId) {
Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren.");
return false;
}
params->requestType = API_REQUEST_OCTO_SPOOL_UPDATE;
params->httpType = "POST";
params->spoolsUrl = spoolsUrl;
params->updatePayload = updatePayload;
@@ -243,7 +313,7 @@ bool updateSpoolOcto(int spoolId) {
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
4096, // Stackgröße in Bytes
6144, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
@@ -283,6 +353,7 @@ bool updateSpoolBambuData(String payload) {
Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren.");
return false;
}
params->requestType = API_REQUEST_BAMBU_UPDATE;
params->httpType = "PATCH";
params->spoolsUrl = spoolsUrl;
params->updatePayload = updatePayload;
@@ -291,7 +362,7 @@ bool updateSpoolBambuData(String payload) {
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
4096, // Stackgröße in Bytes
6144, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
@@ -487,6 +558,8 @@ bool checkSpoolmanInstance(const String& url) {
return strcmp(status, "healthy") == 0;
}
}
} else {
Serial.println("Error contacting spoolman instance! HTTP Code: " + String(httpCode));
}
http.end();
return false;

View File

@@ -12,6 +12,14 @@ typedef enum {
API_TRANSMITTING
} spoolmanApiStateType;
typedef enum {
API_REQUEST_OCTO_SPOOL_UPDATE,
API_REQUEST_BAMBU_UPDATE,
API_REQUEST_SPOOL_TAG_ID_UPDATE,
API_REQUEST_SPOOL_WEIGHT_UPDATE,
API_REQUEST_SPOOL_LOCATION_UPDATE
} SpoolmanApiRequestType;
extern volatile spoolmanApiStateType spoolmanApiState;
extern bool spoolman_connected;
extern String spoolmanUrl;
@@ -26,6 +34,7 @@ bool checkSpoolmanExtraFields(); // Neue Funktion zum Überprüfen der Extrafeld
JsonDocument fetchSingleSpoolInfo(int spoolId); // API-Funktion für die Webseite
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
uint8_t updateSpoolLocation(String spoolId, String location);
bool initSpoolman(); // Neue Funktion zum Initialisieren von Spoolman
bool updateSpoolBambuData(String payload); // Neue Funktion zum Aktualisieren der Bambu-Daten
bool updateSpoolOcto(int spoolId); // Neue Funktion zum Aktualisieren der Octo-Daten

View File

@@ -674,6 +674,7 @@ bool setupMqtt() {
vTaskDelay(2000 / portTICK_PERIOD_MS);
connected = false;
oledShowTopRow();
autoSetToBambuSpoolId = 0;
}
if (!connected) return false;
@@ -687,6 +688,8 @@ bool setupMqtt() {
}
void bambu_restart() {
Serial.println("Bambu restart");
if (BambuMqttTask) {
vTaskDelete(BambuMqttTask);
delay(10);

View File

@@ -180,7 +180,8 @@ void loop() {
lastWeightReadTime = currentMillis;
// Prüfen ob die Waage korrekt genullt ist
if (autoTare && (weight > 0 && weight < 5) || weight < 0)
// Abweichung von 2g ignorieren
if (autoTare && (weight > 2 && weight < 7) || weight < -2)
{
scale_tare_counter++;
}

View File

@@ -218,11 +218,25 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage) {
// Sende die aktualisierten AMS-Daten an alle WebSocket-Clients
Serial.println("JSON-Dokument erfolgreich verarbeitet");
Serial.println(doc.as<String>());
if (doc["sm_id"] != "")
if (doc.containsKey("sm_id") && doc["sm_id"] != "")
{
Serial.println("SPOOL-ID gefunden: " + doc["sm_id"].as<String>());
spoolId = doc["sm_id"].as<String>();
}
}
else if(doc.containsKey("location") && doc["location"] != "")
{
Serial.println("Location Tag found!");
String location = doc["location"].as<String>();
if(spoolId != ""){
updateSpoolLocation(spoolId, location);
}
else
{
Serial.println("Location update tag scanned without scanning spool before!");
oledShowMessage("No spool scanned before!");
}
}
else
{
Serial.println("Keine SPOOL-ID gefunden.");

View File

@@ -74,7 +74,11 @@ void scale_loop(void * parameter) {
scaleTareRequest = false;
}
weight = round(scale.get_units());
// Only update weight if median changed more than 1
int16_t newWeight = round(scale.get_units());
if(abs(weight-newWeight) > 1){
weight = newWeight;
}
}
vTaskDelay(pdMS_TO_TICKS(100));