Compare commits
12 Commits
3bb6c1caf5
...
739fe7e764
Author | SHA1 | Date | |
---|---|---|---|
739fe7e764 | |||
5f8953a19d | |||
c919eeb848 | |||
43177c670e | |||
1b50694f5f | |||
48edde8557 | |||
|
cb5d8ac10a | ||
|
bf48c6d4e1 | ||
|
5d2d5e9ee1 | ||
|
7e76612bb4 | ||
|
f038020042 | ||
|
8343fe887b |
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
.vscode/extensions.json
|
||||
.vscode/settings.json
|
||||
data
|
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,5 +1,24 @@
|
||||
# Changelog
|
||||
|
||||
## [1.5.6] - 2025-07-28
|
||||
### Added
|
||||
- Adds ENABLE_HEAP_DEBUGGING define as comment to the build flags
|
||||
- Adds data directory and further .vscode files to to .gitignore
|
||||
- Introduces new heap debugging feature and fixes some memory leaks in website feature
|
||||
|
||||
### Changed
|
||||
- update webpages for version v1.5.6
|
||||
- update platformio.ini for version v1.5.6
|
||||
- Merge pull request #42 from janecker/configuration_nvs_storage
|
||||
- Merge branch 'main' into configuration_nvs_storage
|
||||
- Changes configuration storage of spoolman and bambu values
|
||||
|
||||
### Fixed
|
||||
- Merge pull request #41 from janecker/memory_leak_fixes
|
||||
- Fixes compiler warnings in nfc
|
||||
- Memory leak fixes in api and nfc, location tag fix
|
||||
|
||||
|
||||
## [1.5.5] - 2025-07-22
|
||||
### Added
|
||||
- Fixes some issues with the new location tags
|
||||
|
BIN
html/.DS_Store
vendored
Normal file
BIN
html/.DS_Store
vendored
Normal file
Binary file not shown.
1
html/bambu_credentials.json
Normal file
1
html/bambu_credentials.json
Normal file
@@ -0,0 +1 @@
|
||||
{"bambu_ip": "192.168.1.14", "bambu_accesscode": "22772584", "bambu_serialnr": "01P00C492600230","autoSendToBambu":true,"autoSendTime": 60}
|
@@ -146,20 +146,20 @@
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Set URL/IP to your Spoolman-Instanz</h5>
|
||||
<input type="text" id="spoolmanUrl" placeholder="http://ip-or-url-of-your-spoolman-instanz:port">
|
||||
<h5 class="card-title">If you want to enable sending Spool to Spoolman Octoprint Plugin:</h5>
|
||||
<h5 class="card-title">Set URL/IP to your Spoolman instance</h5>
|
||||
<input type="text" id="spoolmanUrl" onkeydown="if(event.keyCode == 13) document.getElementById('btnSaveSpoolmanUrl').click()" placeholder="http://ip-or-url-of-your-spoolman-instance:port">
|
||||
<h5 class="card-title">If you want to enable sending the spool to the Spoolman Octoprint plugin:</h5>
|
||||
<p>
|
||||
<input type="checkbox" id="spoolmanOctoEnabled" {{spoolmanOctoEnabled}} onchange="toggleOctoFields()"> Send to Octo-Plugin
|
||||
</p>
|
||||
<div id="octoFields" style="display: none;">
|
||||
<p>
|
||||
<input type="text" id="spoolmanOctoUrl" placeholder="http://ip-or-url-of-your-octoprint-instanz:port" value="{{spoolmanOctoUrl}}">
|
||||
<input type="text" id="spoolmanOctoUrl" placeholder="http://ip-or-url-of-your-octoprint-instance:port" value="{{spoolmanOctoUrl}}">
|
||||
<input type="text" id="spoolmanOctoToken" placeholder="Your Octoprint Token" value="{{spoolmanOctoToken}}">
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button onclick="checkSpoolmanInstance()">Save Spoolman URL</button>
|
||||
<button id="btnSaveSpoolmanUrl" onclick="checkSpoolmanInstance()">Save Spoolman URL</button>
|
||||
<p id="statusMessage"></p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -169,16 +169,16 @@
|
||||
<h5 class="card-title">Bambu Lab Printer Credentials</h5>
|
||||
<div class="bambu-settings">
|
||||
<div class="input-group">
|
||||
<label for="bambuIp">Bambu Drucker IP-Adresse:</label>
|
||||
<label for="bambuIp">Bambu Printer IP Address:</label>
|
||||
<input type="text" id="bambuIp" placeholder="192.168.1.xxx" value="{{bambuIp}}">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="bambuSerial">Drucker Seriennummer:</label>
|
||||
<label for="bambuSerial">Printer Serial Number:</label>
|
||||
<input type="text" id="bambuSerial" placeholder="BBLXXXXXXXX" value="{{bambuSerial}}">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="bambuCode">Access Code:</label>
|
||||
<input type="text" id="bambuCode" placeholder="Access Code vom Drucker" value="{{bambuCode}}">
|
||||
<input type="text" id="bambuCode" placeholder="Access Code of the printer" value="{{bambuCode}}">
|
||||
</div>
|
||||
<hr>
|
||||
<p>If activated, FilaMan will automatically update the next filled tray with the last scanned and weighed spool.</p>
|
||||
|
1
html/spoolman_url.json
Normal file
1
html/spoolman_url.json
Normal file
@@ -0,0 +1 @@
|
||||
{"url": "http://192.168.1.5:7912", "octoEnabled": true, "octoUrl": "http://192.168.1.17:5001", "octoToken": "O5zZ58mXRAyeGpVEj2ZZj-UPAPqJ2N7JgtD36mw1M4g"}
|
@@ -9,7 +9,7 @@
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[common]
|
||||
version = "1.5.5"
|
||||
version = "1.5.6"
|
||||
to_old_version = "1.5.0"
|
||||
|
||||
##
|
||||
@@ -52,6 +52,7 @@ build_flags =
|
||||
-mtext-section-literals
|
||||
-DVERSION=\"${common.version}\"
|
||||
-DTOOLDVERSION=\"${common.to_old_version}\"
|
||||
#-DENABLE_HEAP_DEBUGGING
|
||||
-DASYNCWEBSERVER_REGEX
|
||||
#-DCORE_DEBUG_LEVEL=3
|
||||
-DCONFIG_ARDUHAL_LOG_COLORS=1
|
||||
|
71
src/api.cpp
71
src/api.cpp
@@ -2,6 +2,8 @@
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include "commonFS.h"
|
||||
#include <Preferences.h>
|
||||
#include "debug.h"
|
||||
|
||||
volatile spoolmanApiStateType spoolmanApiState = API_INIT;
|
||||
//bool spoolman_connected = false;
|
||||
@@ -87,6 +89,8 @@ JsonDocument fetchSingleSpoolInfo(int spoolId) {
|
||||
}
|
||||
|
||||
void sendToApi(void *parameter) {
|
||||
HEAP_DEBUG_MESSAGE("sendToApi begin");
|
||||
|
||||
spoolmanApiState = API_TRANSMITTING;
|
||||
SendToApiParams* params = (SendToApiParams*)parameter;
|
||||
|
||||
@@ -131,8 +135,8 @@ void sendToApi(void *parameter) {
|
||||
}
|
||||
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
doc.clear();
|
||||
}
|
||||
doc.clear();
|
||||
|
||||
} else {
|
||||
Serial.println("Fehler beim Senden an Spoolman! HTTP Code: " + String(httpCode));
|
||||
@@ -145,8 +149,9 @@ void sendToApi(void *parameter) {
|
||||
|
||||
// Speicher freigeben
|
||||
delete params;
|
||||
vTaskDelete(NULL);
|
||||
HEAP_DEBUG_MESSAGE("sendToApi end");
|
||||
spoolmanApiState = API_IDLE;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
bool updateSpoolTagId(String uidString, const char* payload) {
|
||||
@@ -169,6 +174,8 @@ bool updateSpoolTagId(String uidString, const char* payload) {
|
||||
Serial.print("Update Spule mit URL: ");
|
||||
Serial.println(spoolsUrl);
|
||||
|
||||
doc.clear();
|
||||
|
||||
// Update Payload erstellen
|
||||
JsonDocument updateDoc;
|
||||
updateDoc["extra"]["nfc_id"] = "\""+uidString+"\"";
|
||||
@@ -207,6 +214,7 @@ bool updateSpoolTagId(String uidString, const char* payload) {
|
||||
}
|
||||
|
||||
uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
|
||||
HEAP_DEBUG_MESSAGE("updateSpoolWeight begin");
|
||||
String spoolsUrl = spoolmanUrl + apiUrl + "/spool/" + spoolId + "/measure";
|
||||
Serial.print("Update Spule mit URL: ");
|
||||
Serial.println(spoolsUrl);
|
||||
@@ -241,11 +249,14 @@ uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
|
||||
);
|
||||
|
||||
updateDoc.clear();
|
||||
HEAP_DEBUG_MESSAGE("updateSpoolWeight end");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t updateSpoolLocation(String spoolId, String location){
|
||||
HEAP_DEBUG_MESSAGE("updateSpoolLocation begin");
|
||||
|
||||
String spoolsUrl = spoolmanUrl + apiUrl + "/spool/" + spoolId;
|
||||
Serial.print("Update Spule mit URL: ");
|
||||
Serial.println(spoolsUrl);
|
||||
@@ -281,6 +292,7 @@ uint8_t updateSpoolLocation(String spoolId, String location){
|
||||
|
||||
updateDoc.clear();
|
||||
|
||||
HEAP_DEBUG_MESSAGE("updateSpoolLocation end");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -345,6 +357,10 @@ bool updateSpoolBambuData(String payload) {
|
||||
|
||||
String updatePayload;
|
||||
serializeJson(updateDoc, updatePayload);
|
||||
|
||||
doc.clear();
|
||||
updateDoc.clear();
|
||||
|
||||
Serial.print("Update Payload: ");
|
||||
Serial.println(updatePayload);
|
||||
|
||||
@@ -511,6 +527,7 @@ bool checkSpoolmanExtraFields() {
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
doc.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,6 +574,8 @@ bool checkSpoolmanInstance(const String& url) {
|
||||
oledShowTopRow();
|
||||
return strcmp(status, "healthy") == 0;
|
||||
}
|
||||
|
||||
doc.clear();
|
||||
}
|
||||
} else {
|
||||
Serial.println("Error contacting spoolman instance! HTTP Code: " + String(httpCode));
|
||||
@@ -565,42 +584,38 @@ bool checkSpoolmanInstance(const String& url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool saveSpoolmanUrl(const String& url, bool octoOn, const String& octoWh, const String& octoTk) {
|
||||
if (!checkSpoolmanInstance(url)) return false;
|
||||
bool saveSpoolmanUrl(const String& url, bool octoOn, const String& octo_url, const String& octoTk) {
|
||||
Preferences preferences;
|
||||
preferences.begin(NVS_NAMESPACE_API, false); // false = readwrite
|
||||
preferences.putString(NVS_KEY_SPOOLMAN_URL, url);
|
||||
preferences.putBool(NVS_KEY_OCTOPRINT_ENABLED, octoOn);
|
||||
preferences.putString(NVS_KEY_OCTOPRINT_URL, octo_url);
|
||||
preferences.putString(NVS_KEY_OCTOPRINT_TOKEN, octoTk);
|
||||
preferences.end();
|
||||
|
||||
JsonDocument doc;
|
||||
doc["url"] = url;
|
||||
doc["octoEnabled"] = octoOn;
|
||||
doc["octoUrl"] = octoWh;
|
||||
doc["octoToken"] = octoTk;
|
||||
Serial.print("Speichere Spoolman Data in Datei: ");
|
||||
Serial.println(doc.as<String>());
|
||||
if (!saveJsonValue("/spoolman_url.json", doc)) {
|
||||
Serial.println("Fehler beim Speichern der Spoolman-URL.");
|
||||
return false;
|
||||
}
|
||||
//TBD: This could be handled nicer in the future
|
||||
spoolmanUrl = url;
|
||||
octoEnabled = octoOn;
|
||||
octoUrl = octoWh;
|
||||
octoUrl = octo_url;
|
||||
octoToken = octoTk;
|
||||
|
||||
doc.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String loadSpoolmanUrl() {
|
||||
JsonDocument doc;
|
||||
if (loadJsonValue("/spoolman_url.json", doc) && doc["url"].is<String>()) {
|
||||
octoEnabled = (doc["octoEnabled"].is<bool>()) ? doc["octoEnabled"].as<bool>() : false;
|
||||
if (octoEnabled && doc["octoToken"].is<String>() && doc["octoUrl"].is<String>())
|
||||
{
|
||||
octoUrl = doc["octoUrl"].as<String>();
|
||||
octoToken = doc["octoToken"].as<String>();
|
||||
}
|
||||
|
||||
return doc["url"].as<String>();
|
||||
Preferences preferences;
|
||||
preferences.begin(NVS_NAMESPACE_API, true);
|
||||
String spoolmanUrl = preferences.getString(NVS_KEY_SPOOLMAN_URL, "");
|
||||
octoEnabled = preferences.getBool(NVS_KEY_OCTOPRINT_ENABLED, false);
|
||||
if(octoEnabled)
|
||||
{
|
||||
octoUrl = preferences.getString(NVS_KEY_OCTOPRINT_URL, "");
|
||||
octoToken = preferences.getString(NVS_KEY_OCTOPRINT_TOKEN, "");
|
||||
}
|
||||
Serial.println("Keine gültige Spoolman-URL gefunden.");
|
||||
return "";
|
||||
preferences.end();
|
||||
return spoolmanUrl;
|
||||
}
|
||||
|
||||
bool initSpoolman() {
|
||||
|
148
src/bambu.cpp
148
src/bambu.cpp
@@ -10,6 +10,7 @@
|
||||
#include "esp_task_wdt.h"
|
||||
#include "config.h"
|
||||
#include "display.h"
|
||||
#include <Preferences.h>
|
||||
|
||||
WiFiClient espClient;
|
||||
SSLClient sslClient(&espClient);
|
||||
@@ -17,22 +18,13 @@ PubSubClient client(sslClient);
|
||||
|
||||
TaskHandle_t BambuMqttTask;
|
||||
|
||||
String topic = "";
|
||||
//String request_topic = "";
|
||||
const char* bambu_username = "bblp";
|
||||
const char* bambu_ip = nullptr;
|
||||
const char* bambu_accesscode = nullptr;
|
||||
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;
|
||||
int autoSetToBambuSpoolId = 0;
|
||||
|
||||
BambuCredentials bambuCredentials;
|
||||
|
||||
// Globale Variablen für AMS-Daten
|
||||
int ams_count = 0;
|
||||
String amsJsonData; // Speichert das fertige JSON für WebSocket-Clients
|
||||
@@ -43,18 +35,22 @@ bool removeBambuCredentials() {
|
||||
vTaskDelete(BambuMqttTask);
|
||||
}
|
||||
|
||||
if (!removeJsonValue("/bambu_credentials.json")) {
|
||||
Serial.println("Fehler beim Löschen der Bambu-Credentials.");
|
||||
return false;
|
||||
}
|
||||
Preferences preferences;
|
||||
preferences.begin(NVS_NAMESPACE_BAMBU, false); // false = readwrite
|
||||
preferences.remove(NVS_KEY_BAMBU_IP);
|
||||
preferences.remove(NVS_KEY_BAMBU_SERIAL);
|
||||
preferences.remove(NVS_KEY_BAMBU_ACCESSCODE);
|
||||
preferences.remove(NVS_KEY_BAMBU_AUTOSEND_ENABLE);
|
||||
preferences.remove(NVS_KEY_BAMBU_AUTOSEND_TIME);
|
||||
preferences.end();
|
||||
|
||||
// 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;
|
||||
bambuCredentials.ip = "";
|
||||
bambuCredentials.serial = "";
|
||||
bambuCredentials.accesscode = "";
|
||||
bambuCredentials.autosend_enable = false;
|
||||
bambuCredentials.autosend_time = BAMBU_DEFAULT_AUTOSEND_TIME;
|
||||
|
||||
autoSetToBambuSpoolId = 0;
|
||||
ams_count = 0;
|
||||
amsJsonData = "";
|
||||
@@ -68,25 +64,21 @@ bool saveBambuCredentials(const String& ip, const String& serialnr, const String
|
||||
if (BambuMqttTask) {
|
||||
vTaskDelete(BambuMqttTask);
|
||||
}
|
||||
|
||||
JsonDocument doc;
|
||||
doc["bambu_ip"] = ip;
|
||||
doc["bambu_accesscode"] = accesscode;
|
||||
doc["bambu_serialnr"] = serialnr;
|
||||
doc["autoSendToBambu"] = autoSend;
|
||||
doc["autoSendTime"] = (autoSendTime != "") ? autoSendTime.toInt() : autoSetBambuAmsCounter;
|
||||
|
||||
if (!saveJsonValue("/bambu_credentials.json", doc)) {
|
||||
Serial.println("Fehler beim Speichern der Bambu-Credentials.");
|
||||
return false;
|
||||
}
|
||||
bambuCredentials.ip = ip.c_str();
|
||||
bambuCredentials.serial = serialnr.c_str();
|
||||
bambuCredentials.accesscode = accesscode.c_str();
|
||||
bambuCredentials.autosend_enable = autoSend;
|
||||
bambuCredentials.autosend_time = autoSendTime.toInt();
|
||||
|
||||
// Dynamische Speicherallokation für die globalen Pointer
|
||||
bambu_ip = ip.c_str();
|
||||
bambu_accesscode = accesscode.c_str();
|
||||
bambu_serialnr = serialnr.c_str();
|
||||
autoSendToBambu = autoSend;
|
||||
autoSetBambuAmsCounter = autoSendTime.toInt();
|
||||
Preferences preferences;
|
||||
preferences.begin(NVS_NAMESPACE_BAMBU, false); // false = readwrite
|
||||
preferences.putString(NVS_KEY_BAMBU_IP, bambuCredentials.ip);
|
||||
preferences.putString(NVS_KEY_BAMBU_SERIAL, bambuCredentials.serial);
|
||||
preferences.putString(NVS_KEY_BAMBU_ACCESSCODE, bambuCredentials.accesscode);
|
||||
preferences.putBool(NVS_KEY_BAMBU_AUTOSEND_ENABLE, bambuCredentials.autosend_enable);
|
||||
preferences.putInt(NVS_KEY_BAMBU_AUTOSEND_TIME, bambuCredentials.autosend_time);
|
||||
preferences.end();
|
||||
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
if (!setupMqtt()) return false;
|
||||
@@ -95,35 +87,36 @@ bool saveBambuCredentials(const String& ip, const String& serialnr, const String
|
||||
}
|
||||
|
||||
bool loadBambuCredentials() {
|
||||
JsonDocument doc;
|
||||
if (loadJsonValue("/bambu_credentials.json", doc) && doc["bambu_ip"].is<String>()) {
|
||||
// Temporäre Strings für die Werte
|
||||
String ip = doc["bambu_ip"].as<String>();
|
||||
String code = doc["bambu_accesscode"].as<String>();
|
||||
String serial = doc["bambu_serialnr"].as<String>();
|
||||
Preferences preferences;
|
||||
preferences.begin(NVS_NAMESPACE_BAMBU, true);
|
||||
String ip = preferences.getString(NVS_KEY_BAMBU_IP, "");
|
||||
String serial = preferences.getString(NVS_KEY_BAMBU_SERIAL, "");
|
||||
String code = preferences.getString(NVS_KEY_BAMBU_ACCESSCODE, "");
|
||||
bool autosendEnable = preferences.getBool(NVS_KEY_BAMBU_AUTOSEND_ENABLE, false);
|
||||
int autosendTime = preferences.getInt(NVS_KEY_BAMBU_AUTOSEND_TIME, BAMBU_DEFAULT_AUTOSEND_TIME);
|
||||
preferences.end();
|
||||
|
||||
g_bambu_ip = ip;
|
||||
g_bambu_accesscode = code;
|
||||
g_bambu_serialnr = serial;
|
||||
if(ip != ""){
|
||||
bambuCredentials.ip = ip.c_str();
|
||||
bambuCredentials.serial = serial.c_str();
|
||||
bambuCredentials.accesscode = code.c_str();
|
||||
bambuCredentials.autosend_enable = autosendEnable;
|
||||
bambuCredentials.autosend_time = autosendTime;
|
||||
|
||||
if (doc["autoSendToBambu"].is<bool>()) autoSendToBambu = doc["autoSendToBambu"].as<bool>();
|
||||
if (doc["autoSendTime"].is<int>()) autoSetBambuAmsCounter = doc["autoSendTime"].as<int>();
|
||||
Serial.println("credentials loaded loadCredentials!");
|
||||
Serial.println(bambuCredentials.ip);
|
||||
Serial.println(bambuCredentials.serial);
|
||||
Serial.println(bambuCredentials.accesscode);
|
||||
Serial.println(String(bambuCredentials.autosend_enable));
|
||||
Serial.println(String(bambuCredentials.autosend_time));
|
||||
|
||||
ip.trim();
|
||||
code.trim();
|
||||
serial.trim();
|
||||
|
||||
// Dynamische Speicherallokation für die globalen Pointer
|
||||
bambu_ip = g_bambu_ip.c_str();
|
||||
bambu_accesscode = g_bambu_accesscode.c_str();
|
||||
bambu_serialnr = g_bambu_serialnr.c_str();
|
||||
|
||||
topic = "device/" + String(bambu_serialnr);
|
||||
//request_topic = "device/" + String(bambu_serialnr) + "/request";
|
||||
return true;
|
||||
}
|
||||
Serial.println("Keine gültigen Bambu-Credentials gefunden.");
|
||||
return false;
|
||||
else
|
||||
{
|
||||
Serial.println("Keine gültigen Bambu-Credentials gefunden.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct FilamentResult {
|
||||
@@ -226,7 +219,7 @@ FilamentResult findFilamentIdx(String brand, String type) {
|
||||
bool sendMqttMessage(const String& payload) {
|
||||
Serial.println("Sending MQTT message");
|
||||
Serial.println(payload);
|
||||
if (client.publish((String(topic) + "/request").c_str(), payload.c_str()))
|
||||
if (client.publish(("device/"+bambuCredentials.serial+"/request").c_str(), payload.c_str()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -499,7 +492,7 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
|
||||
trayObj["cali_idx"].as<String>() != ams_data[storedIndex].trays[j].cali_idx) {
|
||||
hasChanges = true;
|
||||
|
||||
if (autoSendToBambu && autoSetToBambuSpoolId > 0 && hasChanges)
|
||||
if (bambuCredentials.autosend_enable && autoSetToBambuSpoolId > 0 && hasChanges)
|
||||
{
|
||||
autoSetSpool(autoSetToBambuSpoolId, ams_data[storedIndex].trays[j].id);
|
||||
}
|
||||
@@ -523,7 +516,7 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
|
||||
(vtTray["tray_type"].as<String>() != "" && vtTray["cali_idx"].as<String>() != ams_data[i].trays[0].cali_idx)) {
|
||||
hasChanges = true;
|
||||
|
||||
if (autoSendToBambu && autoSetToBambuSpoolId > 0 && hasChanges)
|
||||
if (bambuCredentials.autosend_enable && autoSetToBambuSpoolId > 0 && hasChanges)
|
||||
{
|
||||
autoSetSpool(autoSetToBambuSpoolId, 254);
|
||||
}
|
||||
@@ -580,11 +573,11 @@ void reconnect() {
|
||||
oledShowTopRow();
|
||||
|
||||
// Attempt to connect
|
||||
String clientId = String(bambu_serialnr) + "_" + String(random(0, 100));
|
||||
if (client.connect(clientId.c_str(), bambu_username, bambu_accesscode)) {
|
||||
String clientId = bambuCredentials.serial + "_" + String(random(0, 100));
|
||||
if (client.connect(clientId.c_str(), BAMBU_USERNAME, bambuCredentials.accesscode.c_str())) {
|
||||
Serial.println("MQTT re/connected");
|
||||
|
||||
client.subscribe((String(topic) + "/report").c_str());
|
||||
client.subscribe(("device/"+bambuCredentials.serial+"/report").c_str());
|
||||
bambu_connected = true;
|
||||
oledShowTopRow();
|
||||
} else {
|
||||
@@ -630,28 +623,23 @@ void mqtt_loop(void * parameter) {
|
||||
|
||||
bool setupMqtt() {
|
||||
// Wenn Bambu Daten vorhanden
|
||||
bool success = loadBambuCredentials();
|
||||
//bool success = loadBambuCredentials();
|
||||
|
||||
if (!success) {
|
||||
bambuDisabled = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (success && bambu_ip != "" && bambu_accesscode != "" && bambu_serialnr != "")
|
||||
if (bambuCredentials.ip != "" && bambuCredentials.accesscode != "" && bambuCredentials.serial != "")
|
||||
{
|
||||
bambuDisabled = false;
|
||||
sslClient.setCACert(root_ca);
|
||||
sslClient.setInsecure();
|
||||
client.setServer(bambu_ip, 8883);
|
||||
client.setServer(bambuCredentials.ip.c_str(), 8883);
|
||||
|
||||
// Verbinden mit dem MQTT-Server
|
||||
bool connected = true;
|
||||
String clientId = String(bambu_serialnr) + "_" + String(random(0, 100));
|
||||
if (client.connect(clientId.c_str(), bambu_username, bambu_accesscode))
|
||||
String clientId = String(bambuCredentials.serial) + "_" + String(random(0, 100));
|
||||
if (client.connect(bambuCredentials.ip.c_str(), BAMBU_USERNAME, bambuCredentials.accesscode.c_str()))
|
||||
{
|
||||
client.setCallback(mqtt_callback);
|
||||
client.setBufferSize(15488);
|
||||
client.subscribe((String(topic) + "/report").c_str());
|
||||
client.subscribe(("device/"+bambuCredentials.serial+"/report").c_str());
|
||||
Serial.println("MQTT-Client initialisiert");
|
||||
|
||||
oledShowMessage("Bambu Connected");
|
||||
|
11
src/bambu.h
11
src/bambu.h
@@ -16,6 +16,14 @@ struct TrayData {
|
||||
String cali_idx;
|
||||
};
|
||||
|
||||
struct BambuCredentials {
|
||||
String ip;
|
||||
String serial;
|
||||
String accesscode;
|
||||
bool autosend_enable;
|
||||
int autosend_time;
|
||||
};
|
||||
|
||||
#define MAX_AMS 17 // 16 normale AMS + 1 externe Spule
|
||||
extern String amsJsonData; // Für die vorbereiteten JSON-Daten
|
||||
|
||||
@@ -28,9 +36,10 @@ extern bool bambu_connected;
|
||||
|
||||
extern int ams_count;
|
||||
extern AMSData ams_data[MAX_AMS];
|
||||
extern bool autoSendToBambu;
|
||||
//extern bool autoSendToBambu;
|
||||
extern int autoSetToBambuSpoolId;
|
||||
extern bool bambuDisabled;
|
||||
extern BambuCredentials bambuCredentials;
|
||||
|
||||
bool removeBambuCredentials();
|
||||
bool loadBambuCredentials();
|
||||
|
@@ -46,8 +46,6 @@ const uint8_t webserverPort = 80;
|
||||
const char* apiUrl = "/api/v1";
|
||||
// ***** API
|
||||
|
||||
// ***** Bambu Auto Set Spool
|
||||
uint8_t autoSetBambuAmsCounter = 60;
|
||||
// ***** Bambu Auto Set Spool
|
||||
|
||||
// ***** Task Prios
|
||||
|
25
src/config.h
25
src/config.h
@@ -3,6 +3,29 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#define BAMBU_DEFAULT_AUTOSEND_TIME 60
|
||||
|
||||
|
||||
#define NVS_NAMESPACE_API "api"
|
||||
#define NVS_KEY_SPOOLMAN_URL "spoolmanUrl"
|
||||
#define NVS_KEY_OCTOPRINT_ENABLED "octoEnabled"
|
||||
#define NVS_KEY_OCTOPRINT_URL "octoUrl"
|
||||
#define NVS_KEY_OCTOPRINT_TOKEN "octoToken"
|
||||
|
||||
#define NVS_NAMESPACE_BAMBU "bambu"
|
||||
#define NVS_KEY_BAMBU_IP "bambuIp"
|
||||
#define NVS_KEY_BAMBU_ACCESSCODE "bambuCode"
|
||||
#define NVS_KEY_BAMBU_SERIAL "bambuSerial"
|
||||
#define NVS_KEY_BAMBU_AUTOSEND_ENABLE "autosendEnable"
|
||||
#define NVS_KEY_BAMBU_AUTOSEND_TIME "autosendTime"
|
||||
|
||||
#define NVS_NAMESPACE_SCALE "scale"
|
||||
#define NVS_KEY_CALIBRATION "cal_value"
|
||||
#define NVS_KEY_AUTOTARE "auto_tare"
|
||||
|
||||
#define BAMBU_USERNAME "bblp"
|
||||
|
||||
|
||||
extern const uint8_t PN532_IRQ;
|
||||
extern const uint8_t PN532_RESET;
|
||||
|
||||
@@ -25,7 +48,7 @@ extern const uint8_t OLED_DATA_END;
|
||||
extern const char* apiUrl;
|
||||
extern const uint8_t webserverPort;
|
||||
|
||||
extern uint8_t autoSetBambuAmsCounter;
|
||||
|
||||
|
||||
extern const unsigned char wifi_on[];
|
||||
extern const unsigned char wifi_off[];
|
||||
|
12
src/debug.h
Normal file
12
src/debug.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_HEAP_DEBUGGING
|
||||
#define HEAP_DEBUG_MESSAGE(location) printHeapDebugData(location);
|
||||
#else
|
||||
#define HEAP_DEBUG_MESSAGE(location)
|
||||
#endif
|
||||
|
||||
inline void printHeapDebugData(String location){
|
||||
Serial.println("Heap: " + String(ESP.getMinFreeHeap()/1024) + "\t" + String(ESP.getFreeHeap()/1024) + "\t" + String(ESP.getMaxAllocHeap()/1024) + "\t" + location);
|
||||
}
|
14
src/main.cpp
14
src/main.cpp
@@ -119,7 +119,7 @@ void loop() {
|
||||
}
|
||||
|
||||
// Wenn Bambu auto set Spool aktiv
|
||||
if (autoSendToBambu && autoSetToBambuSpoolId > 0)
|
||||
if (bambuCredentials.autosend_enable && autoSetToBambuSpoolId > 0)
|
||||
{
|
||||
if (!bambuDisabled && !bambu_connected)
|
||||
{
|
||||
@@ -131,10 +131,10 @@ void loop() {
|
||||
if (nfcReaderState == NFC_IDLE)
|
||||
{
|
||||
lastAutoSetBambuAmsTime = currentMillis;
|
||||
oledShowMessage("Auto Set " + String(autoSetBambuAmsCounter - autoAmsCounter) + "s");
|
||||
oledShowMessage("Auto Set " + String(bambuCredentials.autosend_time - autoAmsCounter) + "s");
|
||||
autoAmsCounter++;
|
||||
|
||||
if (autoAmsCounter >= autoSetBambuAmsCounter)
|
||||
if (autoAmsCounter >= bambuCredentials.autosend_time)
|
||||
{
|
||||
autoSetToBambuSpoolId = 0;
|
||||
autoAmsCounter = 0;
|
||||
@@ -162,7 +162,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 && nfcReaderState == NFC_IDLE && (!bambuCredentials.autosend_enable || autoSetToBambuSpoolId == 0)))
|
||||
{
|
||||
(weight < 2) ? ((weight < -2) ? oledShowMessage("!! -0") : oledShowWeight(0)) : oledShowWeight(weight);
|
||||
}
|
||||
@@ -212,14 +212,14 @@ 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 (activeSpoolId != "" && weigthCouterToApi > 3 && weightSend == 0 && nfcReaderState == NFC_READ_SUCCESS) {
|
||||
oledShowIcon("loading");
|
||||
if (updateSpoolWeight(spoolId, weight))
|
||||
if (updateSpoolWeight(activeSpoolId, weight))
|
||||
{
|
||||
oledShowIcon("success");
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
weightSend = 1;
|
||||
autoSetToBambuSpoolId = spoolId.toInt();
|
||||
autoSetToBambuSpoolId = activeSpoolId.toInt();
|
||||
|
||||
if (octoEnabled)
|
||||
{
|
||||
|
24
src/nfc.cpp
24
src/nfc.cpp
@@ -7,6 +7,7 @@
|
||||
#include "api.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#include "scale.h"
|
||||
#include "bambu.h"
|
||||
|
||||
//Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
|
||||
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
|
||||
@@ -14,7 +15,8 @@ Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
|
||||
TaskHandle_t RfidReaderTask;
|
||||
|
||||
JsonDocument rfidData;
|
||||
String spoolId = "";
|
||||
String activeSpoolId = "";
|
||||
String lastSpoolId = "";
|
||||
String nfcJsonData = "";
|
||||
volatile bool pauseBambuMqttTask = false;
|
||||
|
||||
@@ -64,6 +66,8 @@ void payloadToJson(uint8_t *data) {
|
||||
Serial.print("deserializeJson() failed: ");
|
||||
Serial.println(error.f_str());
|
||||
}
|
||||
|
||||
doc.clear();
|
||||
} else {
|
||||
Serial.println("Kein gültiger JSON-Inhalt gefunden oder fehlerhafte Formatierung.");
|
||||
//writeJsonToTag("{\"version\":\"1.0\",\"protocol\":\"NFC\",\"color_hex\":\"#FFFFFF\",\"type\":\"Example\",\"min_temp\":10,\"max_temp\":30,\"brand\":\"BrandName\"}");
|
||||
@@ -218,17 +222,18 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage) {
|
||||
// Sende die aktualisierten AMS-Daten an alle WebSocket-Clients
|
||||
Serial.println("JSON-Dokument erfolgreich verarbeitet");
|
||||
Serial.println(doc.as<String>());
|
||||
if (doc.containsKey("sm_id") && doc["sm_id"] != "")
|
||||
if (doc["sm_id"].is<String>() && doc["sm_id"] != "")
|
||||
{
|
||||
Serial.println("SPOOL-ID gefunden: " + doc["sm_id"].as<String>());
|
||||
spoolId = doc["sm_id"].as<String>();
|
||||
activeSpoolId = doc["sm_id"].as<String>();
|
||||
lastSpoolId = activeSpoolId;
|
||||
}
|
||||
else if(doc.containsKey("location") && doc["location"] != "")
|
||||
else if(doc["location"].is<String>() && doc["location"] != "")
|
||||
{
|
||||
Serial.println("Location Tag found!");
|
||||
String location = doc["location"].as<String>();
|
||||
if(spoolId != ""){
|
||||
updateSpoolLocation(spoolId, location);
|
||||
if(lastSpoolId != ""){
|
||||
updateSpoolLocation(lastSpoolId, location);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -240,12 +245,14 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage) {
|
||||
else
|
||||
{
|
||||
Serial.println("Keine SPOOL-ID gefunden.");
|
||||
spoolId = "";
|
||||
activeSpoolId = "";
|
||||
oledShowMessage("Unknown Spool");
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
doc.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -446,8 +453,9 @@ void scanRfidTask(void * parameter) {
|
||||
nfcReaderState = NFC_IDLE;
|
||||
//uidString = "";
|
||||
nfcJsonData = "";
|
||||
activeSpoolId = "";
|
||||
Serial.println("Tag entfernt");
|
||||
if (!autoSendToBambu) oledShowWeight(weight);
|
||||
if (!bambuCredentials.autosend_enable) oledShowWeight(weight);
|
||||
}
|
||||
|
||||
// aktualisieren der Website wenn sich der Status ändert
|
||||
|
@@ -19,7 +19,8 @@ void startWriteJsonToTag(const char* payload);
|
||||
|
||||
extern TaskHandle_t RfidReaderTask;
|
||||
extern String nfcJsonData;
|
||||
extern String spoolId;
|
||||
extern String activeSpoolId;
|
||||
extern String lastSpoolId;
|
||||
extern volatile nfcReaderStateType nfcReaderState;
|
||||
extern volatile bool pauseBambuMqttTask;
|
||||
|
||||
|
@@ -18,11 +18,6 @@ uint8_t scale_tare_counter = 0;
|
||||
bool scaleTareRequest = false;
|
||||
uint8_t pauseMainTask = 0;
|
||||
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 #####
|
||||
@@ -32,7 +27,8 @@ uint8_t setAutoTare(bool autoTareValue) {
|
||||
autoTare = autoTareValue;
|
||||
|
||||
// Speichern mit NVS
|
||||
preferences.begin(NVS_NAMESPACE, false); // false = readwrite
|
||||
Preferences preferences;
|
||||
preferences.begin(NVS_NAMESPACE_SCALE, false); // false = readwrite
|
||||
preferences.putBool(NVS_KEY_AUTOTARE, autoTare);
|
||||
preferences.end();
|
||||
|
||||
@@ -90,7 +86,8 @@ void start_scale(bool touchSensorConnected) {
|
||||
float calibrationValue;
|
||||
|
||||
// NVS lesen
|
||||
preferences.begin(NVS_NAMESPACE, true); // true = readonly
|
||||
Preferences preferences;
|
||||
preferences.begin(NVS_NAMESPACE_SCALE, true); // true = readonly
|
||||
calibrationValue = preferences.getFloat(NVS_KEY_CALIBRATION, defaultScaleCalibrationValue);
|
||||
|
||||
// auto Tare
|
||||
@@ -197,12 +194,13 @@ uint8_t calibrate_scale() {
|
||||
Serial.println(newCalibrationValue);
|
||||
|
||||
// Speichern mit NVS
|
||||
preferences.begin(NVS_NAMESPACE, false); // false = readwrite
|
||||
Preferences preferences;
|
||||
preferences.begin(NVS_NAMESPACE_SCALE, false); // false = readwrite
|
||||
preferences.putFloat(NVS_KEY_CALIBRATION, newCalibrationValue);
|
||||
preferences.end();
|
||||
|
||||
// Verifizieren
|
||||
preferences.begin(NVS_NAMESPACE, true);
|
||||
preferences.begin(NVS_NAMESPACE_SCALE, true);
|
||||
float verifyValue = preferences.getFloat(NVS_KEY_CALIBRATION, 0);
|
||||
preferences.end();
|
||||
|
||||
|
@@ -10,6 +10,9 @@
|
||||
#include <Update.h>
|
||||
#include "display.h"
|
||||
#include "ota.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "1.1.0"
|
||||
@@ -26,6 +29,7 @@ nfcReaderStateType lastnfcReaderState = NFC_IDLE;
|
||||
|
||||
|
||||
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
||||
HEAP_DEBUG_MESSAGE("onWsEvent begin");
|
||||
if (type == WS_EVT_CONNECT) {
|
||||
Serial.println("Neuer Client verbunden!");
|
||||
// Sende die AMS-Daten an den neuen Client
|
||||
@@ -33,6 +37,10 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
|
||||
sendNfcData(client);
|
||||
foundNfcTag(client, 0);
|
||||
sendWriteResult(client, 3);
|
||||
|
||||
// Clean up dead connections
|
||||
(*server).cleanupClients();
|
||||
Serial.println("Currently connected number of clients: " + String((*server).getClients().size()));
|
||||
} else if (type == WS_EVT_DISCONNECT) {
|
||||
Serial.println("Client getrennt.");
|
||||
} else if (type == WS_EVT_ERROR) {
|
||||
@@ -113,7 +121,9 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
|
||||
else {
|
||||
Serial.println("Unbekannter WebSocket-Typ: " + doc["type"].as<String>());
|
||||
}
|
||||
doc.clear();
|
||||
}
|
||||
HEAP_DEBUG_MESSAGE("onWsEvent end");
|
||||
}
|
||||
|
||||
// Funktion zum Laden und Ersetzen des Headers in einer HTML-Datei
|
||||
@@ -195,6 +205,9 @@ void setupWebserver(AsyncWebServer &server) {
|
||||
Serial.print("Geladene Spoolman-URL: ");
|
||||
Serial.println(spoolmanUrl);
|
||||
|
||||
// Load Bamb credentials:
|
||||
loadBambuCredentials();
|
||||
|
||||
// Route für about
|
||||
server.on("/about", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
Serial.println("Anfrage für /about erhalten");
|
||||
@@ -254,31 +267,13 @@ void setupWebserver(AsyncWebServer &server) {
|
||||
html.replace("{{spoolmanOctoUrl}}", (octoUrl != "") ? octoUrl : "");
|
||||
html.replace("{{spoolmanOctoToken}}", (octoToken != "") ? octoToken : "");
|
||||
|
||||
JsonDocument doc;
|
||||
if (loadJsonValue("/bambu_credentials.json", doc) && doc["bambu_ip"].is<String>())
|
||||
{
|
||||
String bambuIp = doc["bambu_ip"].as<String>();
|
||||
String bambuSerial = doc["bambu_serialnr"].as<String>();
|
||||
String bambuCode = doc["bambu_accesscode"].as<String>();
|
||||
autoSendToBambu = doc["autoSendToBambu"].as<bool>();
|
||||
bambuIp.trim();
|
||||
bambuSerial.trim();
|
||||
bambuCode.trim();
|
||||
html.replace("{{bambuIp}}", bambuCredentials.ip);
|
||||
html.replace("{{bambuSerial}}", bambuCredentials.serial);
|
||||
html.replace("{{bambuCode}}", bambuCredentials.accesscode ? bambuCredentials.accesscode : "");
|
||||
html.replace("{{autoSendToBambu}}", bambuCredentials.autosend_enable ? "checked" : "");
|
||||
html.replace("{{autoSendTime}}", (bambuCredentials.autosend_time != 0) ? String(bambuCredentials.autosend_time) : String(BAMBU_DEFAULT_AUTOSEND_TIME));
|
||||
|
||||
html.replace("{{bambuIp}}", bambuIp ? bambuIp : "");
|
||||
html.replace("{{bambuSerial}}", bambuSerial ? bambuSerial : "");
|
||||
html.replace("{{bambuCode}}", bambuCode ? bambuCode : "");
|
||||
html.replace("{{autoSendToBambu}}", autoSendToBambu ? "checked" : "");
|
||||
html.replace("{{autoSendTime}}", String(autoSetBambuAmsCounter));
|
||||
}
|
||||
else
|
||||
{
|
||||
html.replace("{{bambuIp}}", "");
|
||||
html.replace("{{bambuSerial}}", "");
|
||||
html.replace("{{bambuCode}}", "");
|
||||
html.replace("{{autoSendToBambu}}", "");
|
||||
html.replace("{{autoSendTime}}", String(autoSetBambuAmsCounter));
|
||||
}
|
||||
doc.clear();
|
||||
|
||||
request->send(200, "text/html", html);
|
||||
});
|
||||
|
Reference in New Issue
Block a user