From 2b6606d8addae3a1642044e2b3245b1c13f55e5a Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 26 Dec 2025 15:25:41 +0100 Subject: [PATCH] disable uart when uploading, show when uploading, store flag showing its a new firmware --- src/ESP32React/UploadFileService.cpp | 22 ++++++++++++++++++++-- src/core/emsesp.cpp | 5 +++++ src/core/emsesp.h | 2 ++ src/core/system.cpp | 14 ++++++++++++-- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/ESP32React/UploadFileService.cpp b/src/ESP32React/UploadFileService.cpp index 88b1aa436..7a0312e6e 100644 --- a/src/ESP32React/UploadFileService.cpp +++ b/src/ESP32React/UploadFileService.cpp @@ -3,6 +3,7 @@ #include #include +#include static String getFilenameExtension(const String & filename) { const auto pos = filename.lastIndexOf('.'); @@ -81,6 +82,10 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri } #endif // it's firmware - initialize the ArduinoOTA updater + emsesp::EMSESP::logger().info("Uploading firmware file %s (size: %d bytes)", filename.c_str(), filesize); + // turn off UART to prevent interference with the upload + emsesp::EMSuart::stop(); + if (Update.begin(filesize - sizeof(esp_image_header_t))) { if (strlen(_md5.data()) == _md5.size() - 1) { Update.setMD5(_md5.data()); @@ -113,6 +118,8 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri } void UploadFileService::uploadComplete(AsyncWebServerRequest * request) { + emsesp::EMSESP::logger().info("Upload complete"); + // did we just complete uploading a json file? if (request->_tempFile) { request->_tempFile.close(); // close the file handle as the upload is now done @@ -126,6 +133,10 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) { // check if it was a firmware upgrade // if no error, send the success response as a JSON if (_is_firmware && !request->_tempObject) { + // set NVS to tell EMS-ESP this is a new firmware on next restart + // we do this by removing the install date + emsesp::EMSESP::nvs_.putBool(emsesp::EMSESP_NVS_BOOT_NEW_FIRMWARE, true); + AsyncWebServerResponse * response = request->beginResponse(200); request->send(response); emsesp::EMSESP::system_.systemStatus( @@ -147,6 +158,9 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) { } void UploadFileService::handleError(AsyncWebServerRequest * request, int code) { + emsesp::EMSESP::logger().info("Upload error: %d", code); + emsesp::EMSESP::system_.uart_init(); // re-enable UART + // if we have had an error already, do nothing if (request->_tempObject) { return; @@ -156,15 +170,19 @@ void UploadFileService::handleError(AsyncWebServerRequest * request, int code) { AsyncWebServerResponse * response = request->beginResponse(code); request->send(response); - // check for invalid extension and immediately kill the connection, which will through an error + // check for invalid extension and immediately kill the connection, which will throw an error // that is caught by the web code. Unfortunately the http error code is not sent to the client on fast network connections if (code == 406) { request->client()->close(true); - handleEarlyDisconnect(); + _is_firmware = false; + Update.abort(); } } void UploadFileService::handleEarlyDisconnect() { + emsesp::EMSESP::logger().info("Upload aborted"); + emsesp::EMSESP::system_.uart_init(); // re-enable UART + _is_firmware = false; Update.abort(); } diff --git a/src/core/emsesp.cpp b/src/core/emsesp.cpp index 0c5d030bd..9754ca180 100644 --- a/src/core/emsesp.cpp +++ b/src/core/emsesp.cpp @@ -1720,6 +1720,11 @@ void EMSESP::start() { #else LOG_INFO("EMS-ESP version %s", EMSESP_APP_VERSION); #endif + + if (!EMSESP::nvs_.getBool(EMSESP_NVS_BOOT_NEW_FIRMWARE)) { + LOG_DEBUG("Firmware is fresh"); + } + LOG_DEBUG("System is running in Debug mode"); LOG_INFO("Last system reset reason Core0: %s, Core1: %s", system_.reset_reason(0).c_str(), system_.reset_reason(1).c_str()); diff --git a/src/core/emsesp.h b/src/core/emsesp.h index 5fe7cfb99..c094f7f7a 100644 --- a/src/core/emsesp.h +++ b/src/core/emsesp.h @@ -96,6 +96,8 @@ using DeviceValueNumOp = DeviceValue::DeviceValueNumOp; class EMSESPShell; class Shower; +static constexpr const char * EMSESP_NVS_BOOT_NEW_FIRMWARE = "fresh_firmware"; // max 15 characters + class EMSESP { public: EMSESP(); diff --git a/src/core/system.cpp b/src/core/system.cpp index b7efae044..f9e7ce6f4 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -371,11 +371,21 @@ void System::get_partition_info() { void System::set_partition_install_date(bool override) { #ifndef EMSESP_STANDALONE auto current_partition = (const char *)esp_ota_get_running_partition()->label; - // skip if it already has an install date - if (!partition_info_[current_partition].install_date.empty() && !override) { + auto is_fresh_firmware = EMSESP::nvs_.getBool(EMSESP_NVS_BOOT_NEW_FIRMWARE); + + // reset flag after setting the install date + EMSESP::nvs_.putBool(EMSESP_NVS_BOOT_NEW_FIRMWARE, false); + + // skip if it already has an install date, unless override is true or the firmware is new + // EMSESP_NVS_BOOT_NEW_FIRMWARE is set in UploadFileService::uploadComplete() + if (!partition_info_[current_partition].install_date.empty() && !override && !is_fresh_firmware) { return; } + if (is_fresh_firmware) { + LOG_DEBUG("Firmware is fresh, setting the new install date"); + } + // set current date/time from NTP char time_string[25]; time_t now = time(nullptr);