docs: add backup and restore functions for JSON configurations during OTA updates

This commit is contained in:
Manuel Weiser 2025-02-21 17:38:20 +01:00
parent 38b68aecfc
commit b0b3d41c84
3 changed files with 66 additions and 6 deletions

View File

@ -29,12 +29,37 @@ void stopAllTasks() {
Serial.println("All tasks stopped"); Serial.println("All tasks stopped");
} }
void backupJsonConfigs() {
const char* configs[] = {"/bambu_credentials.json", "/spoolman_url.json"};
for (const char* config : configs) {
if (SPIFFS.exists(config)) {
String backupPath = String(config) + ".bak";
SPIFFS.remove(backupPath);
SPIFFS.rename(config, backupPath);
}
}
}
void restoreJsonConfigs() {
const char* configs[] = {"/bambu_credentials.json", "/spoolman_url.json"};
for (const char* config : configs) {
String backupPath = String(config) + ".bak";
if (SPIFFS.exists(backupPath)) {
SPIFFS.remove(config);
SPIFFS.rename(backupPath, config);
}
}
}
void performStageTwo() { void performStageTwo() {
if (!SPIFFS.begin(true)) { if (!SPIFFS.begin(true)) {
Serial.println("Error: Could not mount SPIFFS for stage 2"); Serial.println("Error: Could not mount SPIFFS for stage 2");
return; return;
} }
// Backup JSON configs before update
backupJsonConfigs();
File firmwareFile = SPIFFS.open("/firmware.bin", "r"); File firmwareFile = SPIFFS.open("/firmware.bin", "r");
if (!firmwareFile) { if (!firmwareFile) {
Serial.println("Error: Could not open firmware.bin from SPIFFS"); Serial.println("Error: Could not open firmware.bin from SPIFFS");
@ -71,6 +96,10 @@ void performStageTwo() {
firmwareFile.close(); firmwareFile.close();
SPIFFS.remove("/firmware.bin"); // Cleanup SPIFFS.remove("/firmware.bin"); // Cleanup
// Restore JSON configs after update
restoreJsonConfigs();
Serial.println("Stage 2 update successful, restarting..."); Serial.println("Stage 2 update successful, restarting...");
delay(500); delay(500);
ESP.restart(); ESP.restart();

View File

@ -8,8 +8,11 @@
#define UPDATE_SIZE_UNKNOWN 0xFFFFFFFF #define UPDATE_SIZE_UNKNOWN 0xFFFFFFFF
#endif #endif
void stopAllTasks(); void handleOTAUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final);
void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
void checkForStagedUpdate(); void checkForStagedUpdate();
void performStageTwo();
void stopAllTasks();
void backupJsonConfigs();
void restoreJsonConfigs();
#endif #endif

View File

@ -7,7 +7,6 @@
#include "nfc.h" #include "nfc.h"
#include "scale.h" #include "scale.h"
#include "esp_task_wdt.h" #include "esp_task_wdt.h"
#include "ota.h"
#include <Update.h> #include <Update.h>
#ifndef VERSION #ifndef VERSION
@ -444,26 +443,29 @@ void setupWebserver(AsyncWebServer &server) {
} }
void handleOTAUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) { void handleOTAUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
static bool isSpiffsUpdate = false;
if (!index) { if (!index) {
// Start eines neuen Uploads // Start eines neuen Uploads
Serial.println("Update Start: " + filename); Serial.println("Update Start: " + filename);
// Überprüfe den Dateityp basierend auf dem Dateinamen // Überprüfe den Dateityp basierend auf dem Dateinamen
bool isFirmware = filename.startsWith("filaman_"); bool isFirmware = filename.startsWith("filaman_");
bool isWebpage = filename.startsWith("webpage_"); isSpiffsUpdate = filename.startsWith("webpage_");
if (!isFirmware && !isWebpage) { if (!isFirmware && !isSpiffsUpdate) {
request->send(400, "application/json", "{\"message\":\"Invalid file type. File must start with 'filaman_' or 'webpage_'\"}"); request->send(400, "application/json", "{\"message\":\"Invalid file type. File must start with 'filaman_' or 'webpage_'\"}");
return; return;
} }
// Wähle den Update-Typ basierend auf dem Dateinamen // Wähle den Update-Typ basierend auf dem Dateinamen
if (isWebpage) { if (isSpiffsUpdate) {
if (!Update.begin(SPIFFS.totalBytes(), U_SPIFFS)) { if (!Update.begin(SPIFFS.totalBytes(), U_SPIFFS)) {
Update.printError(Serial); Update.printError(Serial);
request->send(400, "application/json", "{\"message\":\"SPIFFS Update failed: " + String(Update.errorString()) + "\"}"); request->send(400, "application/json", "{\"message\":\"SPIFFS Update failed: " + String(Update.errorString()) + "\"}");
return; return;
} }
// Backup JSON configs before SPIFFS update
backupJsonConfigs();
} else { } else {
if (!Update.begin(UPDATE_SIZE_UNKNOWN, U_FLASH)) { if (!Update.begin(UPDATE_SIZE_UNKNOWN, U_FLASH)) {
Update.printError(Serial); Update.printError(Serial);
@ -485,8 +487,34 @@ void handleOTAUpload(AsyncWebServerRequest *request, const String& filename, siz
request->send(400, "application/json", "{\"message\":\"Update failed: " + String(Update.errorString()) + "\"}"); request->send(400, "application/json", "{\"message\":\"Update failed: " + String(Update.errorString()) + "\"}");
return; return;
} }
if (isSpiffsUpdate) {
// Restore JSON configs after SPIFFS update
restoreJsonConfigs();
}
request->send(200, "application/json", "{\"message\":\"Update successful!\", \"restart\": true}"); request->send(200, "application/json", "{\"message\":\"Update successful!\", \"restart\": true}");
delay(500); delay(500);
ESP.restart(); ESP.restart();
} }
} }
void backupJsonConfigs() {
const char* configs[] = {"/bambu_credentials.json", "/spoolman_url.json"};
for (const char* config : configs) {
if (SPIFFS.exists(config)) {
String backupPath = String(config) + ".bak";
SPIFFS.remove(backupPath);
SPIFFS.rename(config, backupPath);
}
}
}
void restoreJsonConfigs() {
const char* configs[] = {"/bambu_credentials.json", "/spoolman_url.json"};
for (const char* config : configs) {
String backupPath = String(config) + ".bak";
if (SPIFFS.exists(backupPath)) {
SPIFFS.remove(config);
SPIFFS.rename(backupPath, config);
}
}
}