mirror of
https://github.com/esphome/esphome.git
synced 2025-10-04 19:03:47 +01:00
Use scheduler for api reboot
This commit is contained in:
@@ -47,6 +47,11 @@ void APIServer::setup() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Schedule reboot if no clients connect within timeout
|
||||||
|
if (this->reboot_timeout_ != 0) {
|
||||||
|
this->schedule_reboot_timeout_();
|
||||||
|
}
|
||||||
|
|
||||||
this->socket_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0); // monitored for incoming connections
|
this->socket_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0); // monitored for incoming connections
|
||||||
if (this->socket_ == nullptr) {
|
if (this->socket_ == nullptr) {
|
||||||
ESP_LOGW(TAG, "Could not create socket");
|
ESP_LOGW(TAG, "Could not create socket");
|
||||||
@@ -106,8 +111,6 @@ void APIServer::setup() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->last_connected_ = App.get_loop_component_start_time();
|
|
||||||
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
#ifdef USE_ESP32_CAMERA
|
||||||
if (esp32_camera::global_esp32_camera != nullptr && !esp32_camera::global_esp32_camera->is_internal()) {
|
if (esp32_camera::global_esp32_camera != nullptr && !esp32_camera::global_esp32_camera->is_internal()) {
|
||||||
esp32_camera::global_esp32_camera->add_image_callback(
|
esp32_camera::global_esp32_camera->add_image_callback(
|
||||||
@@ -121,6 +124,16 @@ void APIServer::setup() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void APIServer::schedule_reboot_timeout_() {
|
||||||
|
this->status_set_warning();
|
||||||
|
this->set_timeout("api_reboot", this->reboot_timeout_, []() {
|
||||||
|
if (!global_api_server->is_connected()) {
|
||||||
|
ESP_LOGE(TAG, "No client connected; rebooting");
|
||||||
|
App.reboot();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void APIServer::loop() {
|
void APIServer::loop() {
|
||||||
// Accept new clients only if the socket exists and has incoming connections
|
// Accept new clients only if the socket exists and has incoming connections
|
||||||
if (this->socket_ && this->socket_->ready()) {
|
if (this->socket_ && this->socket_->ready()) {
|
||||||
@@ -135,6 +148,12 @@ void APIServer::loop() {
|
|||||||
auto *conn = new APIConnection(std::move(sock), this);
|
auto *conn = new APIConnection(std::move(sock), this);
|
||||||
this->clients_.emplace_back(conn);
|
this->clients_.emplace_back(conn);
|
||||||
conn->start();
|
conn->start();
|
||||||
|
|
||||||
|
// Clear warning status and cancel reboot when first client connects
|
||||||
|
if (this->clients_.size() == 1 && this->reboot_timeout_ != 0) {
|
||||||
|
this->status_clear_warning();
|
||||||
|
this->cancel_timeout("api_reboot");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +173,12 @@ void APIServer::loop() {
|
|||||||
std::swap(this->clients_[client_index], this->clients_.back());
|
std::swap(this->clients_[client_index], this->clients_.back());
|
||||||
}
|
}
|
||||||
this->clients_.pop_back();
|
this->clients_.pop_back();
|
||||||
|
|
||||||
|
// Schedule reboot when last client disconnects
|
||||||
|
if (this->clients_.empty() && this->reboot_timeout_ != 0) {
|
||||||
|
this->schedule_reboot_timeout_();
|
||||||
|
}
|
||||||
|
|
||||||
// Don't increment client_index since we need to process the swapped element
|
// Don't increment client_index since we need to process the swapped element
|
||||||
} else {
|
} else {
|
||||||
// Process active client
|
// Process active client
|
||||||
@@ -163,19 +188,7 @@ void APIServer::loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->reboot_timeout_ != 0) {
|
// Reboot timeout is now handled by connection/disconnection events
|
||||||
const uint32_t now = App.get_loop_component_start_time();
|
|
||||||
if (!this->is_connected()) {
|
|
||||||
if (now - this->last_connected_ > this->reboot_timeout_) {
|
|
||||||
ESP_LOGE(TAG, "No client connected; rebooting");
|
|
||||||
App.reboot();
|
|
||||||
}
|
|
||||||
this->status_set_warning();
|
|
||||||
} else {
|
|
||||||
this->last_connected_ = now;
|
|
||||||
this->status_clear_warning();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIServer::dump_config() {
|
void APIServer::dump_config() {
|
||||||
|
@@ -142,6 +142,7 @@ class APIServer : public Component, public Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void schedule_reboot_timeout_();
|
||||||
// Pointers and pointer-like types first (4 bytes each)
|
// Pointers and pointer-like types first (4 bytes each)
|
||||||
std::unique_ptr<socket::Socket> socket_ = nullptr;
|
std::unique_ptr<socket::Socket> socket_ = nullptr;
|
||||||
Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>();
|
Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>();
|
||||||
@@ -150,7 +151,6 @@ class APIServer : public Component, public Controller {
|
|||||||
// 4-byte aligned types
|
// 4-byte aligned types
|
||||||
uint32_t reboot_timeout_{300000};
|
uint32_t reboot_timeout_{300000};
|
||||||
uint32_t batch_delay_{100};
|
uint32_t batch_delay_{100};
|
||||||
uint32_t last_connected_{0};
|
|
||||||
|
|
||||||
// Vectors and strings (12 bytes each on 32-bit)
|
// Vectors and strings (12 bytes each on 32-bit)
|
||||||
std::vector<std::unique_ptr<APIConnection>> clients_;
|
std::vector<std::unique_ptr<APIConnection>> clients_;
|
||||||
|
Reference in New Issue
Block a user