diff --git a/src/ota.cpp b/src/ota.cpp new file mode 100644 index 0000000..038dd67 --- /dev/null +++ b/src/ota.cpp @@ -0,0 +1,192 @@ +#include +#include +#include + +// Globale Variablen für Config Backups hinzufügen +String bambuCredentialsBackup; +String spoolmanUrlBackup; + +// Globale Variable für den Update-Typ +static int currentUpdateCommand = 0; + +// Globale Update-Variablen +static size_t updateTotalSize = 0; +static size_t updateWritten = 0; +static bool isSpiffsUpdate = false; + + +void backupJsonConfigs() { + // Bambu Credentials backup + if (SPIFFS.exists("/bambu_credentials.json")) { + File file = SPIFFS.open("/bambu_credentials.json", "r"); + if (file) { + bambuCredentialsBackup = file.readString(); + file.close(); + Serial.println("Bambu credentials backed up"); + } + } + + // Spoolman URL backup + if (SPIFFS.exists("/spoolman_url.json")) { + File file = SPIFFS.open("/spoolman_url.json", "r"); + if (file) { + spoolmanUrlBackup = file.readString(); + file.close(); + Serial.println("Spoolman URL backed up"); + } + } +} + +void restoreJsonConfigs() { + // Restore Bambu credentials + if (bambuCredentialsBackup.length() > 0) { + File file = SPIFFS.open("/bambu_credentials.json", "w"); + if (file) { + file.print(bambuCredentialsBackup); + file.close(); + Serial.println("Bambu credentials restored"); + } + bambuCredentialsBackup = ""; // Clear backup + } + + // Restore Spoolman URL + if (spoolmanUrlBackup.length() > 0) { + File file = SPIFFS.open("/spoolman_url.json", "w"); + if (file) { + file.print(spoolmanUrlBackup); + file.close(); + Serial.println("Spoolman URL restored"); + } + spoolmanUrlBackup = ""; // Clear backup + } +} + +void sendUpdateProgress(int progress, const char* status = nullptr, const char* message = nullptr) { + static int lastSentProgress = -1; + + // Verhindere zu häufige Updates + if (progress == lastSentProgress && !status && !message) { + return; + } + + String progressMsg = "{\"type\":\"updateProgress\",\"progress\":" + String(progress); + if (status) { + progressMsg += ",\"status\":\"" + String(status) + "\""; + } + if (message) { + progressMsg += ",\"message\":\"" + String(message) + "\""; + } + progressMsg += "}"; + + // Sende die Nachricht mehrmals mit Verzögerung für wichtige Updates + if (status || abs(progress - lastSentProgress) >= 10 || progress == 100) { + for (int i = 0; i < 2; i++) { + ws.textAll(progressMsg); + delay(100); // Längerer Delay zwischen Nachrichten + } + } else { + ws.textAll(progressMsg); + delay(50); + } + + lastSentProgress = progress; +} + +void handleUpdate(AsyncWebServer &server) { + AsyncCallbackWebHandler* updateHandler = new AsyncCallbackWebHandler(); + updateHandler->setUri("/update"); + updateHandler->setMethod(HTTP_POST); + + updateHandler->onUpload([](AsyncWebServerRequest *request, String filename, + size_t index, uint8_t *data, size_t len, bool final) { + if (!index) { + updateTotalSize = request->contentLength(); + updateWritten = 0; + isSpiffsUpdate = (filename.indexOf("website") > -1); + + if (isSpiffsUpdate) { + // Backup vor dem Update + sendUpdateProgress(0, "backup", "Backing up configurations..."); + delay(200); + backupJsonConfigs(); + delay(200); + + const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, NULL); + if (!partition || !Update.begin(partition->size, U_SPIFFS)) { + request->send(400, "application/json", "{\"success\":false,\"message\":\"Update initialization failed\"}"); + return; + } + sendUpdateProgress(5, "starting", "Starting SPIFFS update..."); + delay(200); + } else { + if (!Update.begin(updateTotalSize)) { + request->send(400, "application/json", "{\"success\":false,\"message\":\"Update initialization failed\"}"); + return; + } + sendUpdateProgress(0, "starting", "Starting firmware update..."); + delay(200); + } + } + + if (len) { + if (Update.write(data, len) != len) { + request->send(400, "application/json", "{\"success\":false,\"message\":\"Write failed\"}"); + return; + } + + updateWritten += len; + int currentProgress; + + // Berechne den Fortschritt basierend auf dem Update-Typ + if (isSpiffsUpdate) { + // SPIFFS: 5-75% für Upload + currentProgress = 5 + (updateWritten * 100) / updateTotalSize; + } else { + // Firmware: 0-100% für Upload + currentProgress = 1 + (updateWritten * 100) / updateTotalSize; + } + + static int lastProgress = -1; + if (currentProgress != lastProgress && (currentProgress % 10 == 0 || final)) { + sendUpdateProgress(currentProgress, "uploading"); + oledShowMessage("Update: " + String(currentProgress) + "%"); + delay(50); + lastProgress = currentProgress; + } + } + + if (final) { + if (Update.end(true)) { + if (isSpiffsUpdate) { + restoreJsonConfigs(); + } + } else { + request->send(400, "application/json", "{\"success\":false,\"message\":\"Update finalization failed\"}"); + } + } + }); + + updateHandler->onRequest([](AsyncWebServerRequest *request) { + if (Update.hasError()) { + request->send(400, "application/json", "{\"success\":false,\"message\":\"Update failed\"}"); + return; + } + + // Erste 100% Nachricht + ws.textAll("{\"type\":\"updateProgress\",\"progress\":100,\"status\":\"success\",\"message\":\"Update successful! Restarting device...\"}"); + delay(2000); // Längerer Delay für die erste Nachricht + + AsyncWebServerResponse *response = request->beginResponse(200, "application/json", + "{\"success\":true,\"message\":\"Update successful! Restarting device...\"}"); + response->addHeader("Connection", "close"); + request->send(response); + + // Zweite 100% Nachricht zur Sicherheit + ws.textAll("{\"type\":\"updateProgress\",\"progress\":100,\"status\":\"success\",\"message\":\"Update successful! Restarting device...\"}"); + delay(3000); // Noch längerer Delay vor dem Neustart + + ESP.restart(); + }); + + server.addHandler(updateHandler); +} \ No newline at end of file diff --git a/src/ota.h b/src/ota.h new file mode 100644 index 0000000..a9740fc --- /dev/null +++ b/src/ota.h @@ -0,0 +1,9 @@ +#ifndef OTA_H +#define OTA_H + +#include +#include + +void handleUpdate(AsyncWebServer &server); + +#endif \ No newline at end of file diff --git a/src/website.cpp b/src/website.cpp index b656563..ab96d78 100644 --- a/src/website.cpp +++ b/src/website.cpp @@ -9,6 +9,7 @@ #include "esp_task_wdt.h" #include #include "display.h" +#include "ota.h" #ifndef VERSION #define VERSION "1.1.0" @@ -23,48 +24,6 @@ AsyncWebSocket ws("/ws"); uint8_t lastSuccess = 0; uint8_t lastHasReadRfidTag = 0; -// Globale Variablen für Config Backups hinzufügen -String bambuCredentialsBackup; -String spoolmanUrlBackup; - -// Globale Variable für den Update-Typ -static int currentUpdateCommand = 0; - -// Globale Update-Variablen -static size_t updateTotalSize = 0; -static size_t updateWritten = 0; -static bool isSpiffsUpdate = false; - -void sendUpdateProgress(int progress, const char* status = nullptr, const char* message = nullptr) { - static int lastSentProgress = -1; - - // Verhindere zu häufige Updates - if (progress == lastSentProgress && !status && !message) { - return; - } - - String progressMsg = "{\"type\":\"updateProgress\",\"progress\":" + String(progress); - if (status) { - progressMsg += ",\"status\":\"" + String(status) + "\""; - } - if (message) { - progressMsg += ",\"message\":\"" + String(message) + "\""; - } - progressMsg += "}"; - - // Sende die Nachricht mehrmals mit Verzögerung für wichtige Updates - if (status || abs(progress - lastSentProgress) >= 10 || progress == 100) { - for (int i = 0; i < 2; i++) { - ws.textAll(progressMsg); - delay(100); // Längerer Delay zwischen Nachrichten - } - } else { - ws.textAll(progressMsg); - delay(50); - } - - lastSentProgress = progress; -} void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { if (type == WS_EVT_CONNECT) { @@ -207,105 +166,6 @@ void sendAmsData(AsyncWebSocketClient *client) { } } -void handleUpdate(AsyncWebServer &server) { - AsyncCallbackWebHandler* updateHandler = new AsyncCallbackWebHandler(); - updateHandler->setUri("/update"); - updateHandler->setMethod(HTTP_POST); - - updateHandler->onUpload([](AsyncWebServerRequest *request, String filename, - size_t index, uint8_t *data, size_t len, bool final) { - if (!index) { - updateTotalSize = request->contentLength(); - updateWritten = 0; - isSpiffsUpdate = (filename.indexOf("website") > -1); - - if (isSpiffsUpdate) { - // Backup vor dem Update - sendUpdateProgress(0, "backup", "Backing up configurations..."); - delay(200); - backupJsonConfigs(); - delay(200); - - const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, NULL); - if (!partition || !Update.begin(partition->size, U_SPIFFS)) { - request->send(400, "application/json", "{\"success\":false,\"message\":\"Update initialization failed\"}"); - return; - } - sendUpdateProgress(5, "starting", "Starting SPIFFS update..."); - delay(200); - } else { - if (!Update.begin(updateTotalSize)) { - request->send(400, "application/json", "{\"success\":false,\"message\":\"Update initialization failed\"}"); - return; - } - sendUpdateProgress(0, "starting", "Starting firmware update..."); - delay(200); - } - } - - if (len) { - if (Update.write(data, len) != len) { - request->send(400, "application/json", "{\"success\":false,\"message\":\"Write failed\"}"); - return; - } - - updateWritten += len; - int currentProgress; - - // Berechne den Fortschritt basierend auf dem Update-Typ - if (isSpiffsUpdate) { - // SPIFFS: 5-75% für Upload - currentProgress = 5 + (updateWritten * 100) / updateTotalSize; - } else { - // Firmware: 0-100% für Upload - currentProgress = 1 + (updateWritten * 100) / updateTotalSize; - } - - static int lastProgress = -1; - if (currentProgress != lastProgress && (currentProgress % 10 == 0 || final)) { - sendUpdateProgress(currentProgress, "uploading"); - oledShowMessage("Update: " + String(currentProgress) + "%"); - delay(50); - lastProgress = currentProgress; - } - } - - if (final) { - if (Update.end(true)) { - if (isSpiffsUpdate) { - restoreJsonConfigs(); - } - } else { - request->send(400, "application/json", "{\"success\":false,\"message\":\"Update finalization failed\"}"); - } - } - }); - - updateHandler->onRequest([](AsyncWebServerRequest *request) { - if (Update.hasError()) { - request->send(400, "application/json", "{\"success\":false,\"message\":\"Update failed\"}"); - return; - } - - // Erste 100% Nachricht - ws.textAll("{\"type\":\"updateProgress\",\"progress\":100,\"status\":\"success\",\"message\":\"Update successful! Restarting device...\"}"); - delay(2000); // Längerer Delay für die erste Nachricht - - AsyncWebServerResponse *response = request->beginResponse(200, "application/json", - "{\"success\":true,\"message\":\"Update successful! Restarting device...\"}"); - response->addHeader("Connection", "close"); - request->send(response); - - // Zweite 100% Nachricht zur Sicherheit - ws.textAll("{\"type\":\"updateProgress\",\"progress\":100,\"status\":\"success\",\"message\":\"Update successful! Restarting device...\"}"); - delay(3000); // Noch längerer Delay vor dem Neustart - - ESP.restart(); - }); - - server.addHandler(updateHandler); -} - void setupWebserver(AsyncWebServer &server) { // Deaktiviere alle Debug-Ausgaben Serial.setDebugOutput(false); @@ -534,50 +394,3 @@ void setupWebserver(AsyncWebServer &server) { server.begin(); Serial.println("Webserver gestartet"); } - - -void backupJsonConfigs() { - // Bambu Credentials backup - if (SPIFFS.exists("/bambu_credentials.json")) { - File file = SPIFFS.open("/bambu_credentials.json", "r"); - if (file) { - bambuCredentialsBackup = file.readString(); - file.close(); - Serial.println("Bambu credentials backed up"); - } - } - - // Spoolman URL backup - if (SPIFFS.exists("/spoolman_url.json")) { - File file = SPIFFS.open("/spoolman_url.json", "r"); - if (file) { - spoolmanUrlBackup = file.readString(); - file.close(); - Serial.println("Spoolman URL backed up"); - } - } -} - -void restoreJsonConfigs() { - // Restore Bambu credentials - if (bambuCredentialsBackup.length() > 0) { - File file = SPIFFS.open("/bambu_credentials.json", "w"); - if (file) { - file.print(bambuCredentialsBackup); - file.close(); - Serial.println("Bambu credentials restored"); - } - bambuCredentialsBackup = ""; // Clear backup - } - - // Restore Spoolman URL - if (spoolmanUrlBackup.length() > 0) { - File file = SPIFFS.open("/spoolman_url.json", "w"); - if (file) { - file.print(spoolmanUrlBackup); - file.close(); - Serial.println("Spoolman URL restored"); - } - spoolmanUrlBackup = ""; // Clear backup - } -} diff --git a/src/website.h b/src/website.h index ede6aa9..ad4a16e 100644 --- a/src/website.h +++ b/src/website.h @@ -19,7 +19,6 @@ extern AsyncWebSocket ws; // Server-Initialisierung und Handler void initWebServer(); -void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total); void setupWebserver(AsyncWebServer &server); @@ -29,8 +28,4 @@ void sendNfcData(AsyncWebSocketClient *client); void foundNfcTag(AsyncWebSocketClient *client, uint8_t success); void sendWriteResult(AsyncWebSocketClient *client, uint8_t success); -// Upgrade-Funktionen -void backupJsonConfigs(); -void restoreJsonConfigs(); - #endif