Compare commits

..

No commits in common. "main" and "v1.4.6" have entirely different histories.
main ... v1.4.6

28 changed files with 153 additions and 757 deletions

@ -1,122 +1,5 @@
# Changelog
## [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
## [1.4.14] - 2025-03-30
### Added
- add auto-tare functionality and update scale handling based on touch sensor connection
### Changed
- update platformio.ini for version v1.4.14
## [1.4.13] - 2025-03-30
### Changed
- update platformio.ini for version v1.4.13
### Fixed
- update touch sensor connection logic to correctly identify connection status
## [1.4.12] - 2025-03-30
### Added
- add touch sensor connection check and update logic
### Changed
- update platformio.ini for version v1.4.12
- update README files to clarify PN532 DIP switch settings
## [1.4.11] - 2025-03-30
### Added
- Renamed states of NFC state machine and introduced new state machine for spoolman API
### Changed
- update platformio.ini for version v1.4.11
- Merge branch 'main' of github.com:ManuelW77/Filaman
- Merge pull request #31 from janecker/nfc_rework
- Introducing enum for handling the NFC state to improve code readability
## [1.4.10] - 2025-03-30
### Added
- add manual tare functionality for scale
- add debounce handling for TTP223 touch sensor
- add TTP223 touch sensor support and wiring configuration
### Changed
- update platformio.ini for version v1.4.10
### Fixed
- update TTP223 pin configuration and adjust touch sensor logic
## [1.4.9] - 2025-03-29
### Changed
- update platformio.ini for version v1.4.9
### Fixed
- enhance HTTP method handling in sendToApi function
## [1.4.8] - 2025-03-29
### Changed
- update platformio.ini for version v1.4.8
- Merge pull request #30 from janecker/main
- Merge branch 'testing' into main
### Fixed
- improve HTTP client configuration and clear update documents after API calls
- Fixes memory leak in HTTPClient by disabling connection reuse
- update reload logic after removing and saving Bambu credentials for better cache handling
## [1.4.7] - 2025-03-27
### Added
- add forced cache refresh after removing and saving Bambu credentials
- add functionality to remove Bambu credentials and update API handling
- add rfid_bambu.html and update bambu connection handling
### Changed
- update platformio.ini for version v1.4.7
- Merge branch 'testing'
- update remove button for Bambu credentials with red background
- Merge pull request #28 from tugsi/main
### Fixed
- handle Bambu connection state by introducing bambuDisabled flag
- Fix rfid.js-Failure with X1-Series, if you wanna send a Spool to AMS: - Uncaught TypeError: Cannot read properties of undefined (reading 'replace') at handleSpoolIn (rfid.js:493:67) at HTMLButtonElement.onclick ((Index):1:1) handleSpoolIn @ rfid.js:493 onclick @ (Index):1
## [1.4.6] - 2025-03-26
### Changed
- update platformio.ini for version v1.4.6

