This commit is contained in:
J. Nick Koston 2025-06-29 15:23:32 -05:00
parent 3162bb475d
commit 78fd0a4870
No known key found for this signature in database
4 changed files with 23 additions and 17 deletions

View File

@ -14,7 +14,7 @@
#endif #endif
#endif #endif
#ifdef USE_WEBSERVER_OTA #if defined(USE_ESP_IDF) && defined(USE_WEBSERVER_OTA)
#include "esphome/components/ota/ota_backend.h" #include "esphome/components/ota/ota_backend.h"
#endif #endif
@ -119,15 +119,17 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Strin
this->ota_started_ = false; this->ota_started_ = false;
// Create OTA backend // Create OTA backend
this->ota_backend_ = ota::make_ota_backend(); auto backend = ota::make_ota_backend();
// Begin OTA with unknown size // Begin OTA with unknown size
auto result = this->ota_backend_->begin(0); auto result = backend->begin(0);
if (result != ota::OTA_RESPONSE_OK) { if (result != ota::OTA_RESPONSE_OK) {
ESP_LOGE(TAG, "OTA begin failed: %d", result); ESP_LOGE(TAG, "OTA begin failed: %d", result);
this->ota_backend_.reset();
return; return;
} }
// Store the backend pointer
this->ota_backend_ = backend.release();
this->ota_started_ = true; this->ota_started_ = true;
} else if (!this->ota_started_ || !this->ota_backend_) { } else if (!this->ota_started_ || !this->ota_backend_) {
// Begin failed or was aborted // Begin failed or was aborted
@ -136,11 +138,13 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Strin
// Write data // Write data
if (len > 0) { if (len > 0) {
auto result = this->ota_backend_->write(data, len); auto *backend = static_cast<ota::OTABackend *>(this->ota_backend_);
auto result = backend->write(data, len);
if (result != ota::OTA_RESPONSE_OK) { if (result != ota::OTA_RESPONSE_OK) {
ESP_LOGE(TAG, "OTA write failed: %d", result); ESP_LOGE(TAG, "OTA write failed: %d", result);
this->ota_backend_->abort(); backend->abort();
this->ota_backend_.reset(); delete backend;
this->ota_backend_ = nullptr;
this->ota_started_ = false; this->ota_started_ = false;
return; return;
} }
@ -150,13 +154,15 @@ void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const Strin
} }
if (final) { if (final) {
auto result = this->ota_backend_->end(); auto *backend = static_cast<ota::OTABackend *>(this->ota_backend_);
auto result = backend->end();
if (result == ota::OTA_RESPONSE_OK) { if (result == ota::OTA_RESPONSE_OK) {
this->schedule_ota_reboot_(); this->schedule_ota_reboot_();
} else { } else {
ESP_LOGE(TAG, "OTA end failed: %d", result); ESP_LOGE(TAG, "OTA end failed: %d", result);
} }
this->ota_backend_.reset(); delete backend;
this->ota_backend_ = nullptr;
this->ota_started_ = false; this->ota_started_ = false;
} }
#endif // USE_ESP_IDF #endif // USE_ESP_IDF
@ -176,8 +182,7 @@ void OTARequestHandler::handleRequest(AsyncWebServerRequest *request) {
} }
#endif // USE_ARDUINO #endif // USE_ARDUINO
#ifdef USE_ESP_IDF #ifdef USE_ESP_IDF
response = request->beginResponse( response = request->beginResponse(200, "text/plain", this->ota_started_ ? "Update Successful!" : "Update Failed!");
200, "text/plain", (this->ota_started_ && this->ota_backend_) ? "Update Successful!" : "Update Failed!");
#endif // USE_ESP_IDF #endif // USE_ESP_IDF
response->addHeader("Connection", "close"); response->addHeader("Connection", "close");
request->send(response); request->send(response);

View File

@ -148,8 +148,10 @@ class OTARequestHandler : public AsyncWebHandler {
uint32_t ota_read_length_{0}; uint32_t ota_read_length_{0};
#endif #endif
WebServerBase *parent_; WebServerBase *parent_;
private:
#if defined(USE_ESP_IDF) && defined(USE_WEBSERVER_OTA) #if defined(USE_ESP_IDF) && defined(USE_WEBSERVER_OTA)
std::unique_ptr<ota::OTABackend> ota_backend_; void *ota_backend_{nullptr}; // Actually ota::OTABackend*, stored as void* to avoid incomplete type issues
bool ota_started_{false}; bool ota_started_{false};
#endif #endif
}; };

View File

@ -1,6 +1,5 @@
from esphome.components.esp32 import add_idf_component, add_idf_sdkconfig_option from esphome.components.esp32 import add_idf_component, add_idf_sdkconfig_option
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import CONF_OTA
from esphome.core import CORE from esphome.core import CORE
CODEOWNERS = ["@dentra"] CODEOWNERS = ["@dentra"]
@ -17,6 +16,6 @@ async def to_code(config):
# Check if web_server component has OTA enabled # Check if web_server component has OTA enabled
web_server_config = CORE.config.get("web_server", {}) web_server_config = CORE.config.get("web_server", {})
if web_server_config.get(CONF_OTA, True): # OTA is enabled by default if web_server_config and web_server_config.get("ota", True):
# Add multipart parser component for OTA support # Add multipart parser component for ESP-IDF OTA support
add_idf_component(name="zorxx/multipart-parser", ref="1.0.1") add_idf_component(name="zorxx/multipart-parser", ref="1.0.1")

View File

@ -9,13 +9,13 @@
#include "esp_tls_crypto.h" #include "esp_tls_crypto.h"
#include "utils.h" #include "utils.h"
#include "web_server_idf.h"
#ifdef USE_WEBSERVER_OTA #ifdef USE_WEBSERVER_OTA
#include "multipart_reader.h" #include "multipart_reader.h"
#include "multipart_parser_utils.h" #include "multipart_parser_utils.h"
#endif #endif
#include "web_server_idf.h"
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
#include "esphome/components/web_server/web_server.h" #include "esphome/components/web_server/web_server.h"
#include "esphome/components/web_server/list_entities.h" #include "esphome/components/web_server/list_entities.h"