Compare commits

..

10 Commits

Author SHA1 Message Date
tugsi 2068810386 git 2025-03-23 18:31:25 +01:00
tugsi f2bf5e96f0 - RFID-Reader-Task optimized 2025-03-18 11:54:56 +01:00
tugsi 9a7ba2845d -RFID SPI Pins angepasst
- NFC-Tag verbessert
2025-03-18 11:36:10 +01:00
tugsi f1a9c3c5d4 -Abfrage Error gefixt, wenn leer dann kein Error mehr 2025-03-17 11:19:28 +01:00
tugsi ccca159a10 rfid.js wieder auf Originalstand gebracht 2025-03-17 09:31:26 +01:00
tugsi 70c8b7bdc0 Delete data directory
Old and not used... Testing from SPIFFS
2025-03-16 19:40:05 +01:00
tugsi c574cc964e Merge branch 'Bambu-Serie-X-MQTT-Fix' of https://github.com/tugsi/Filaman into Bambu-Serie-X-MQTT-Fix 2025-03-16 19:35:08 +01:00
tugsi 9262865b56 - X1C MQTT Fix
- Spoolman Settings Fix
- Spoolman Out Fix
- Spoolman In Fix
2025-03-16 19:30:37 +01:00
tugsi f7c01eb5f0 Merge remote-tracking branch 'upstream/main' into Bambu-Serie-X-MQTT-Fix 2025-03-14 17:43:52 +01:00
tugsi a41ef9e75a docs: update changelog and header for version v1.4.1
- Die MQTT-Puffergröße auf 16.384 Byte (16 KB) erhöht.
Dies sollte ausreichen, um Ihre 15.403 Byte große JSON-Nutzlast mit etwas mehr Spielraum zu verarbeiten. Diese Änderung ermöglicht es dem MQTT-Client, größere JSON-Nachrichten ohne Kürzung zu empfangen und zu verarbeiten.

Einige wichtige Hinweise zu dieser Änderung:
Die neue Puffergröße von 16 KB verbraucht mehr RAM, der ESP32 sollte jedoch ausreichend Speicher dafür haben.
Die Größe ist auf 16 KB festgelegt, um über die benötigten 15.403 Byte hinaus zusätzlichen Puffer-Overhead bereitzustellen.