@ -54,23 +54,20 @@ Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
## Hardware-Anforderungen
### Komponenten (Affiliate Links)
- **ESP32 Development Board:** Any ESP32 variant.
[Amazon Link](https://amzn.to/3FHea6D)
- **HX711 5kg Load Cell Amplifier:** For weight measurement.
[Amazon Link](https://amzn.to/4ja1KTe)
- **OLED 0.96 Zoll I2C white/yellow Display:** 128x64 SSD1306.
[Amazon Link](https://amzn.to/445aaa9)
- **PN532 NFC NXP RFID-Modul V3:** For NFC tag operations.
[Amazon Link](https://amzn.to/4iO6CO4)
- **NFC Tags NTAG213 NTAG215:** RFID Tag
[Amazon Link](https://amzn.to/3E071xO)
- **TTP223 Touch Sensor (optional):** For reTARE per Button/Touch
[Amazon Link](https://amzn.to/4hTChMK)
### Komponenten
- **ESP32 Entwicklungsboard:** Jede ESP32-Variante.
[Amazon Link](https://amzn.eu/d/aXThslf)
- **HX711 5kg Wägezellen-Verstärker:** Für Gewichtsmessung.
[Amazon Link](https://amzn.eu/d/06A0DLb)
- **OLED 0.96 Zoll I2C weiß/gelb Display:** 128x64 SSD1306.
[Amazon Link](https://amzn.eu/d/0AuBp2c)
- **PN532 NFC NXP RFID-Modul V3:** Für NFC-Tag-Operationen.
[Amazon Link](https://amzn.eu/d/jfIuQXb)
- **NFC Tags NTAG213 NTA215:** RFID Tag
[Amazon Link](https://amzn.eu/d/9Z6mXc1)
### Pin Konfiguration
| Component | ESP32 Pin |
### Pin-Konfiguration
| Komponente | ESP32 Pin |
|-------------------|-----------|
| HX711 DOUT | 16 |
| HX711 SCK | 17 |
@ -80,22 +77,14 @@ Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
| PN532 RESET | 33 |
| PN532 SDA | 21 |
| PN532 SCL | 22 |
| TTP223 I/O | 25 |
**!! Achte darauf, dass am PN532 die DIP-Schalter auf I2C gestellt sind**
**Nutze den 3V Pin vom ESP für den Touch Sensor**
**Achte darauf, dass am PN532 die DIP-Schalter auf I2C gestellt sind**
![Wiring](./img/Schaltplan.png)
![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

@ -58,19 +58,17 @@ Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
## Hardware Requirements
### Components (Affiliate Links)
### Components
- **ESP32 Development Board:** Any ESP32 variant.
[Amazon Link](https://amzn.to/3FHea6D)
[Amazon Link](https://amzn.eu/d/aXThslf)
- **HX711 5kg Load Cell Amplifier:** For weight measurement.
[Amazon Link](https://amzn.to/4ja1KTe)
[Amazon Link](https://amzn.eu/d/06A0DLb)
- **OLED 0.96 Zoll I2C white/yellow Display:** 128x64 SSD1306.
[Amazon Link](https://amzn.to/445aaa9)
[Amazon Link](https://amzn.eu/d/0AuBp2c)
- **PN532 NFC NXP RFID-Modul V3:** For NFC tag operations.
[Amazon Link](https://amzn.to/4iO6CO4)
[Amazon Link](https://amzn.eu/d/jfIuQXb)
- **NFC Tags NTAG213 NTAG215:** RFID Tag
[Amazon Link](https://amzn.to/3E071xO)
- **TTP223 Touch Sensor (optional):** For reTARE per Button/Touch
[Amazon Link](https://amzn.to/4hTChMK)
[Amazon Link](https://amzn.eu/d/9Z6mXc1)
### Pin Configuration
@ -84,22 +82,14 @@ Discord Server: [https://discord.gg/my7Gvaxj2v](https://discord.gg/my7Gvaxj2v)
| PN532 RESET | 33 |
| PN532 SDA | 21 |
| PN532 SCL | 22 |
| TTP223 I/O | 25 |
**!! Make sure that the DIP switches on the PN532 are set to I2C**
**Use the 3V pin from the ESP for the touch sensor**
**Make sure that the DIP switches on the PN532 are set to I2C**
![Wiring](./img/Schaltplan.png)
![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

@ -141,6 +141,15 @@
</div>
</div>
<!-- Rechte Spalte -->
<div class="column">
<div class="feature-box">
<h2>Bambu AMS</h2>
<div id="amsDataContainer">
<div class="amsData" id="amsData">Wait for AMS-Data...</div>
</div>
</div>
</div>
</div>
</div>

@ -208,13 +208,27 @@ document.addEventListener('spoolmanError', function(event) {
showNotification(`Spoolman Error: ${event.detail.message}`, false);
});
document.addEventListener('filamentSelected', function (event) {
document.addEventListener('filamentSelected', function(event) {
updateNfcInfo();
// Zeige Spool-Buttons wenn ein Filament ausgewählt wurde
const selectedText = document.getElementById("selected-filament").textContent;
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");

@ -1,160 +0,0 @@
<!-- head --><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FilaMan - Filament Management Tool</title>
<link rel="icon" type="image/png" href="/favicon.ico">
<link rel="stylesheet" href="style.css">
<script>
fetch('/api/version')
.then(response => response.json())
.then(data => {
const versionSpan = document.querySelector('.version');
if (versionSpan) {
versionSpan.textContent = 'v' + data.version;
}
})
.catch(error => console.error('Error fetching version:', error));
</script>
</head>
<body>
<div class="navbar">
<div style="display: flex; align-items: center; gap: 2rem;">
<img src="/logo.png" alt="FilaMan Logo" class="logo">
<div class="logo-text">
<h1>FilaMan<span class="version"></span></h1>
<h4>Filament Management Tool</h4>
</div>
</div>
<nav style="display: flex; gap: 1rem;">
<a href="/">Start</a>
<a href="/waage">Scale</a>
<a href="/spoolman">Spoolman/Bambu</a>
<a href="/about">About</a>
<a href="/upgrade">Upgrade</a>
</nav>
<div class="status-container">
<div class="status-item">
<span class="status-dot" id="bambuDot"></span>B
</div>
<div class="status-item">
<span class="status-dot" id="spoolmanDot"></span>S
</div>
<div class="ram-status" id="ramStatus"></div>
</div>
</div>
<!-- head -->
<div class="connection-status hidden">
<div class="spinner"></div>
<span>Connection lost. Trying to reconnect...</span>
</div>
<div class="content">
<div class="three-column-layout">
<!-- Linke Spalte -->
<div class="column">
<div class="feature-box">
<div class="statistics-header">
<h2>Statistics</h2>
<button id="refreshSpoolman" class="refresh-button">
<span>Refresh Spoolman</span>
</button>
</div>
<div class="statistics-column">
<h3>Spools</h3>
<div class="spool-stat" style="display: flex; justify-content: center; align-items: center;">
<span class="stat-label">total:</span>
<span class="stat-value" id="totalSpools"></span>
<div style="width: auto;"></div>
<span class="stat-label">without Tag:</span>
<span class="stat-value" id="spoolsWithoutTag"></span>
</div>
</div>
<div class="statistics-grid">
<div class="statistics-column">
<h3>Overview</h3>
<ul class="statistics-list">
<li>
<span class="stat-label">Manufacturer:</span>
<span class="stat-value" id="totalVendors"></span>
</li>
<li>
<span class="stat-label">Weight:</span>
<span class="stat-value"><span id="totalWeight"></span></span>
</li>
<li>
<span class="stat-label">Length:</span>
<span class="stat-value"><span id="totalLength"></span></span>
</li>
</ul>
</div>
<div class="statistics-column">
<h3>Materials</h3>
<ul class="statistics-list" id="materialsList">
<!-- Wird dynamisch befüllt -->
</ul>
</div>
</div>
</div>
<div class="feature-box">
<div class="nfc-header">
<h2>NFC-Tag</h2>
<span id="nfcStatusIndicator" class="status-circle"></span>
</div>
<div class="nfc-status-display"></div>
</div>
</div>
<!-- Mittlere Spalte -->
<div class="column">
<div class="feature-box">
<h2>Spoolman Spools</h2>
<label for="vendorSelect">Manufacturer:</label>
<div style="display: flex; justify-content: space-between; align-items: center;">
<select id="vendorSelect" class="styled-select">
<option value="">Please choose...</option>
</select>
<label style="margin-left: 10px;">
<input type="checkbox" id="onlyWithoutSmId" checked onchange="updateFilamentDropdown()">
Only Spools without SM ID
</label>
</div>
</div>
<div id="filamentSection" class="feature-box hidden">
<label>Spool / Filament:</label>
<div class="custom-dropdown">
<div class="dropdown-button" onclick="toggleFilamentDropdown()">
<div class="selected-color" id="selected-color"></div>
<span id="selected-filament">Please choose...</span>
<span class="dropdown-arrow"></span>
</div>
<div class="dropdown-content" id="filament-dropdown-content">
<!-- Optionen werden dynamisch hinzugefügt -->
</div>
</div>
<p id="nfcInfo" class="nfc-status"></p>
<button id="writeNfcButton" class="btn btn-primary hidden" onclick="writeNfcTag()">Write Tag</button>
</div>
</div>
<!-- Rechte Spalte -->
<div class="column">
<div class="feature-box">
<h2>Bambu AMS</h2>
<div id="amsDataContainer">
<div class="amsData" id="amsData">Wait for AMS-Data...</div>
</div>
</div>
</div>
</div>
</div>
<script src="spoolman.js"></script>
<script src="rfid.js"></script>
</body>
</html>

@ -57,31 +57,6 @@
toggleOctoFields();
};
function removeBambuCredentials() {
fetch('/api/bambu?remove=true')
.then(response => response.json())
.then(data => {
if (data.success) {
document.getElementById('bambuIp').value = '';
document.getElementById('bambuSerial').value = '';
document.getElementById('bambuCode').value = '';
document.getElementById('autoSend').checked = false;
document.getElementById('autoSendTime').value = '';
document.getElementById('bambuStatusMessage').innerText = 'Bambu Credentials removed!';
// Reload with forced cache refresh after short delay
setTimeout(() => {
window.location.reload(true);
window.location.href = '/';
}, 1500);
} else {
document.getElementById('bambuStatusMessage').innerText = 'Error while removing Bambu Credentials.';
}
})
.catch(error => {
document.getElementById('bambuStatusMessage').innerText = 'Error while removing: ' + error.message;
});
}
function checkSpoolmanInstance() {
const url = document.getElementById('spoolmanUrl').value;
const spoolmanOctoEnabled = document.getElementById('spoolmanOctoEnabled').checked;
@ -114,11 +89,6 @@
.then(data => {
if (data.healthy) {
document.getElementById('bambuStatusMessage').innerText = 'Bambu Credentials saved!';
// Reload with forced cache refresh after short delay
setTimeout(() => {
window.location.reload(true);
window.location.href = '/';
}, 1500);
} else {
document.getElementById('bambuStatusMessage').innerText = 'Error while saving Bambu Credentials.';
}
@ -192,7 +162,6 @@
</div>
<button style="margin: 0;" onclick="saveBambuCredentials()">Save Bambu Credentials</button>
<button style="margin: 0; background-color: red;" onclick="removeBambuCredentials()">Remove Credentials</button>
<p id="bambuStatusMessage"></p>
</div>
</div>

@ -169,32 +169,9 @@ function updateFilamentDropdown(selectedSmId = null) {
option.setAttribute("data-value", spool.filament.id);
option.setAttribute("data-nfc-id", spool.extra.nfc_id || "");
// 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>`;
}
const colorHex = spool.filament.color_hex || 'FFFFFF';
option.innerHTML = `
${colorHTML}
<div class="option-color" style="background-color: #${colorHex}"></div>
<span>${spool.id} | ${spool.filament.name} (${spool.filament.material})</span>
`;
@ -213,29 +190,7 @@ function selectFilament(spool) {
const selectedText = document.getElementById("selected-filament");
const dropdownContent = document.getElementById("filament-dropdown-content");
// 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'}`;
}
selectedColor.style.backgroundColor = `#${spool.filament.color_hex || 'FFFFFF'}`;
selectedText.textContent = `${spool.id} | ${spool.filament.name} (${spool.filament.material})`;
dropdownContent.classList.remove("show");

@ -759,50 +759,6 @@ 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;

@ -55,7 +55,6 @@
<h5 class="card-title">Sacle Calibration</h5>
<button id="calibrateBtn" class="btn btn-primary">Calibrate Scale</button>
<button id="tareBtn" class="btn btn-secondary">Tare Scale</button>
&nbsp;&nbsp;&nbsp;Enable Auto-TARE <input type="checkbox" id="autoTareCheckbox" onchange="setAutoTare(this.checked);" {{autoTare}}>
<div id="statusMessage" class="mt-3"></div>
</div>
</div>
@ -141,15 +140,6 @@
}));
});
// Add auto-tare function
function setAutoTare(enabled) {
ws.send(JSON.stringify({
type: 'scale',
payload: 'setAutoTare',
enabled: enabled
}));
}
// WebSocket-Verbindung beim Laden der Seite initiieren
connectWebSocket();
</script>

@ -9,8 +9,8 @@
; https://docs.platformio.org/page/projectconf.html
[common]
version = "1.5.3"
to_old_version = "1.5.0"
version = "1.4.6"
to_old_version = "1.4.0"
##
[env:esp32dev]

@ -14,7 +14,7 @@ def copy_file(input_file, output_file):
def should_compress(file):
# Skip compression for spoolman.html
if file == 'spoolman.html' or file == 'waage.html':
if file == 'spoolman.html':
return False
# Komprimiere nur bestimmte Dateitypen
return file.endswith(('.js', '.png', '.css', '.html'))

@ -3,8 +3,7 @@
#include <ArduinoJson.h>
#include "commonFS.h"
volatile spoolmanApiStateType spoolmanApiState = API_INIT;
//bool spoolman_connected = false;
bool spoolman_connected = false;
String spoolmanUrl = "";
bool octoEnabled = false;
String octoUrl = "";
@ -86,7 +85,6 @@ JsonDocument fetchSingleSpoolInfo(int spoolId) {
}
void sendToApi(void *parameter) {
spoolmanApiState = API_TRANSMITTING;
SendToApiParams* params = (SendToApiParams*)parameter;
// Extrahiere die Werte
@ -96,52 +94,27 @@ void sendToApi(void *parameter) {
String octoToken = params->octoToken;
HTTPClient http;
http.setReuse(false);
http.begin(spoolsUrl);
http.addHeader("Content-Type", "application/json");
if (octoEnabled && octoToken != "") http.addHeader("X-Api-Key", octoToken);
int httpCode;
int httpCode = http.PUT(updatePayload);
if (httpType == "PATCH") httpCode = http.PATCH(updatePayload);
else if (httpType == "POST") httpCode = http.POST(updatePayload);
else httpCode = http.PUT(updatePayload);
if (httpType == "POST") httpCode = http.POST(updatePayload);
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 (httpType == "PUT") {
uint16_t remaining_weight = doc["remaining_weight"].as<float>();
Serial.print("Aktuelles Gewicht: ");
Serial.println(remaining_weight);
oledShowMessage("Remaining: " + String(remaining_weight) + "g");
}
vTaskDelay(3000 / portTICK_PERIOD_MS);
doc.clear();
}
} else {
Serial.println("Fehler beim Senden an Spoolman! HTTP Code: " + String(httpCode));
Serial.println("Fehler beim Senden an Spoolman!");
oledShowMessage("Spoolman update failed");
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
http.end();
vTaskDelay(50 / portTICK_PERIOD_MS);
// Speicher freigeben
delete params;
vTaskDelete(NULL);
spoolmanApiState = API_IDLE;
}
bool updateSpoolTagId(String uidString, const char* payload) {
@ -186,17 +159,12 @@ bool updateSpoolTagId(String uidString, const char* payload) {
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
6144, // Stackgröße in Bytes
4096, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
);
updateDoc.clear();
// Update Spool weight
if (weight > 10) updateSpoolWeight(doc["sm_id"].as<String>(), weight);
return true;
}
@ -227,14 +195,12 @@ uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
6144, // Stackgröße in Bytes
4096, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
);
updateDoc.clear();
return 1;
}
@ -266,14 +232,12 @@ bool updateSpoolOcto(int spoolId) {
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
6144, // Stackgröße in Bytes
4096, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
);
updateDoc.clear();
return true;
}
@ -314,7 +278,7 @@ bool updateSpoolBambuData(String payload) {
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
6144, // Stackgröße in Bytes
4096, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
@ -505,8 +469,7 @@ bool checkSpoolmanInstance(const String& url) {
return false;
}
spoolmanApiState = API_IDLE;
oledShowTopRow();
spoolman_connected = true;
return strcmp(status, "healthy") == 0;
}
}

@ -6,13 +6,7 @@
#include "website.h"
#include "display.h"
#include <ArduinoJson.h>
typedef enum {
API_INIT,
API_IDLE,
API_TRANSMITTING
} spoolmanApiStateType;
extern volatile spoolmanApiStateType spoolmanApiState;
extern bool spoolman_connected;
extern String spoolmanUrl;
extern bool octoEnabled;

@ -27,7 +27,6 @@ const char* bambu_serialnr = nullptr;
String g_bambu_ip = "";
String g_bambu_accesscode = "";
String g_bambu_serialnr = "";
bool bambuDisabled = false;
bool bambu_connected = false;
bool autoSendToBambu = false;
@ -38,32 +37,6 @@ int ams_count = 0;
String amsJsonData; // Speichert das fertige JSON für WebSocket-Clients
AMSData ams_data[MAX_AMS]; // Definition des Arrays;
bool removeBambuCredentials() {
if (BambuMqttTask) {
vTaskDelete(BambuMqttTask);
}
if (!removeJsonValue("/bambu_credentials.json")) {
Serial.println("Fehler beim Löschen der Bambu-Credentials.");
return false;
}
// Löschen der globalen Variablen
g_bambu_ip = "";
g_bambu_accesscode = "";
g_bambu_serialnr = "";
bambu_ip = nullptr;
bambu_accesscode = nullptr;
bambu_serialnr = nullptr;
autoSendToBambu = false;
autoSetToBambuSpoolId = 0;
ams_count = 0;
amsJsonData = "";
bambuDisabled = true;
return true;
}
bool saveBambuCredentials(const String& ip, const String& serialnr, const String& accesscode, bool autoSend, const String& autoSendTime) {
if (BambuMqttTask) {
vTaskDelete(BambuMqttTask);
@ -633,13 +606,14 @@ bool setupMqtt() {
bool success = loadBambuCredentials();
if (!success) {
bambuDisabled = true;
Serial.println("Failed to load Bambu credentials");
oledShowMessage("Bambu Credentials Missing");
vTaskDelay(2000 / portTICK_PERIOD_MS);
return false;
}
if (success && bambu_ip != "" && bambu_accesscode != "" && bambu_serialnr != "")
{
bambuDisabled = false;
sslClient.setCACert(root_ca);
sslClient.setInsecure();
client.setServer(bambu_ip, 8883);
@ -674,22 +648,22 @@ bool setupMqtt() {
vTaskDelay(2000 / portTICK_PERIOD_MS);
connected = false;
oledShowTopRow();
autoSetToBambuSpoolId = 0;
}
if (!connected) return false;
}
else
{
bambuDisabled = true;
Serial.println("Fehler: Keine MQTT-Daten vorhanden");
oledShowMessage("Bambu Credentials Missing");
oledShowTopRow();
vTaskDelay(2000 / portTICK_PERIOD_MS);
return false;
}
return true;
}
void bambu_restart() {
Serial.println("Bambu restart");
if (BambuMqttTask) {
vTaskDelete(BambuMqttTask);
delay(10);

@ -30,9 +30,7 @@ extern int ams_count;
extern AMSData ams_data[MAX_AMS];
extern bool autoSendToBambu;
extern int autoSetToBambuSpoolId;
extern bool bambuDisabled;
bool removeBambuCredentials();
bool loadBambuCredentials();
bool saveBambuCredentials(const String& bambu_ip, const String& bambu_serialnr, const String& bambu_accesscode, const bool autoSend, const String& autoSendTime);
bool setupMqtt();

@ -1,20 +1,6 @@
#include "commonFS.h"
#include <LittleFS.h>
bool removeJsonValue(const char* filename) {
File file = LittleFS.open(filename, "r");
if (!file) {
return true;
}
file.close();
if (!LittleFS.remove(filename)) {
Serial.print("Fehler beim Löschen der Datei: ");
Serial.println(filename);
return false;
}
return true;
}
bool saveJsonValue(const char* filename, const JsonDocument& doc) {
File file = LittleFS.open(filename, "w");
if (!file) {

@ -5,7 +5,6 @@
#include <ArduinoJson.h>
#include <LittleFS.h>
bool removeJsonValue(const char* filename);
bool saveJsonValue(const char* filename, const JsonDocument& doc);
bool loadJsonValue(const char* filename, JsonDocument& doc);
void initializeFileSystem();

@ -19,12 +19,6 @@ const uint16_t SCALE_LEVEL_WEIGHT = 500;
uint16_t defaultScaleCalibrationValue = 430;
// ***** HX711
// ***** TTP223 (Touch Sensor)
// TTP223 circuit wiring
const uint8_t TTP223_PIN = 25;
// ***** TTP223
// ***** Display
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// On an ESP32: 21(SDA), 22(SCL)

@ -11,8 +11,6 @@ extern const uint8_t LOADCELL_SCK_PIN;
extern const uint8_t calVal_eepromAdress;
extern const uint16_t SCALE_LEVEL_WEIGHT;
extern const uint8_t TTP223_PIN;
extern const int8_t OLED_RESET;
extern const uint8_t SCREEN_ADDRESS;
extern const uint8_t SCREEN_WIDTH;

@ -177,7 +177,7 @@ void oledShowTopRow() {
display.drawBitmap(50, 0, bitmap_off , 16, 16, WHITE);
}
if (spoolmanApiState != API_INIT) {
if (spoolman_connected == 1) {
display.drawBitmap(80, 0, bitmap_spoolman_on , 16, 16, WHITE);
} else {
display.drawBitmap(80, 0, bitmap_off , 16, 16, WHITE);

@ -15,7 +15,6 @@
bool mainTaskWasPaused = 0;
uint8_t scaleTareCounter = 0;
bool touchSensorConnected = false;
// ##### SETUP #####
void setup() {
@ -40,6 +39,7 @@ void setup() {
setupWebserver(server);
// Spoolman API
// api.cpp
initSpoolman();
// Bambu MQTT
@ -48,16 +48,7 @@ void setup() {
// NFC Reader
startNfc();
// Touch Sensor
pinMode(TTP223_PIN, INPUT_PULLUP);
if (digitalRead(TTP223_PIN) == LOW)
{
Serial.println("Touch Sensor is connected");
touchSensorConnected = true;
}
// Scale
start_scale(touchSensorConnected);
start_scale();
// WDT initialisieren mit 10 Sekunden Timeout
bool panic = true; // Wenn true, löst ein WDT-Timeout einen System-Panik aus
@ -93,25 +84,13 @@ uint8_t autoAmsCounter = 0;
uint8_t weightSend = 0;
int16_t lastWeight = 0;
// WIFI check variables
unsigned long lastWifiCheckTime = 0;
const unsigned long wifiCheckInterval = 60000; // Überprüfe alle 60 Sekunden (60000 ms)
// Button debounce variables
unsigned long lastButtonPress = 0;
const unsigned long debounceDelay = 500; // 500 ms debounce delay
// ##### PROGRAM START #####
void loop() {
unsigned long currentMillis = millis();
// Überprüfe den Status des Touch Sensors
if (touchSensorConnected && digitalRead(TTP223_PIN) == HIGH && currentMillis - lastButtonPress > debounceDelay)
{
lastButtonPress = currentMillis;
scaleTareRequest = true;
}
// Überprüfe regelmäßig die WLAN-Verbindung
if (intervalElapsed(currentMillis, lastWifiCheckTime, wifiCheckInterval))
{
@ -121,14 +100,14 @@ void loop() {
// Wenn Bambu auto set Spool aktiv
if (autoSendToBambu && autoSetToBambuSpoolId > 0)
{
if (!bambuDisabled && !bambu_connected)
if (!bambu_connected)
{
bambu_restart();
}
if (intervalElapsed(currentMillis, lastAutoSetBambuAmsTime, autoSetBambuAmsInterval))
{
if (nfcReaderState == NFC_IDLE)
if (hasReadRfidTag == 0)
{
lastAutoSetBambuAmsTime = currentMillis;
oledShowMessage("Auto Set " + String(autoSetBambuAmsCounter - autoAmsCounter) + "s");
@ -162,7 +141,7 @@ void loop() {
// Ausgabe der Waage auf Display
if(pauseMainTask == 0)
{
if (mainTaskWasPaused || (weight != lastWeight && nfcReaderState == NFC_IDLE && (!autoSendToBambu || autoSetToBambuSpoolId == 0)))
if (mainTaskWasPaused || (weight != lastWeight && hasReadRfidTag == 0 && (!autoSendToBambu || autoSetToBambuSpoolId == 0)))
{
(weight < 2) ? ((weight < -2) ? oledShowMessage("!! -0") : oledShowWeight(0)) : oledShowWeight(weight);
}
@ -175,23 +154,31 @@ void loop() {
// Wenn Timer abgelaufen und nicht gerade ein RFID-Tag geschrieben wird
if (currentMillis - lastWeightReadTime >= weightReadInterval && nfcReaderState < NFC_WRITING)
if (currentMillis - lastWeightReadTime >= weightReadInterval && hasReadRfidTag < 3)
{
lastWeightReadTime = currentMillis;
// Prüfen ob die Waage korrekt genullt ist
// Abweichung von 2g ignorieren
if (autoTare && (weight > 2 && weight < 7) || weight < -2)
if ((weight > 0 && weight < 5) || weight < -1)
{
scale_tare_counter++;
if(scaleTareCounter < 5)
{
scaleTareCounter++;
}
else
{
scaleTareRequest = true;
scaleTareCounter = 0;
}
}
else
{
scale_tare_counter = 0;
scaleTareCounter = 0;
}
// Prüfen ob das Gewicht gleich bleibt und dann senden
if (abs(weight - lastWeight) <= 2 && weight > 5)
if (weight == lastWeight && weight > 5)
{
weigthCouterToApi++;
}
@ -203,8 +190,7 @@ void loop() {
}
// reset weight counter after writing tag
// TBD: what exactly is the logic behind this?
if (currentMillis - lastWeightReadTime >= weightReadInterval && nfcReaderState != NFC_IDLE && nfcReaderState != NFC_READ_SUCCESS)
if (currentMillis - lastWeightReadTime >= weightReadInterval && hasReadRfidTag > 1)
{
weigthCouterToApi = 0;
}
@ -212,7 +198,7 @@ void loop() {
lastWeight = weight;
// Wenn ein Tag mit SM id erkannte wurde und der Waage Counter anspricht an SM Senden
if (spoolId != "" && weigthCouterToApi > 3 && weightSend == 0 && nfcReaderState == NFC_READ_SUCCESS) {
if (spoolId != "" && weigthCouterToApi > 3 && weightSend == 0 && hasReadRfidTag == 1) {
oledShowIcon("loading");
if (updateSpoolWeight(spoolId, weight))
{

@ -18,7 +18,7 @@ String spoolId = "";
String nfcJsonData = "";
volatile bool pauseBambuMqttTask = false;
volatile nfcReaderStateType nfcReaderState = NFC_IDLE;
volatile uint8_t hasReadRfidTag = 0;
// 0 = nicht gelesen
// 1 = erfolgreich gelesen
// 2 = fehler beim Lesen
@ -242,7 +242,7 @@ void writeJsonToTag(void *parameter) {
Serial.println("Erstelle NDEF-Message...");
Serial.println(payload);
nfcReaderState = NFC_WRITING;
hasReadRfidTag = 3;
vTaskSuspend(RfidReaderTask);
vTaskDelay(50 / portTICK_PERIOD_MS);
@ -288,7 +288,7 @@ void writeJsonToTag(void *parameter) {
//oledShowMessage("NFC-Tag written");
oledShowIcon("success");
vTaskDelay(1000 / portTICK_PERIOD_MS);
nfcReaderState = NFC_WRITE_SUCCESS;
hasReadRfidTag = 5;
// aktualisieren der Website wenn sich der Status ändert
sendNfcData(nullptr);
pauseBambuMqttTask = false;
@ -310,7 +310,7 @@ void writeJsonToTag(void *parameter) {
Serial.println("Fehler beim Schreiben der NDEF-Message auf den Tag");
oledShowIcon("failed");
vTaskDelay(2000 / portTICK_PERIOD_MS);
nfcReaderState = NFC_WRITE_ERROR;
hasReadRfidTag = 4;
}
}
else
@ -318,7 +318,7 @@ void writeJsonToTag(void *parameter) {
Serial.println("Fehler: Kein Tag zu schreiben gefunden.");
oledShowMessage("No NFC-Tag found");
vTaskDelay(2000 / portTICK_PERIOD_MS);
nfcReaderState = NFC_IDLE;
hasReadRfidTag = 0;
}
sendWriteResult(nullptr, success);
@ -334,7 +334,7 @@ void startWriteJsonToTag(const char* payload) {
char* payloadCopy = strdup(payload);
// Task nicht mehrfach starten
if (nfcReaderState != NFC_WRITING) {
if (hasReadRfidTag != 3) {
// Erstelle die Task
xTaskCreate(
writeJsonToTag, // Task-Funktion
@ -351,7 +351,7 @@ void scanRfidTask(void * parameter) {
Serial.println("RFID Task gestartet");
for(;;) {
// Wenn geschrieben wird Schleife aussetzen
if (nfcReaderState != NFC_WRITING)
if (hasReadRfidTag != 3)
{
yield();
@ -363,12 +363,12 @@ void scanRfidTask(void * parameter) {
foundNfcTag(nullptr, success);
if (success && nfcReaderState != NFC_READ_SUCCESS)
if (success && hasReadRfidTag != 1)
{
// Display some basic information about the card
Serial.println("Found an ISO14443A card");
nfcReaderState = NFC_READING;
hasReadRfidTag = 6;
oledShowIcon("transfer");
vTaskDelay(500 / portTICK_PERIOD_MS);
@ -406,11 +406,11 @@ void scanRfidTask(void * parameter) {
{
oledShowMessage("NFC-Tag unknown");
vTaskDelay(2000 / portTICK_PERIOD_MS);
nfcReaderState = NFC_READ_ERROR;
hasReadRfidTag = 2;
}
else
{
nfcReaderState = NFC_READ_SUCCESS;
hasReadRfidTag = 1;
}
free(data);
@ -418,7 +418,7 @@ void scanRfidTask(void * parameter) {
else
{
oledShowMessage("NFC-Tag read error");
nfcReaderState = NFC_READ_ERROR;
hasReadRfidTag = 2;
}
}
else
@ -427,9 +427,9 @@ void scanRfidTask(void * parameter) {
}
}
if (!success && nfcReaderState != NFC_IDLE)
if (!success && hasReadRfidTag > 0)
{
nfcReaderState = NFC_IDLE;
hasReadRfidTag = 0;
//uidString = "";
nfcJsonData = "";
Serial.println("Tag entfernt");

@ -3,16 +3,6 @@
#include <Arduino.h>
typedef enum{
NFC_IDLE,
NFC_READING,
NFC_READ_SUCCESS,
NFC_READ_ERROR,
NFC_WRITING,
NFC_WRITE_SUCCESS,
NFC_WRITE_ERROR
} nfcReaderStateType;
void startNfc();
void scanRfidTask(void * parameter);
void startWriteJsonToTag(const char* payload);
@ -20,9 +10,7 @@ void startWriteJsonToTag(const char* payload);
extern TaskHandle_t RfidReaderTask;
extern String nfcJsonData;
extern String spoolId;
extern volatile nfcReaderStateType nfcReaderState;
extern volatile uint8_t hasReadRfidTag;
extern volatile bool pauseBambuMqttTask;
#endif

@ -1,10 +1,6 @@
#include <Arduino.h>
#include <website.h>
#include <commonFS.h>
#include "scale.h"
#include "bambu.h"
#include "nfc.h"
// Globale Variablen für Config Backups hinzufügen
String bambuCredentialsBackup;
@ -155,25 +151,6 @@ void handleUpdate(AsyncWebServer &server) {
updateHandler->onUpload([](AsyncWebServerRequest *request, String filename,
size_t index, uint8_t *data, size_t len, bool final) {
// Disable all Tasks
if (BambuMqttTask != NULL)
{
Serial.println("Delete BambuMqttTask");
vTaskDelete(BambuMqttTask);
BambuMqttTask = NULL;
}
if (ScaleTask) {
Serial.println("Delete ScaleTask");
vTaskDelete(ScaleTask);
ScaleTask = NULL;
}
if (RfidReaderTask) {
Serial.println("Delete RfidReaderTask");
vTaskDelete(RfidReaderTask);
RfidReaderTask = NULL;
}
if (!index) {
updateTotalSize = request->contentLength();
updateWritten = 0;
@ -182,9 +159,9 @@ void handleUpdate(AsyncWebServer &server) {
if (isSpiffsUpdate) {
// Backup vor dem Update
sendUpdateProgress(0, "backup", "Backing up configurations...");
vTaskDelay(200 / portTICK_PERIOD_MS);
delay(200);
backupJsonConfigs();
vTaskDelay(200 / portTICK_PERIOD_MS);
delay(200);
const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, NULL);
if (!partition || !Update.begin(partition->size, U_SPIFFS)) {
@ -192,14 +169,14 @@ void handleUpdate(AsyncWebServer &server) {
return;
}
sendUpdateProgress(5, "starting", "Starting SPIFFS update...");
vTaskDelay(200 / portTICK_PERIOD_MS);
delay(200);
} else {
if (!Update.begin(updateTotalSize)) {
request->send(400, "application/json", "{\"success\":false,\"message\":\"Update initialization failed\"}");
return;
}
sendUpdateProgress(0, "starting", "Starting firmware update...");
vTaskDelay(200 / portTICK_PERIOD_MS);
delay(200);
}
}
@ -225,7 +202,7 @@ void handleUpdate(AsyncWebServer &server) {
if (currentProgress != lastProgress && (currentProgress % 10 == 0 || final)) {
sendUpdateProgress(currentProgress, "uploading");
oledShowMessage("Update: " + String(currentProgress) + "%");
vTaskDelay(50 / portTICK_PERIOD_MS);
delay(50);
lastProgress = currentProgress;
}
}

@ -14,7 +14,6 @@ TaskHandle_t ScaleTask;
int16_t weight = 0;
uint8_t weigthCouterToApi = 0;
uint8_t scale_tare_counter = 0;
bool scaleTareRequest = false;
uint8_t pauseMainTask = 0;
uint8_t scaleCalibrated = 1;
@ -22,23 +21,8 @@ uint8_t scaleCalibrated = 1;
Preferences preferences;
const char* NVS_NAMESPACE = "scale";
const char* NVS_KEY_CALIBRATION = "cal_value";
const char* NVS_KEY_AUTOTARE = "auto_tare";
bool autoTare = true;
// ##### Funktionen für Waage #####
uint8_t setAutoTare(bool autoTareValue) {
Serial.print("Set AutoTare to ");
Serial.println(autoTareValue);
autoTare = autoTareValue;
// Speichern mit NVS
preferences.begin(NVS_NAMESPACE, false); // false = readwrite
preferences.putBool(NVS_KEY_AUTOTARE, autoTare);
preferences.end();
return 1;
}
uint8_t tareScale() {
Serial.println("Tare scale");
scale.tare();
@ -54,23 +38,11 @@ void scale_loop(void * parameter) {
for(;;) {
if (scale.is_ready())
{
// Waage automatisch Taren, wenn zu lange Abweichung
if (autoTare && scale_tare_counter >= 5)
{
Serial.println("Auto Tare scale");
scale.tare();
scale_tare_counter = 0;
}
// Waage manuell Taren
// Waage nochmal Taren, wenn zu lange Abweichung
if (scaleTareRequest == true)
{
Serial.println("Re-Tare scale");
oledShowMessage("TARE Scale");
vTaskDelay(pdMS_TO_TICKS(1000));
scale.tare();
vTaskDelay(pdMS_TO_TICKS(1000));
oledShowWeight(0);
scaleTareRequest = false;
}
@ -81,20 +53,13 @@ void scale_loop(void * parameter) {
}
}
void start_scale(bool touchSensorConnected) {
void start_scale() {
Serial.println("Prüfe Calibration Value");
float calibrationValue;
// NVS lesen
preferences.begin(NVS_NAMESPACE, true); // true = readonly
calibrationValue = preferences.getFloat(NVS_KEY_CALIBRATION, defaultScaleCalibrationValue);
// auto Tare
// Wenn Touch Sensor verbunden, dann autoTare auf false setzen
// Danach prüfen was in NVS gespeichert ist
autoTare = (touchSensorConnected) ? false : true;
autoTare = preferences.getBool(NVS_KEY_AUTOTARE, autoTare);
preferences.end();
Serial.print("Read Scale Calibration Value ");

@ -4,19 +4,17 @@
#include <Arduino.h>
#include "HX711.h"
uint8_t setAutoTare(bool autoTareValue);
uint8_t start_scale(bool touchSensorConnected);
uint8_t start_scale();
uint8_t calibrate_scale();
uint8_t tareScale();
extern HX711 scale;
extern int16_t weight;
extern uint8_t weigthCouterToApi;
extern uint8_t scale_tare_counter;
extern uint8_t scaleTareRequest;
extern uint8_t pauseMainTask;
extern uint8_t scaleCalibrated;
extern bool autoTare;
extern TaskHandle_t ScaleTask;

@ -22,14 +22,14 @@ AsyncWebServer server(webserverPort);
AsyncWebSocket ws("/ws");
uint8_t lastSuccess = 0;
nfcReaderStateType lastnfcReaderState = NFC_IDLE;
uint8_t lastHasReadRfidTag = 0;
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
if (type == WS_EVT_CONNECT) {
Serial.println("Neuer Client verbunden!");
// Sende die AMS-Daten an den neuen Client
if (!bambuDisabled) sendAmsData(client);
sendAmsData(client);
sendNfcData(client);
foundNfcTag(client, 0);
sendWriteResult(client, 3);
@ -44,15 +44,13 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
JsonDocument doc;
deserializeJson(doc, message);
bool spoolmanConnected = (spoolmanApiState != API_INIT);
if (doc["type"] == "heartbeat") {
// Sende Heartbeat-Antwort
ws.text(client->id(), "{"
"\"type\":\"heartbeat\","
"\"freeHeap\":" + String(ESP.getFreeHeap()/1024) + ","
"\"bambu_connected\":" + String(bambu_connected) + ","
"\"spoolman_connected\":" + String(spoolmanConnected) + ""
"\"spoolman_connected\":" + String(spoolman_connected) + ""
"}");
}
@ -75,10 +73,6 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
success = calibrate_scale();
}
if (doc["payload"] == "setAutoTare") {
success = setAutoTare(doc["enabled"].as<bool>());
}
if (success) {
ws.textAll("{\"type\":\"scale\",\"payload\":\"success\"}");
} else {
@ -145,31 +139,34 @@ void foundNfcTag(AsyncWebSocketClient *client, uint8_t success) {
}
void sendNfcData(AsyncWebSocketClient *client) {
if (lastnfcReaderState == nfcReaderState) return;
// TBD: Why is there no status for reading the tag?
switch(nfcReaderState){
case NFC_IDLE:
ws.textAll("{\"type\":\"nfcData\", \"payload\":{}}");
break;
case NFC_READ_SUCCESS:
ws.textAll("{\"type\":\"nfcData\", \"payload\":" + nfcJsonData + "}");
break;
case NFC_READ_ERROR:
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Empty Tag or Data not readable\"}}");
break;
case NFC_WRITING:
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"info\":\"Schreibe Tag...\"}}");
break;
case NFC_WRITE_SUCCESS:
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"info\":\"Tag erfolgreich geschrieben\"}}");
break;
case NFC_WRITE_ERROR:
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Error writing to Tag\"}}");
break;
case DEFAULT:
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Something went wrong\"}}");
if (lastHasReadRfidTag == hasReadRfidTag) return;
if (hasReadRfidTag == 0) {
ws.textAll("{\"type\":\"nfcData\", \"payload\":{}}");
}
lastnfcReaderState = nfcReaderState;
else if (hasReadRfidTag == 1) {
ws.textAll("{\"type\":\"nfcData\", \"payload\":" + nfcJsonData + "}");
}
else if (hasReadRfidTag == 2)
{
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Empty Tag or Data not readable\"}}");
}
else if (hasReadRfidTag == 3)
{
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"info\":\"Schreibe Tag...\"}}");
}
else if (hasReadRfidTag == 4)
{
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Error writing to Tag\"}}");
}
else if (hasReadRfidTag == 5)
{
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"info\":\"Tag erfolgreich geschrieben\"}}");
}
else
{
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Something went wrong\"}}");
}
lastHasReadRfidTag = hasReadRfidTag;
}
void sendAmsData(AsyncWebSocketClient *client) {
@ -207,23 +204,16 @@ void setupWebserver(AsyncWebServer &server) {
// Route für Waage
server.on("/waage", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Anfrage für /waage erhalten");
//AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/waage.html.gz", "text/html");
//response->addHeader("Content-Encoding", "gzip");
//response->addHeader("Cache-Control", CACHE_CONTROL);
String html = loadHtmlWithHeader("/waage.html");
html.replace("{{autoTare}}", (autoTare) ? "checked" : "");
request->send(200, "text/html", html);
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/waage.html.gz", "text/html");
response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response);
});
// Route für RFID
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Anfrage für /rfid erhalten");
String page = (bambuDisabled) ? "/rfid.html.gz" : "/rfid_bambu.html.gz";
AsyncWebServerResponse *response = request->beginResponse(LittleFS, page, "text/html");
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/rfid.html.gz", "text/html");
response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response);
@ -320,15 +310,6 @@ void setupWebserver(AsyncWebServer &server) {
// Route für das Überprüfen der Bambu-Instanz
server.on("/api/bambu", HTTP_GET, [](AsyncWebServerRequest *request){
if (request->hasParam("remove")) {
if (removeBambuCredentials()) {
request->send(200, "application/json", "{\"success\": true}");
} else {
request->send(500, "application/json", "{\"success\": false, \"error\": \"Fehler beim Löschen der Bambu-Credentials\"}");
}
return;
}
if (!request->hasParam("bambu_ip") || !request->hasParam("bambu_serialnr") || !request->hasParam("bambu_accesscode")) {
request->send(400, "application/json", "{\"success\": false, \"error\": \"Missing parameter\"}");
return;