ESPHome  2024.3.1
web_server_base.cpp
Go to the documentation of this file.
1 #include "web_server_base.h"
2 #include "esphome/core/log.h"
4 #include "esphome/core/helpers.h"
5 
6 #ifdef USE_ARDUINO
7 #include <StreamString.h>
8 #if defined(USE_ESP32) || defined(USE_LIBRETINY)
9 #include <Update.h>
10 #endif
11 #ifdef USE_ESP8266
12 #include <Updater.h>
13 #endif
14 #endif
15 
16 namespace esphome {
17 namespace web_server_base {
18 
19 static const char *const TAG = "web_server_base";
20 
21 void WebServerBase::add_handler(AsyncWebHandler *handler) {
22  // remove all handlers
23 
24  if (!credentials_.username.empty()) {
25  handler = new internal::AuthMiddlewareHandler(handler, &credentials_);
26  }
27  this->handlers_.push_back(handler);
28  if (this->server_ != nullptr) {
29  this->server_->addHandler(handler);
30  }
31 }
32 
34 #ifdef USE_ARDUINO
35  StreamString ss;
36  Update.printError(ss);
37  ESP_LOGW(TAG, "OTA Update failed! Error: %s", ss.c_str());
38 #endif
39 }
40 
41 void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index,
42  uint8_t *data, size_t len, bool final) {
43 #ifdef USE_ARDUINO
44  bool success;
45  if (index == 0) {
46  ESP_LOGI(TAG, "OTA Update Start: %s", filename.c_str());
47  this->ota_read_length_ = 0;
48 #ifdef USE_ESP8266
49  Update.runAsync(true);
50  // NOLINTNEXTLINE(readability-static-accessed-through-instance)
51  success = Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
52 #endif
53 #if defined(USE_ESP32_FRAMEWORK_ARDUINO) || defined(USE_LIBRETINY)
54  if (Update.isRunning()) {
55  Update.abort();
56  }
57  success = Update.begin(UPDATE_SIZE_UNKNOWN, U_FLASH);
58 #endif
59  if (!success) {
61  return;
62  }
63  } else if (Update.hasError()) {
64  // don't spam logs with errors if something failed at start
65  return;
66  }
67 
68  success = Update.write(data, len) == len;
69  if (!success) {
71  return;
72  }
73  this->ota_read_length_ += len;
74 
75  const uint32_t now = millis();
76  if (now - this->last_ota_progress_ > 1000) {
77  if (request->contentLength() != 0) {
78  float percentage = (this->ota_read_length_ * 100.0f) / request->contentLength();
79  ESP_LOGD(TAG, "OTA in progress: %0.1f%%", percentage);
80  } else {
81  ESP_LOGD(TAG, "OTA in progress: %u bytes read", this->ota_read_length_);
82  }
83  this->last_ota_progress_ = now;
84  }
85 
86  if (final) {
87  if (Update.end(true)) {
88  ESP_LOGI(TAG, "OTA update successful!");
89  this->parent_->set_timeout(100, []() { App.safe_reboot(); });
90  } else {
92  }
93  }
94 #endif
95 }
96 void OTARequestHandler::handleRequest(AsyncWebServerRequest *request) {
97 #ifdef USE_ARDUINO
98  AsyncWebServerResponse *response;
99  if (!Update.hasError()) {
100  response = request->beginResponse(200, "text/plain", "Update Successful!");
101  } else {
102  StreamString ss;
103  ss.print("Update Failed: ");
104  Update.printError(ss);
105  response = request->beginResponse(200, "text/plain", ss);
106  }
107  response->addHeader("Connection", "close");
108  request->send(response);
109 #endif
110 }
111 
113 #ifdef USE_ARDUINO
114  this->add_handler(new OTARequestHandler(this)); // NOLINT
115 #endif
116 }
118  // Before WiFi (captive portal)
119  return setup_priority::WIFI + 2.0f;
120 }
121 
122 } // namespace web_server_base
123 } // namespace esphome
std::shared_ptr< AsyncWebServer > server_
void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) override
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
void add_handler(AsyncWebHandler *handler)
Application App
Global storage of Application pointer - only one Application can exist.
std::string size_t len
Definition: helpers.h:292
void handleRequest(AsyncWebServerRequest *request) override
std::vector< AsyncWebHandler * > handlers_
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7