Diese Änderung betrifft nur den MQTT-Empfangspuffer
--
- Die Task-Stack-Größe von 8192 auf 16384 Wörter erhöht, um mehr Speicher für die JSON-Verarbeitung bereitzustellen
---
- Erhöhung des Keepalive-Intervalls auf 60 Sekunden
- Verbesserte Fehlerbehandlung und Debugging-Ausgaben
- Detaillierte Statusmeldungen für die MQTT-Verbindung
- Periodische Verbindungsüberprüfung alle 30 Sekunden
- Bessere Handhabung von Verbindungsverlusten
---
- Verwendung einer eindeutigen Client-ID mit Zufallssuffix
- Erhöhung der QoS (Quality of Service) auf 1 für zuverlässigere Übertragung
- Einstellung eines Socket-Timeouts von 60 Sekunden
- Aktivierung von Clean Session und Will Message
- Verbessertes Verbindungs-Logging
2025-03-14 17:42:26 +01:00
27 changed files with 230 additions and 612 deletions
+5 -1
View File
@@ -1,3 +1,7 @@
.pio .pio
.vscode .vscode
data .vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
data
+10
View File
@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}
+9
View File
@@ -141,6 +141,15 @@
</div> </div>
</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>
</div> </div>
+2 -1
View File
@@ -685,4 +685,5 @@ function showNotification(message, isSuccess) {
setTimeout(() => { setTimeout(() => {
notification.remove(); notification.remove();
}, 300); }, 300);
}, 3000);} }, 3000);
}
-165
View File
@@ -1,165 +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>
+2 -33
View File
@@ -57,31 +57,6 @@
toggleOctoFields(); 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() { function checkSpoolmanInstance() {
const url = document.getElementById('spoolmanUrl').value; const url = document.getElementById('spoolmanUrl').value;
const spoolmanOctoEnabled = document.getElementById('spoolmanOctoEnabled').checked; const spoolmanOctoEnabled = document.getElementById('spoolmanOctoEnabled').checked;
@@ -114,12 +89,7 @@
.then(data => { .then(data => {
if (data.healthy) { if (data.healthy) {
document.getElementById('bambuStatusMessage').innerText = 'Bambu Credentials saved!'; document.getElementById('bambuStatusMessage').innerText = 'Bambu Credentials saved!';
// Reload with forced cache refresh after short delay } else {
setTimeout(() => {
window.location.reload(true);
window.location.href = '/';
}, 1500);
} else {
document.getElementById('bambuStatusMessage').innerText = 'Error while saving Bambu Credentials.'; document.getElementById('bambuStatusMessage').innerText = 'Error while saving Bambu Credentials.';
} }
}) })
@@ -192,8 +162,7 @@
</div> </div>
<button style="margin: 0;" onclick="saveBambuCredentials()">Save Bambu Credentials</button> <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>
<p id="bambuStatusMessage"></p>
</div> </div>
</div> </div>
</div> </div>
+12 -7
View File
@@ -147,13 +147,6 @@ function updateFilamentDropdown(selectedSmId = null) {
if (vendorId) { if (vendorId) {
const filteredFilaments = spoolsData.filter(spool => { const filteredFilaments = spoolsData.filter(spool => {
if (!spool?.filament?.vendor?.id) {
console.log('Problem aufgetreten bei: ', spool?.filament?.vendor);
console.log('Problematische Spulen:',
spoolsData.filter(spool => !spool?.filament?.vendor?.id));
return false;
}
const hasValidNfcId = spool.extra && const hasValidNfcId = spool.extra &&
spool.extra.nfc_id && spool.extra.nfc_id &&
spool.extra.nfc_id !== '""' && spool.extra.nfc_id !== '""' &&
@@ -247,6 +240,18 @@ async function fetchSpoolData() {
} }
} }
/*
// Exportiere Funktionen
window.getSpoolData = () => spoolsData;
window.reloadSpoolData = initSpoolman;
window.populateVendorDropdown = populateVendorDropdown;
window.updateFilamentDropdown = updateFilamentDropdown;
window.toggleFilamentDropdown = () => {
const content = document.getElementById("filament-dropdown-content");
content.classList.toggle("show");
};
*/
// Event Listener // Event Listener
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initSpoolman(); initSpoolman();
-2
View File
@@ -129,7 +129,6 @@
if (data.status === 'success' || lastReceivedProgress >= 98) { if (data.status === 'success' || lastReceivedProgress >= 98) {
clearTimeout(wsReconnectTimer); clearTimeout(wsReconnectTimer);
setTimeout(() => { setTimeout(() => {
window.location.reload(true);
window.location.href = '/'; window.location.href = '/';
}, 30000); }, 30000);
} }
@@ -165,7 +164,6 @@
status.className = 'status success'; status.className = 'status success';
status.style.display = 'block'; status.style.display = 'block';
setTimeout(() => { setTimeout(() => {
window.location.reload(true);
window.location.href = '/'; window.location.href = '/';
}, 30000); }, 30000);
} }
-10
View File
@@ -55,8 +55,6 @@
<h5 class="card-title">Sacle Calibration</h5> <h5 class="card-title">Sacle Calibration</h5>
<button id="calibrateBtn" class="btn btn-primary">Calibrate Scale</button> <button id="calibrateBtn" class="btn btn-primary">Calibrate Scale</button>
<button id="tareBtn" class="btn btn-secondary">Tare 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 id="statusMessage" class="mt-3"></div>
</div> </div>
</div> </div>
@@ -141,14 +139,6 @@
payload: 'tare' payload: 'tare'
})); }));
}); });
// Add auto-tare function
function setAutoTare(enabled) {
ws.send(JSON.stringify({
type: 'scale',
payload: 'setAutoTare',
enabled: enabled
}));
}
// WebSocket-Verbindung beim Laden der Seite initiieren // WebSocket-Verbindung beim Laden der Seite initiieren
connectWebSocket(); connectWebSocket();
+2 -2
View File
@@ -9,8 +9,8 @@
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[common] [common]
version = "0.2.1" version = "1.4.1"
to_old_version = "0.2.0" to_old_version = "1.4.0"
## ##
[env:esp32dev] [env:esp32dev]
+1 -1
View File
@@ -14,7 +14,7 @@ def copy_file(input_file, output_file):
def should_compress(file): def should_compress(file):
# Skip compression for spoolman.html # Skip compression for spoolman.html
if file == 'spoolman.html' or file == 'waage.html': if file == 'spoolman.html':
return False return False
# Komprimiere nur bestimmte Dateitypen # Komprimiere nur bestimmte Dateitypen
return file.endswith(('.js', '.png', '.css', '.html')) return file.endswith(('.js', '.png', '.css', '.html'))
+5 -16
View File
@@ -3,7 +3,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include "commonFS.h" #include "commonFS.h"
volatile spoolmanApiStateType spoolmanApiState = API_INIT; bool spoolman_connected = false;
String spoolmanUrl = ""; String spoolmanUrl = "";
bool octoEnabled = false; bool octoEnabled = false;
String octoUrl = ""; String octoUrl = "";
@@ -85,8 +85,7 @@ JsonDocument fetchSingleSpoolInfo(int spoolId) {
} }
void sendToApi(void *parameter) { void sendToApi(void *parameter) {
spoolmanApiState = API_TRANSMITTING; SendToApiParams* params = (SendToApiParams*)parameter;
SendToApiParams *params = (SendToApiParams *)parameter;
// Extrahiere die Werte // Extrahiere die Werte
String httpType = params->httpType; String httpType = params->httpType;
@@ -95,17 +94,13 @@ void sendToApi(void *parameter) {
String octoToken = params->octoToken; String octoToken = params->octoToken;
HTTPClient http; HTTPClient http;
http.setReuse(false);
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); if (octoEnabled && octoToken != "") http.addHeader("X-Api-Key", octoToken);
int httpCode; int httpCode = http.PUT(updatePayload);
if (httpType == "PATCH") httpCode = http.PATCH(updatePayload); if (httpType == "PATCH") httpCode = http.PATCH(updatePayload);
else if (httpType == "POST") if (httpType == "POST") httpCode = http.POST(updatePayload);
httpCode = http.POST(updatePayload);
else
httpCode = http.PUT(updatePayload);
if (httpCode == HTTP_CODE_OK) { if (httpCode == HTTP_CODE_OK) {
Serial.println("Spoolman erfolgreich aktualisiert"); Serial.println("Spoolman erfolgreich aktualisiert");
@@ -116,12 +111,10 @@ void sendToApi(void *parameter) {
} }
http.end(); http.end();
vTaskDelay(50 / portTICK_PERIOD_MS);
// Speicher freigeben // Speicher freigeben
delete params; delete params;
vTaskDelete(NULL); vTaskDelete(NULL);
spoolmanApiState = API_IDLE;
} }
bool updateSpoolTagId(String uidString, const char* payload) { bool updateSpoolTagId(String uidString, const char* payload) {
@@ -171,7 +164,6 @@ bool updateSpoolTagId(String uidString, const char* payload) {
0, // Priorität 0, // Priorität
NULL // Task-Handle (nicht benötigt) NULL // Task-Handle (nicht benötigt)
); );
updateDoc.clear();
return true; return true;
} }
@@ -208,7 +200,6 @@ uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
0, // Priorität 0, // Priorität
NULL // Task-Handle (nicht benötigt) NULL // Task-Handle (nicht benötigt)
); );
updateDoc.clear();
return 1; return 1;
} }
@@ -246,7 +237,6 @@ bool updateSpoolOcto(int spoolId) {
0, // Priorität 0, // Priorität
NULL // Task-Handle (nicht benötigt) NULL // Task-Handle (nicht benötigt)
); );
updateDoc.clear();
return true; return true;
} }
@@ -479,8 +469,7 @@ bool checkSpoolmanInstance(const String& url) {
return false; return false;
} }
spoolmanApiState = API_IDLE; spoolman_connected = true;
oledShowTopRow();
return strcmp(status, "healthy") == 0; return strcmp(status, "healthy") == 0;
} }
} }
-7
View File
@@ -6,14 +6,7 @@
#include "website.h" #include "website.h"
#include "display.h" #include "display.h"
#include <ArduinoJson.h> #include <ArduinoJson.h>
typedef enum
{
API_INIT,
API_IDLE,
API_TRANSMITTING
} spoolmanApiStateType;
extern volatile spoolmanApiStateType spoolmanApiState;
extern bool spoolman_connected; extern bool spoolman_connected;
extern String spoolmanUrl; extern String spoolmanUrl;
extern bool octoEnabled; extern bool octoEnabled;
+10 -42
View File
@@ -27,7 +27,6 @@ const char* bambu_serialnr = nullptr;
String g_bambu_ip = ""; String g_bambu_ip = "";
String g_bambu_accesscode = ""; String g_bambu_accesscode = "";
String g_bambu_serialnr = ""; String g_bambu_serialnr = "";
bool bambuDisabled = false;
bool bambu_connected = false; bool bambu_connected = false;
bool autoSendToBambu = false; bool autoSendToBambu = false;
@@ -38,35 +37,6 @@ int ams_count = 0;
String amsJsonData; // Speichert das fertige JSON für WebSocket-Clients 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 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) { bool saveBambuCredentials(const String& ip, const String& serialnr, const String& accesscode, bool autoSend, const String& autoSendTime) {
if (BambuMqttTask) { if (BambuMqttTask) {
vTaskDelete(BambuMqttTask); vTaskDelete(BambuMqttTask);
@@ -296,10 +266,8 @@ bool setBambuSpool(String payload) {
JsonDocument doc; JsonDocument doc;
DeserializationError error = deserializeJson(doc, payload); DeserializationError error = deserializeJson(doc, payload);
if (error) { if (error) {
Serial.print("Error parsing setBambuSpool-JSON: "); Serial.print("Error parsing JSON: ");
Serial.println(error.c_str()); Serial.println(error.c_str());
Serial.print("Free Heap-Memory: ");
Serial.println(ESP.getFreeHeap());
return false; return false;
} }
@@ -507,9 +475,7 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
message = ""; message = "";
if (error) if (error)
{ {
Serial.print("Free Heap-Memory: "); Serial.print("Fehler beim Parsen des JSON: ");
Serial.println(ESP.getFreeHeap());
Serial.print("Error parsing MQTT-JSON: ");
Serial.println(error.c_str()); Serial.println(error.c_str());
return; return;
} }
@@ -716,12 +682,10 @@ void mqtt_loop(void * parameter) {
} }
// Periodically check connection status // Periodically check connection status
if (now - lastCheck > 60000) { // Check every 60 seconds if (now - lastCheck > 30000) { // Check every 30 seconds
Serial.print("MQTT Status Check - Connected: "); Serial.print("MQTT Status Check - Connected: ");
Serial.println(client.connected() ? "Yes" : "No"); Serial.println(client.connected() ? "Yes" : "No");
lastCheck = now; lastCheck = now;
Serial.print("Free Heap-Memory: ");
Serial.println(ESP.getFreeHeap());
} }
client.loop(); client.loop();
@@ -736,13 +700,14 @@ bool setupMqtt() {
bool success = loadBambuCredentials(); bool success = loadBambuCredentials();
if (!success) { if (!success) {
bambuDisabled = true; Serial.println("Failed to load Bambu credentials");
oledShowMessage("Bambu Credentials Missing");
vTaskDelay(2000 / portTICK_PERIOD_MS);
return false; return false;
} }
if (success && bambu_ip != "" && bambu_accesscode != "" && bambu_serialnr != "") if (success && bambu_ip != "" && bambu_accesscode != "" && bambu_serialnr != "")
{ {
bambuDisabled = false;
sslClient.setCACert(root_ca); sslClient.setCACert(root_ca);
sslClient.setInsecure(); sslClient.setInsecure();
client.setServer(bambu_ip, 8883); client.setServer(bambu_ip, 8883);
@@ -799,7 +764,10 @@ bool setupMqtt() {
} }
else else
{ {
bambuDisabled = true; Serial.println("Fehler: Keine MQTT-Daten vorhanden");
oledShowMessage("Bambu Credentials Missing");
oledShowTopRow();
vTaskDelay(2000 / portTICK_PERIOD_MS);
return false; return false;
} }
return true; return true;
-2
View File
@@ -30,9 +30,7 @@ extern int ams_count;
extern AMSData ams_data[MAX_AMS]; extern AMSData ams_data[MAX_AMS];
extern bool autoSendToBambu; extern bool autoSendToBambu;
extern int autoSetToBambuSpoolId; extern int autoSetToBambuSpoolId;
extern bool bambuDisabled;
bool removeBambuCredentials();
bool loadBambuCredentials(); bool loadBambuCredentials();
bool saveBambuCredentials(const String& bambu_ip, const String& bambu_serialnr, const String& bambu_accesscode, const bool autoSend, const String& autoSendTime); bool saveBambuCredentials(const String& bambu_ip, const String& bambu_serialnr, const String& bambu_accesscode, const bool autoSend, const String& autoSendTime);
bool setupMqtt(); bool setupMqtt();
-17
View File
@@ -1,23 +1,6 @@
#include "commonFS.h" #include "commonFS.h"
#include <LittleFS.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) { bool saveJsonValue(const char* filename, const JsonDocument& doc) {
File file = LittleFS.open(filename, "w"); File file = LittleFS.open(filename, "w");
if (!file) { if (!file) {
+1 -2
View File
@@ -5,8 +5,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <LittleFS.h> #include <LittleFS.h>
bool removeJsonValue(const char *filename); bool saveJsonValue(const char* filename, const JsonDocument& doc);
bool saveJsonValue(const char *filename, const JsonDocument &doc);
bool loadJsonValue(const char* filename, JsonDocument& doc); bool loadJsonValue(const char* filename, JsonDocument& doc);
void initializeFileSystem(); void initializeFileSystem();
-7
View File
@@ -6,8 +6,6 @@
//#define PN532_MOSI 23 //#define PN532_MOSI 23
//#define PN532_SS 5 //#define PN532_SS 5
//#define PN532_MISO 19 //#define PN532_MISO 19
const uint8_t PN532_IRQ = 32;
const uint8_t PN532_RESET = 33;
// ***** PN532 // ***** PN532
// ***** HX711 (Waage) // ***** HX711 (Waage)
@@ -19,11 +17,6 @@ const uint16_t SCALE_LEVEL_WEIGHT = 500;
uint16_t defaultScaleCalibrationValue = 430; uint16_t defaultScaleCalibrationValue = 430;
// ***** HX711 // ***** HX711
// ***** TTP223 (Touch Sensor)
// TTP223 circuit wiring
const uint8_t TTP223_PIN = 25;
// ***** TTP223
// ***** Display // ***** Display
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// On an ESP32: 21(SDA), 22(SCL) // On an ESP32: 21(SDA), 22(SCL)
+13 -6
View File
@@ -1,16 +1,18 @@
#ifndef CONFIG_H #pragma once
#define CONFIG_H
#include <Arduino.h> #include <Arduino.h>
extern const uint8_t PN532_IRQ; // ***** PN532 (RFID)
extern const uint8_t PN532_RESET; //#define PN532_SCK 18
//#define PN532_MOSI 23
//#define PN532_SS 5
//#define PN532_MISO 19
// ***** PN532
extern const uint8_t LOADCELL_DOUT_PIN; extern const uint8_t LOADCELL_DOUT_PIN;
extern const uint8_t LOADCELL_SCK_PIN; extern const uint8_t LOADCELL_SCK_PIN;
extern const uint8_t calVal_eepromAdress; extern const uint8_t calVal_eepromAdress;
extern const uint16_t SCALE_LEVEL_WEIGHT; extern const uint16_t SCALE_LEVEL_WEIGHT;
extern const uint8_t TTP223_PIN;
extern const int8_t OLED_RESET; extern const int8_t OLED_RESET;
extern const uint8_t SCREEN_ADDRESS; extern const uint8_t SCREEN_ADDRESS;
@@ -48,4 +50,9 @@ extern uint8_t scaleTaskCore;
extern uint8_t scaleTaskPrio; extern uint8_t scaleTaskPrio;
extern uint16_t defaultScaleCalibrationValue; extern uint16_t defaultScaleCalibrationValue;
#endif
#define PN532_SCK (18)
#define PN532_MISO (19)
#define PN532_MOSI (23)
#define PN532_CS1 (5)
#define PN532_CS2 (4)
+3 -6
View File
@@ -177,12 +177,9 @@ void oledShowTopRow() {
display.drawBitmap(50, 0, bitmap_off , 16, 16, WHITE); 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);
display.drawBitmap(80, 0, bitmap_spoolman_on, 16, 16, WHITE); } else {
}
else
{
display.drawBitmap(80, 0, bitmap_off , 16, 16, WHITE); display.drawBitmap(80, 0, bitmap_off , 16, 16, WHITE);
} }
+21 -40
View File
@@ -15,7 +15,6 @@
bool mainTaskWasPaused = 0; bool mainTaskWasPaused = 0;
uint8_t scaleTareCounter = 0; uint8_t scaleTareCounter = 0;
bool touchSensorConnected = false;
// ##### SETUP ##### // ##### SETUP #####
void setup() { void setup() {
@@ -40,6 +39,7 @@ void setup() {
setupWebserver(server); setupWebserver(server);
// Spoolman API // Spoolman API
// api.cpp
initSpoolman(); initSpoolman();
// Bambu MQTT // Bambu MQTT
@@ -48,16 +48,7 @@ void setup() {
// NFC Reader // NFC Reader
startNfc(); startNfc();
// Touch Sensor start_scale();
pinMode(TTP223_PIN, INPUT_PULLUP);
if (digitalRead(TTP223_PIN) == LOW)
{
Serial.println("Touch Sensor is connected");
touchSensorConnected = true;
}
// Scale
start_scale(touchSensorConnected);
// WDT initialisieren mit 10 Sekunden Timeout // WDT initialisieren mit 10 Sekunden Timeout
bool panic = true; // Wenn true, löst ein WDT-Timeout einen System-Panik aus 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; uint8_t weightSend = 0;
int16_t lastWeight = 0; int16_t lastWeight = 0;
// WIFI check variables
unsigned long lastWifiCheckTime = 0; unsigned long lastWifiCheckTime = 0;
const unsigned long wifiCheckInterval = 60000; // Überprüfe alle 60 Sekunden (60000 ms) 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 ##### // ##### PROGRAM START #####
void loop() { void loop() {
unsigned long currentMillis = millis(); 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 // Überprüfe regelmäßig die WLAN-Verbindung
if (intervalElapsed(currentMillis, lastWifiCheckTime, wifiCheckInterval)) { if (intervalElapsed(currentMillis, lastWifiCheckTime, wifiCheckInterval)) {
checkWiFiConnection(); checkWiFiConnection();
@@ -119,14 +98,9 @@ void loop() {
// Wenn Bambu auto set Spool aktiv // Wenn Bambu auto set Spool aktiv
if (autoSendToBambu && autoSetToBambuSpoolId > 0) { if (autoSendToBambu && autoSetToBambuSpoolId > 0) {
if (!bambuDisabled && !bambu_connected)
{
bambu_restart();
}
if (intervalElapsed(currentMillis, lastAutoSetBambuAmsTime, autoSetBambuAmsInterval)) if (intervalElapsed(currentMillis, lastAutoSetBambuAmsTime, autoSetBambuAmsInterval))
{ {
if (nfcReaderState == NFC_IDLE) if (hasReadRfidTag == 0)
{ {
lastAutoSetBambuAmsTime = currentMillis; lastAutoSetBambuAmsTime = currentMillis;
oledShowMessage("Auto Set " + String(autoSetBambuAmsCounter - autoAmsCounter) + "s"); oledShowMessage("Auto Set " + String(autoSetBambuAmsCounter - autoAmsCounter) + "s");
@@ -160,7 +134,7 @@ void loop() {
// Ausgabe der Waage auf Display // Ausgabe der Waage auf Display
if(pauseMainTask == 0) 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); (weight < 2) ? ((weight < -2) ? oledShowMessage("!! -0") : oledShowWeight(0)) : oledShowWeight(weight);
} }
@@ -173,18 +147,27 @@ void loop() {
// Wenn Timer abgelaufen und nicht gerade ein RFID-Tag geschrieben wird // 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; lastWeightReadTime = currentMillis;
// Prüfen ob die Waage korrekt genullt ist // Prüfen ob die Waage korrekt genullt ist
if (autoTare && (weight > 0 && weight < 5) || weight < 0) if ((weight > 0 && weight < 5) || weight < 0)
{ {
scale_tare_counter++; if(scaleTareCounter < 5)
{
scaleTareCounter++;
}
else
{
scaleTareRequest = true;
scaleTareCounter = 0;
}
} }
else else
{ {
scale_tare_counter = 0; scaleTareCounter = 0;
} }
// Prüfen ob das Gewicht gleich bleibt und dann senden // Prüfen ob das Gewicht gleich bleibt und dann senden
@@ -200,17 +183,15 @@ void loop() {
} }
// reset weight counter after writing tag // reset weight counter after writing tag
// TBD: what exactly is the logic behind this? if (currentMillis - lastWeightReadTime >= weightReadInterval && hasReadRfidTag > 1)
if (currentMillis - lastWeightReadTime >= weightReadInterval && nfcReaderState != NFC_IDLE && nfcReaderState != NFC_READ_SUCCESS)
{ {
weigthCouterToApi = 0; weigthCouterToApi = 0;
} }
lastWeight = weight; lastWeight = weight;
// Wenn ein Tag mit SM id erkannte wurde und der Waage Counter anspricht an SM Senden // 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"); oledShowIcon("loading");
if (updateSpoolWeight(spoolId, weight)) if (updateSpoolWeight(spoolId, weight))
{ {
@@ -230,6 +211,6 @@ void loop() {
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
} }
} }
esp_task_wdt_reset(); esp_task_wdt_reset();
} }
+89 -121
View File
@@ -32,7 +32,7 @@ String spoolId = "";
String nfcJsonData = ""; String nfcJsonData = "";
volatile bool pauseBambuMqttTask = false; volatile bool pauseBambuMqttTask = false;
volatile nfcReaderStateType nfcReaderState = NFC_IDLE; volatile uint8_t hasReadRfidTag = 0;
// 0 = nicht gelesen // 0 = nicht gelesen
// 1 = erfolgreich gelesen // 1 = erfolgreich gelesen
// 2 = fehler beim Lesen // 2 = fehler beim Lesen
@@ -185,12 +185,12 @@ void processTag(uint8_t *uid, uint8_t uidLength, uint8_t readerNumber) {
void processNfcData(uint8_t *data, String tagId) { void processNfcData(uint8_t *data, String tagId) {
// Process the data and send it via WebSocket // Process the data and send it via WebSocket
if (decodeNdefAndReturnJson(data)) { if (decodeNdefAndReturnJson(data)) {
nfcReaderState = NFC_READ_SUCCESS; hasReadRfidTag = 1;
sendNfcData(nullptr); sendNfcData(nullptr);
} else { } else {
nfcReaderState = NFC_READ_ERROR; hasReadRfidTag = 2;
oledShowMessage("NFC-Tag unknown"); oledShowMessage("NFC-Tag unknown");
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
} }
} }
@@ -407,7 +407,7 @@ void writeJsonToTag(void *parameter) {
Serial.println("Erstelle NDEF-Message..."); Serial.println("Erstelle NDEF-Message...");
Serial.println(payload); Serial.println(payload);
nfcReaderState = NFC_WRITING; hasReadRfidTag = 3;
vTaskSuspend(RfidReaderTask); vTaskSuspend(RfidReaderTask);
vTaskDelay(50 / portTICK_PERIOD_MS); vTaskDelay(50 / portTICK_PERIOD_MS);
@@ -462,7 +462,7 @@ void writeJsonToTag(void *parameter) {
Serial.println("NDEF-Message erfolgreich auf den Tag geschrieben"); Serial.println("NDEF-Message erfolgreich auf den Tag geschrieben");
oledShowIcon("success"); oledShowIcon("success");
vTaskDelay(1000 / portTICK_PERIOD_MS); vTaskDelay(1000 / portTICK_PERIOD_MS);
nfcReaderState = NFC_WRITE_SUCCESS; hasReadRfidTag = 5;
sendNfcData(nullptr); sendNfcData(nullptr);
pauseBambuMqttTask = false; pauseBambuMqttTask = false;
@@ -481,15 +481,15 @@ void writeJsonToTag(void *parameter) {
Serial.println("Fehler beim Schreiben der NDEF-Message auf den Tag"); Serial.println("Fehler beim Schreiben der NDEF-Message auf den Tag");
oledShowIcon("failed"); oledShowIcon("failed");
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
nfcReaderState = NFC_WRITE_ERROR; hasReadRfidTag = 4;
} }
} else { } else {
Serial.println("Fehler: Kein Tag zu schreiben gefunden."); Serial.println("Fehler: Kein Tag zu schreiben gefunden.");
oledShowMessage("No NFC-Tag found"); oledShowMessage("No NFC-Tag found");
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
nfcReaderState = NFC_IDLE; hasReadRfidTag = 0;
} }
sendWriteResult(nullptr, success); sendWriteResult(nullptr, success);
sendNfcData(nullptr); sendNfcData(nullptr);
@@ -503,7 +503,7 @@ void startWriteJsonToTag(const char* payload) {
char* payloadCopy = strdup(payload); char* payloadCopy = strdup(payload);
// Task nicht mehrfach starten // Task nicht mehrfach starten
if (nfcReaderState != NFC_WRITING) { if (hasReadRfidTag != 3) {
// Erstelle die Task // Erstelle die Task
xTaskCreate( xTaskCreate(
writeJsonToTag, // Task-Funktion writeJsonToTag, // Task-Funktion
@@ -518,108 +518,90 @@ void startWriteJsonToTag(const char* payload) {
void scanRfidTask(void * parameter) { void scanRfidTask(void * parameter) {
Serial.println("RFID Task gestartet"); Serial.println("RFID Task gestartet");
if (nfcReaderState != NFC_WRITING) for(;;) {
{ if (hasReadRfidTag != 3) {
yield(); yield();
uint8_t success = 0; uint8_t success = 0;
uint8_t uid[] = {0, 0, 0, 0, 0, 0, 0}; uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t uidLength; uint8_t uidLength;
Adafruit_PN532 *activeReader = nullptr; Adafruit_PN532* activeReader = nullptr;
// Try first reader with increased timeout // Try first reader with increased timeout
success = nfc1.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 150); success = nfc1.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 150);
if (success) if (success) {
{ activeReader = &nfc1;
activeReader = &nfc1; } else {
} delay(50); // Small delay between readers
else // Try second reader with increased timeout
{ success = nfc2.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 150);
delay(50); // Small delay between readers if (success) {
// Try second reader with increased timeout activeReader = &nfc2;
success = nfc2.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 150); }
if (success)
{
activeReader = &nfc2;
}
}
foundNfcTag(nullptr, success);
if (success && nfcReaderState != NFC_READ_SUCCESS && activeReader != nullptr)
{
Serial.println("Found an ISO14443A card");
nfcReaderState = NFC_READING;
oledShowIcon("transfer");
vTaskDelay(500 / portTICK_PERIOD_MS);
if (uidLength == 7)
{
uint16_t tagSize = readTagSize(*activeReader);
if (tagSize > 0)
{
uint8_t *data = (uint8_t *)malloc(tagSize);
memset(data, 0, tagSize);
Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");
uint8_t numPages = readTagSize(*activeReader) / 4;
for (uint8_t i = 4; i < 4 + numPages; i++)
{
if (!activeReader->ntag2xx_ReadPage(i, data + (i - 4) * 4))
{
break;
}
if (data[(i - 4) * 4] == 0xFE)
{
break;
}
yield();
esp_task_wdt_reset();
vTaskDelay(pdMS_TO_TICKS(5)); // Increased delay between page reads
} }
if (!decodeNdefAndReturnJson(data)) foundNfcTag(nullptr, success);
{
oledShowMessage("NFC-Tag unknown"); if (success && hasReadRfidTag != 1 && activeReader != nullptr) {
vTaskDelay(2000 / portTICK_PERIOD_MS); Serial.println("Found an ISO14443A card");
nfcReaderState = NFC_READ_ERROR;
} hasReadRfidTag = 6;
else oledShowIcon("transfer");
{ vTaskDelay(500 / portTICK_PERIOD_MS);
nfcReaderState = NFC_READ_SUCCESS;
if (uidLength == 7) {
uint16_t tagSize = readTagSize(*activeReader);
if(tagSize > 0) {
uint8_t* data = (uint8_t*)malloc(tagSize);
memset(data, 0, tagSize);
Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");
uint8_t numPages = readTagSize(*activeReader)/4;
for (uint8_t i = 4; i < 4+numPages; i++) {
if (!activeReader->ntag2xx_ReadPage(i, data+(i-4) * 4)) {
break;
}
if (data[(i - 4) * 4] == 0xFE) {
break;
}
yield();
esp_task_wdt_reset();
vTaskDelay(pdMS_TO_TICKS(5)); // Increased delay between page reads
}
if (!decodeNdefAndReturnJson(data)) {
oledShowMessage("NFC-Tag unknown");
vTaskDelay(2000 / portTICK_PERIOD_MS);
hasReadRfidTag = 2;
} else {
hasReadRfidTag = 1;
}
free(data);
} else {
oledShowMessage("NFC-Tag read error");
hasReadRfidTag = 2;
}
} else {
Serial.println("This doesn't seem to be an NTAG2xx tag (UUID length != 7 bytes)!");
}
} }
free(data); if (!success && hasReadRfidTag > 0) {
} hasReadRfidTag = 0;
else nfcJsonData = "";
{ Serial.println("Tag entfernt");
oledShowMessage("NFC-Tag read error"); if (!autoSendToBambu) oledShowWeight(weight);
nfcReaderState = NFC_READ_ERROR; }
}
}
else
{
Serial.println("This doesn't seem to be an NTAG2xx tag (UUID length != 7 bytes)!");
}
}
if (!success && nfcReaderState != NFC_IDLE) sendNfcData(nullptr);
{ delay(100); // Add small delay at end of loop
nfcReaderState = NFC_IDLE; }
nfcJsonData = "";
Serial.println("Tag entfernt");
if (!autoSendToBambu)
oledShowWeight(weight);
}
sendNfcData(nullptr);
delay(100); // Add small delay at end of loop
}
yield(); yield();
} }
}
void startNfc() { void startNfc() {
initNfc(); initNfc();
@@ -639,20 +621,6 @@ void startNfc() {
} }
} }
String createTagId(uint8_t *uid, uint8_t uidLength) String createTagId(uint8_t *uid, uint8_t uidLength) {
{ // Implementierung der Funktion
String tagId = ""; // Initialisieren Sie einen leeren String
// Erstellen Sie die Tag-ID basierend auf dem UID
for (uint8_t i = 0; i < uidLength; i++)
{
tagId += String(uid[i], HEX); // Konvertieren Sie die UID in einen String
if (i < uidLength - 1)
{
tagId += ":"; // Fügen Sie einen Trennstrich hinzu, wenn es nicht das letzte Element ist
}
}
return tagId; // Geben Sie die erstellte Tag-ID zurück
Serial.println("tagID:" + tagId);
} }
+1 -11
View File
@@ -2,16 +2,6 @@
#include <Arduino.h> #include <Arduino.h>
#include <Adafruit_PN532.h> #include <Adafruit_PN532.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 startNfc();
void startWriteJsonToTag(const char* payload); void startWriteJsonToTag(const char* payload);
@@ -24,7 +14,7 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage);
extern TaskHandle_t RfidReaderTask; extern TaskHandle_t RfidReaderTask;
extern String nfcJsonData; extern String nfcJsonData;
extern String spoolId; extern String spoolId;
extern volatile nfcReaderStateType nfcReaderState; extern volatile uint8_t hasReadRfidTag;
extern volatile bool pauseBambuMqttTask; extern volatile bool pauseBambuMqttTask;
// Function declarations // Function declarations
+4 -42
View File
@@ -14,7 +14,6 @@ TaskHandle_t ScaleTask;
int16_t weight = 0; int16_t weight = 0;
uint8_t weigthCouterToApi = 0; uint8_t weigthCouterToApi = 0;
uint8_t scale_tare_counter = 0;
bool scaleTareRequest = false; bool scaleTareRequest = false;
uint8_t pauseMainTask = 0; uint8_t pauseMainTask = 0;
uint8_t scaleCalibrated = 1; uint8_t scaleCalibrated = 1;
@@ -22,26 +21,9 @@ uint8_t scaleCalibrated = 1;
Preferences preferences; Preferences preferences;
const char* NVS_NAMESPACE = "scale"; const char* NVS_NAMESPACE = "scale";
const char* NVS_KEY_CALIBRATION = "cal_value"; const char* NVS_KEY_CALIBRATION = "cal_value";
const char *NVS_KEY_AUTOTARE = "auto_tare";
bool autoTare = true;
// ##### Funktionen für Waage ##### // ##### Funktionen für Waage #####
uint8_t setAutoTare(bool autoTareValue) uint8_t tareScale() {
{
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"); Serial.println("Tare scale");
scale.tare(); scale.tare();
@@ -56,23 +38,11 @@ void scale_loop(void * parameter) {
for(;;) { for(;;) {
if (scale.is_ready()) if (scale.is_ready())
{ {
// Waage automatisch Taren, wenn zu lange Abweichung // Waage nochmal Taren, wenn zu lange Abweichung
if (autoTare && scale_tare_counter >= 5) if (scaleTareRequest == true)
{
Serial.println("Auto Tare scale");
scale.tare();
scale_tare_counter = 0;
}
// Waage manuell Taren
if (scaleTareRequest == true)
{ {
Serial.println("Re-Tare scale"); Serial.println("Re-Tare scale");
oledShowMessage("TARE Scale");
vTaskDelay(pdMS_TO_TICKS(1000));
scale.tare(); scale.tare();
vTaskDelay(pdMS_TO_TICKS(1000));
oledShowWeight(0);
scaleTareRequest = false; scaleTareRequest = false;
} }
@@ -83,21 +53,13 @@ void scale_loop(void * parameter) {
} }
} }
void start_scale(bool touchSensorConnected) void start_scale() {
{
Serial.println("Prüfe Calibration Value"); Serial.println("Prüfe Calibration Value");
float calibrationValue; float calibrationValue;
// NVS lesen // NVS lesen
preferences.begin(NVS_NAMESPACE, true); // true = readonly preferences.begin(NVS_NAMESPACE, true); // true = readonly
calibrationValue = preferences.getFloat(NVS_KEY_CALIBRATION, defaultScaleCalibrationValue); 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(); preferences.end();
Serial.print("Read Scale Calibration Value "); Serial.print("Read Scale Calibration Value ");
+2 -4
View File
@@ -4,19 +4,17 @@
#include <Arduino.h> #include <Arduino.h>
#include "HX711.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 calibrate_scale();
uint8_t tareScale(); uint8_t tareScale();
extern HX711 scale; extern HX711 scale;
extern int16_t weight; extern int16_t weight;
extern uint8_t weigthCouterToApi; extern uint8_t weigthCouterToApi;
extern uint8_t scale_tare_counter;
extern uint8_t scaleTareRequest; extern uint8_t scaleTareRequest;
extern uint8_t pauseMainTask; extern uint8_t pauseMainTask;
extern uint8_t scaleCalibrated; extern uint8_t scaleCalibrated;
extern bool autoTare;
extern TaskHandle_t ScaleTask; extern TaskHandle_t ScaleTask;
+37 -66
View File
@@ -22,13 +22,14 @@ AsyncWebServer server(webserverPort);
AsyncWebSocket ws("/ws"); AsyncWebSocket ws("/ws");
uint8_t lastSuccess = 0; 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) { void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
if (type == WS_EVT_CONNECT) { if (type == WS_EVT_CONNECT) {
Serial.println("Neuer Client verbunden!"); Serial.println("Neuer Client verbunden!");
// Sende die AMS-Daten an den neuen Client // Sende die AMS-Daten an den neuen Client
if (!bambuDisabled) sendAmsData(client); sendAmsData(client);
sendNfcData(client); sendNfcData(client);
foundNfcTag(client, 0); foundNfcTag(client, 0);
sendWriteResult(client, 3); sendWriteResult(client, 3);
@@ -42,7 +43,6 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
String message = String((char*)data); String message = String((char*)data);
JsonDocument doc; JsonDocument doc;
deserializeJson(doc, message); deserializeJson(doc, message);
bool spoolmanConnected = (spoolmanApiState != API_INIT);
if (doc["type"] == "heartbeat") { if (doc["type"] == "heartbeat") {
// Sende Heartbeat-Antwort // Sende Heartbeat-Antwort
@@ -50,7 +50,7 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
"\"type\":\"heartbeat\"," "\"type\":\"heartbeat\","
"\"freeHeap\":" + String(ESP.getFreeHeap()/1024) + "," "\"freeHeap\":" + String(ESP.getFreeHeap()/1024) + ","
"\"bambu_connected\":" + String(bambu_connected) + "," "\"bambu_connected\":" + String(bambu_connected) + ","
"\"spoolman_connected\":" + String(spoolmanConnected) + "" "\"spoolman_connected\":" + String(spoolman_connected) + ""
"}"); "}");
} }
@@ -73,11 +73,6 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
success = calibrate_scale(); success = calibrate_scale();
} }
if (doc["payload"] == "setAutoTare")
{
success = setAutoTare(doc["enabled"].as<bool>());
}
if (success) { if (success) {
ws.textAll("{\"type\":\"scale\",\"payload\":\"success\"}"); ws.textAll("{\"type\":\"scale\",\"payload\":\"success\"}");
} else { } else {
@@ -144,33 +139,34 @@ void foundNfcTag(AsyncWebSocketClient *client, uint8_t success) {
} }
void sendNfcData(AsyncWebSocketClient *client) { void sendNfcData(AsyncWebSocketClient *client) {
if (lastnfcReaderState == nfcReaderState) if (lastHasReadRfidTag == hasReadRfidTag) return;
return; if (hasReadRfidTag == 0) {
// TBD: Why is there no status for reading the tag?
switch (nfcReaderState)
{
case NFC_IDLE:
ws.textAll("{\"type\":\"nfcData\", \"payload\":{}}"); ws.textAll("{\"type\":\"nfcData\", \"payload\":{}}");
break; }
case NFC_READ_SUCCESS: else if (hasReadRfidTag == 1) {
ws.textAll("{\"type\":\"nfcData\", \"payload\":" + nfcJsonData + "}"); ws.textAll("{\"type\":\"nfcData\", \"payload\":" + nfcJsonData + "}");
break; }
case NFC_READ_ERROR: else if (hasReadRfidTag == 2)
{
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Empty Tag or Data not readable\"}}"); ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Empty Tag or Data not readable\"}}");
break; }
case NFC_WRITING: else if (hasReadRfidTag == 3)
{
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"info\":\"Schreibe Tag...\"}}"); ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"info\":\"Schreibe Tag...\"}}");
break; }
case NFC_WRITE_SUCCESS: else if (hasReadRfidTag == 4)
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"info\":\"Tag erfolgreich geschrieben\"}}"); {
break;
case NFC_WRITE_ERROR:
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Error writing to Tag\"}}"); ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Error writing to Tag\"}}");
break; }
case DEFAULT: else if (hasReadRfidTag == 5)
{
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"info\":\"Tag erfolgreich geschrieben\"}}");
}
else
{
ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Something went wrong\"}}"); ws.textAll("{\"type\":\"nfcData\", \"payload\":{\"error\":\"Something went wrong\"}}");
} }
lastnfcReaderState = nfcReaderState; lastHasReadRfidTag = hasReadRfidTag;
} }
void sendAmsData(AsyncWebSocketClient *client) { void sendAmsData(AsyncWebSocketClient *client) {
@@ -206,24 +202,18 @@ void setupWebserver(AsyncWebServer &server) {
}); });
// Route für Waage // Route für Waage
server.on("/waage", HTTP_GET, [](AsyncWebServerRequest *request) server.on("/waage", HTTP_GET, [](AsyncWebServerRequest *request){
{
Serial.println("Anfrage für /waage erhalten"); Serial.println("Anfrage für /waage erhalten");
//AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/waage.html.gz", "text/html"); AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/waage.html.gz", "text/html");
//response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
//response->addHeader("Cache-Control", CACHE_CONTROL); response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response);
String html = loadHtmlWithHeader("/waage.html"); });
html.replace("{{autoTare}}", (autoTare) ? "checked" : "");
request->send(200, "text/html", html); });
// Route für RFID // Route für RFID
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Anfrage für /rfid erhalten"); Serial.println("Anfrage für /rfid erhalten");
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/rfid.html.gz", "text/html");
String page = (bambuDisabled) ? "/rfid.html.gz" : "/rfid_bambu.html.gz";
AsyncWebServerResponse *response = request->beginResponse(LittleFS, page, "text/html");
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", CACHE_CONTROL); response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response); request->send(response);
@@ -296,16 +286,6 @@ void setupWebserver(AsyncWebServer &server) {
} }
String url = request->getParam("url")->value(); String url = request->getParam("url")->value();
if (url.indexOf("http://") == -1 && url.indexOf("https://") == -1)
{
url = "http://" + url;
}
// Remove trailing slash if exists
if (url.length() > 0 && url.charAt(url.length() - 1) == '/')
{
url = url.substring(0, url.length() - 1);
}
bool octoEnabled = (request->getParam("octoEnabled")->value() == "true") ? true : false; bool octoEnabled = (request->getParam("octoEnabled")->value() == "true") ? true : false;
String octoUrl = request->getParam("octoUrl")->value(); String octoUrl = request->getParam("octoUrl")->value();
String octoToken = (request->getParam("octoToken")->value() != "") ? request->getParam("octoToken")->value() : ""; String octoToken = (request->getParam("octoToken")->value() != "") ? request->getParam("octoToken")->value() : "";
@@ -320,18 +300,8 @@ void setupWebserver(AsyncWebServer &server) {
request->send(200, "application/json", jsonResponse); request->send(200, "application/json", jsonResponse);
}); });
// Route für das Überprüfen der Bambu-Instanz // Route für das Überprüfen der Spoolman-Instanz
server.on("/api/bambu", HTTP_GET, [](AsyncWebServerRequest *request) 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")) { if (!request->hasParam("bambu_ip") || !request->hasParam("bambu_serialnr") || !request->hasParam("bambu_accesscode")) {
request->send(400, "application/json", "{\"success\": false, \"error\": \"Missing parameter\"}"); request->send(400, "application/json", "{\"success\": false, \"error\": \"Missing parameter\"}");
return; return;
@@ -355,7 +325,8 @@ void setupWebserver(AsyncWebServer &server) {
bool success = saveBambuCredentials(bambu_ip, bambu_serialnr, bambu_accesscode, autoSend, autoSendTime); bool success = saveBambuCredentials(bambu_ip, bambu_serialnr, bambu_accesscode, autoSend, autoSendTime);
request->send(200, "application/json", "{\"healthy\": " + String(success ? "true" : "false") + "}"); }); request->send(200, "application/json", "{\"healthy\": " + String(success ? "true" : "false") + "}");
});
// Route für das Überprüfen der Spoolman-Instanz // Route für das Überprüfen der Spoolman-Instanz
server.on("/reboot", HTTP_GET, [](AsyncWebServerRequest *request){ server.on("/reboot", HTTP_GET, [](AsyncWebServerRequest *request){
+1 -1
View File
@@ -59,7 +59,7 @@ void initWiFi() {
if(wm_nonblocking) wm.setConfigPortalBlocking(false); if(wm_nonblocking) wm.setConfigPortalBlocking(false);
//wm.setConfigPortalTimeout(320); // Portal nach 5min schließen //wm.setConfigPortalTimeout(320); // Portal nach 5min schließen
wm.setWiFiAutoReconnect(true); wm.setWiFiAutoReconnect(true);
wm.setConnectTimeout(10); wm.setConnectTimeout(5);
oledShowTopRow(); oledShowTopRow();
oledShowMessage("WiFi Setup"); oledShowMessage("WiFi Setup");