From 1d52fceafa37b4feb0d8a4b6d630d9be0fd4325a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 15 Jun 2025 01:25:59 -0500 Subject: [PATCH] rename, cleanup --- esphome/components/anova/anova.cpp | 4 ++-- esphome/components/bedjet/bedjet_hub.cpp | 4 ++-- .../components/bedjet/climate/bedjet_climate.cpp | 4 ++-- .../ble_client/sensor/ble_rssi_sensor.cpp | 4 ++-- esphome/components/ble_client/sensor/ble_sensor.cpp | 4 ++-- .../ble_client/text_sensor/ble_text_sensor.cpp | 4 ++-- .../components/captive_portal/captive_portal.cpp | 9 ++++++++- esphome/components/captive_portal/captive_portal.h | 2 ++ .../components/esp32_ble_client/ble_client_base.cpp | 6 ++++++ .../components/esp32_ble_client/ble_client_base.h | 2 ++ .../esp32_improv/esp32_improv_component.cpp | 2 +- esphome/components/online_image/online_image.cpp | 4 ++++ esphome/components/preferences/syncer.h | 2 +- esphome/components/rtttl/rtttl.cpp | 9 ++++++++- esphome/components/safe_mode/safe_mode.cpp | 4 ++-- esphome/components/sntp/sntp_component.cpp | 2 +- esphome/components/tlc5971/tlc5971.cpp | 5 ++++- esphome/core/component.cpp | 11 +++++++++-- esphome/core/component.h | 13 ++++++++++--- 19 files changed, 70 insertions(+), 25 deletions(-) diff --git a/esphome/components/anova/anova.cpp b/esphome/components/anova/anova.cpp index c8d0d27b07..05463d4fc2 100644 --- a/esphome/components/anova/anova.cpp +++ b/esphome/components/anova/anova.cpp @@ -19,8 +19,8 @@ void Anova::setup() { void Anova::loop() { // This component uses polling via update() and BLE callbacks - // Empty loop not needed, mark as done to save CPU cycles - this->mark_loop_done(); + // Empty loop not needed, disable to save CPU cycles + this->disable_loop(); } void Anova::control(const ClimateCall &call) { diff --git a/esphome/components/bedjet/bedjet_hub.cpp b/esphome/components/bedjet/bedjet_hub.cpp index f9b330ccc9..be343eaf18 100644 --- a/esphome/components/bedjet/bedjet_hub.cpp +++ b/esphome/components/bedjet/bedjet_hub.cpp @@ -482,8 +482,8 @@ void BedJetHub::set_clock(uint8_t hour, uint8_t minute) { void BedJetHub::loop() { // This component uses polling via update() and BLE callbacks - // Empty loop not needed, mark as done to save CPU cycles - this->mark_loop_done(); + // Empty loop not needed, disable to save CPU cycles + this->disable_loop(); } void BedJetHub::update() { this->dispatch_status_(); } diff --git a/esphome/components/bedjet/climate/bedjet_climate.cpp b/esphome/components/bedjet/climate/bedjet_climate.cpp index 31880fe3ae..f22d312b5a 100644 --- a/esphome/components/bedjet/climate/bedjet_climate.cpp +++ b/esphome/components/bedjet/climate/bedjet_climate.cpp @@ -85,8 +85,8 @@ void BedJetClimate::reset_state_() { void BedJetClimate::loop() { // This component is controlled via the parent BedJetHub - // Empty loop not needed, mark as done to save CPU cycles - this->mark_loop_done(); + // Empty loop not needed, disable to save CPU cycles + this->disable_loop(); } void BedJetClimate::control(const ClimateCall &call) { diff --git a/esphome/components/ble_client/sensor/ble_rssi_sensor.cpp b/esphome/components/ble_client/sensor/ble_rssi_sensor.cpp index 8511437a4a..790d62f378 100644 --- a/esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +++ b/esphome/components/ble_client/sensor/ble_rssi_sensor.cpp @@ -13,8 +13,8 @@ static const char *const TAG = "ble_rssi_sensor"; void BLEClientRSSISensor::loop() { // This component uses polling via update() and BLE GAP callbacks - // Empty loop not needed, mark as done to save CPU cycles - this->mark_loop_done(); + // Empty loop not needed, disable to save CPU cycles + this->disable_loop(); } void BLEClientRSSISensor::dump_config() { diff --git a/esphome/components/ble_client/sensor/ble_sensor.cpp b/esphome/components/ble_client/sensor/ble_sensor.cpp index 4bf3154e04..08e9b9265c 100644 --- a/esphome/components/ble_client/sensor/ble_sensor.cpp +++ b/esphome/components/ble_client/sensor/ble_sensor.cpp @@ -13,8 +13,8 @@ static const char *const TAG = "ble_sensor"; void BLESensor::loop() { // This component uses polling via update() and BLE callbacks - // Empty loop not needed, mark as done to save CPU cycles - this->mark_loop_done(); + // Empty loop not needed, disable to save CPU cycles + this->disable_loop(); } void BLESensor::dump_config() { diff --git a/esphome/components/ble_client/text_sensor/ble_text_sensor.cpp b/esphome/components/ble_client/text_sensor/ble_text_sensor.cpp index 24b8ad486a..c71f7c76e6 100644 --- a/esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +++ b/esphome/components/ble_client/text_sensor/ble_text_sensor.cpp @@ -16,8 +16,8 @@ static const std::string EMPTY = ""; void BLETextSensor::loop() { // This component uses polling via update() and BLE callbacks - // Empty loop not needed, mark as done to save CPU cycles - this->mark_loop_done(); + // Empty loop not needed, disable to save CPU cycles + this->disable_loop(); } void BLETextSensor::dump_config() { diff --git a/esphome/components/captive_portal/captive_portal.cpp b/esphome/components/captive_portal/captive_portal.cpp index 31e6c51f0f..2c1ce17fb3 100644 --- a/esphome/components/captive_portal/captive_portal.cpp +++ b/esphome/components/captive_portal/captive_portal.cpp @@ -37,7 +37,12 @@ void CaptivePortal::handle_wifisave(AsyncWebServerRequest *request) { request->redirect("/?save"); } -void CaptivePortal::setup() {} +void CaptivePortal::setup() { +#ifndef USE_ARDUINO + // No DNS server needed for non-Arduino frameworks + this->disable_loop(); +#endif +} void CaptivePortal::start() { this->base_->init(); if (!this->initialized_) { @@ -50,6 +55,8 @@ void CaptivePortal::start() { this->dns_server_->setErrorReplyCode(DNSReplyCode::NoError); network::IPAddress ip = wifi::global_wifi_component->wifi_soft_ap_ip(); this->dns_server_->start(53, "*", ip); + // Re-enable loop() when DNS server is started + this->enable_loop(); #endif this->base_->get_server()->onNotFound([this](AsyncWebServerRequest *req) { diff --git a/esphome/components/captive_portal/captive_portal.h b/esphome/components/captive_portal/captive_portal.h index 24d1295e6a..026645ee29 100644 --- a/esphome/components/captive_portal/captive_portal.h +++ b/esphome/components/captive_portal/captive_portal.h @@ -23,6 +23,8 @@ class CaptivePortal : public AsyncWebHandler, public Component { void loop() override { if (this->dns_server_ != nullptr) this->dns_server_->processNextRequest(); + else + this->disable_loop(); } #endif float get_setup_priority() const override; diff --git a/esphome/components/esp32_ble_client/ble_client_base.cpp b/esphome/components/esp32_ble_client/ble_client_base.cpp index 4e61fb287c..8821c70ca3 100644 --- a/esphome/components/esp32_ble_client/ble_client_base.cpp +++ b/esphome/components/esp32_ble_client/ble_client_base.cpp @@ -23,6 +23,12 @@ void BLEClientBase::setup() { } void BLEClientBase::loop() { + // If address is 0, this connection is not in use + if (this->address_ == 0) { + this->disable_loop(); + return; + } + if (!esp32_ble::global_ble->is_active()) { this->set_state(espbt::ClientState::INIT); return; diff --git a/esphome/components/esp32_ble_client/ble_client_base.h b/esphome/components/esp32_ble_client/ble_client_base.h index 89ac04e38c..576c1cf526 100644 --- a/esphome/components/esp32_ble_client/ble_client_base.h +++ b/esphome/components/esp32_ble_client/ble_client_base.h @@ -62,6 +62,8 @@ class BLEClientBase : public espbt::ESPBTClient, public Component { (uint8_t) (this->address_ >> 32) & 0xff, (uint8_t) (this->address_ >> 24) & 0xff, (uint8_t) (this->address_ >> 16) & 0xff, (uint8_t) (this->address_ >> 8) & 0xff, (uint8_t) (this->address_ >> 0) & 0xff); + // Re-enable loop() when a new address is assigned + this->enable_loop(); } } std::string address_str() const { return this->address_str_; } diff --git a/esphome/components/esp32_improv/esp32_improv_component.cpp b/esphome/components/esp32_improv/esp32_improv_component.cpp index 57fc1b5797..ff150a3d69 100644 --- a/esphome/components/esp32_improv/esp32_improv_component.cpp +++ b/esphome/components/esp32_improv/esp32_improv_component.cpp @@ -169,7 +169,7 @@ void ESP32ImprovComponent::loop() { this->incoming_data_.clear(); this->set_status_indicator_state_(false); // Provisioning complete, no further loop execution needed - this->mark_loop_done(); + this->disable_loop(); break; } } diff --git a/esphome/components/online_image/online_image.cpp b/esphome/components/online_image/online_image.cpp index 8030bd0095..3f1d58fb45 100644 --- a/esphome/components/online_image/online_image.cpp +++ b/esphome/components/online_image/online_image.cpp @@ -178,18 +178,21 @@ void OnlineImage::update() { if (this->format_ == ImageFormat::BMP) { ESP_LOGD(TAG, "Allocating BMP decoder"); this->decoder_ = make_unique(this); + this->enable_loop(); } #endif // USE_ONLINE_IMAGE_BMP_SUPPORT #ifdef USE_ONLINE_IMAGE_JPEG_SUPPORT if (this->format_ == ImageFormat::JPEG) { ESP_LOGD(TAG, "Allocating JPEG decoder"); this->decoder_ = esphome::make_unique(this); + this->enable_loop(); } #endif // USE_ONLINE_IMAGE_JPEG_SUPPORT #ifdef USE_ONLINE_IMAGE_PNG_SUPPORT if (this->format_ == ImageFormat::PNG) { ESP_LOGD(TAG, "Allocating PNG decoder"); this->decoder_ = make_unique(this); + this->enable_loop(); } #endif // USE_ONLINE_IMAGE_PNG_SUPPORT @@ -212,6 +215,7 @@ void OnlineImage::update() { void OnlineImage::loop() { if (!this->decoder_) { // Not decoding at the moment => nothing to do. + this->disable_loop(); return; } if (!this->downloader_ || this->decoder_->is_finished()) { diff --git a/esphome/components/preferences/syncer.h b/esphome/components/preferences/syncer.h index 93a8cff371..b6b422d4ba 100644 --- a/esphome/components/preferences/syncer.h +++ b/esphome/components/preferences/syncer.h @@ -13,7 +13,7 @@ class IntervalSyncer : public Component { if (this->write_interval_ != 0) { set_interval(this->write_interval_, []() { global_preferences->sync(); }); // When using interval-based syncing, we don't need the loop - this->mark_loop_done(); + this->disable_loop(); } } void loop() override { diff --git a/esphome/components/rtttl/rtttl.cpp b/esphome/components/rtttl/rtttl.cpp index e24816fd83..2c4a0f917f 100644 --- a/esphome/components/rtttl/rtttl.cpp +++ b/esphome/components/rtttl/rtttl.cpp @@ -142,8 +142,10 @@ void Rtttl::stop() { } void Rtttl::loop() { - if (this->note_duration_ == 0 || this->state_ == State::STATE_STOPPED) + if (this->note_duration_ == 0 || this->state_ == State::STATE_STOPPED) { + this->disable_loop(); return; + } #ifdef USE_SPEAKER if (this->speaker_ != nullptr) { @@ -391,6 +393,11 @@ void Rtttl::set_state_(State state) { this->state_ = state; ESP_LOGV(TAG, "State changed from %s to %s", LOG_STR_ARG(state_to_string(old_state)), LOG_STR_ARG(state_to_string(state))); + + // Clear loop_done when transitioning from STOPPED to any other state + if (old_state == State::STATE_STOPPED && state != State::STATE_STOPPED) { + this->enable_loop(); + } } } // namespace rtttl diff --git a/esphome/components/safe_mode/safe_mode.cpp b/esphome/components/safe_mode/safe_mode.cpp index 88f34beafa..5a62604269 100644 --- a/esphome/components/safe_mode/safe_mode.cpp +++ b/esphome/components/safe_mode/safe_mode.cpp @@ -42,8 +42,8 @@ void SafeModeComponent::loop() { ESP_LOGI(TAG, "Boot seems successful; resetting boot loop counter"); this->clean_rtc(); this->boot_successful_ = true; - // Mark loop as done since we no longer need to check - this->mark_loop_done(); + // Disable loop since we no longer need to check + this->disable_loop(); } } diff --git a/esphome/components/sntp/sntp_component.cpp b/esphome/components/sntp/sntp_component.cpp index ab02720dd9..c7642d0637 100644 --- a/esphome/components/sntp/sntp_component.cpp +++ b/esphome/components/sntp/sntp_component.cpp @@ -71,7 +71,7 @@ void SNTPComponent::loop() { #ifdef USE_ESP_IDF // On ESP-IDF, time sync is permanent and update() doesn't force resync // Time is now synchronized, no need to check anymore - this->mark_loop_done(); + this->disable_loop(); #endif } diff --git a/esphome/components/tlc5971/tlc5971.cpp b/esphome/components/tlc5971/tlc5971.cpp index ebcc3af361..05ff0a0080 100644 --- a/esphome/components/tlc5971/tlc5971.cpp +++ b/esphome/components/tlc5971/tlc5971.cpp @@ -24,8 +24,10 @@ void TLC5971::dump_config() { } void TLC5971::loop() { - if (!this->update_) + if (!this->update_) { + this->disable_loop(); return; + } uint32_t command; @@ -93,6 +95,7 @@ void TLC5971::set_channel_value(uint16_t channel, uint16_t value) { return; if (this->pwm_amounts_[channel] != value) { this->update_ = true; + this->enable_loop(); } this->pwm_amounts_[channel] = value; } diff --git a/esphome/core/component.cpp b/esphome/core/component.cpp index 84fc86609c..7ee0486177 100644 --- a/esphome/core/component.cpp +++ b/esphome/core/component.cpp @@ -137,11 +137,18 @@ void Component::mark_failed() { this->component_state_ |= COMPONENT_STATE_FAILED; this->status_set_error(); } -void Component::mark_loop_done() { - ESP_LOGD(TAG, "Component %s loop marked as done.", this->get_component_source()); +void Component::disable_loop() { + ESP_LOGD(TAG, "Component %s loop disabled.", this->get_component_source()); this->component_state_ &= ~COMPONENT_STATE_MASK; this->component_state_ |= COMPONENT_STATE_LOOP_DONE; } +void Component::enable_loop() { + if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) { + ESP_LOGD(TAG, "Component %s loop enabled.", this->get_component_source()); + this->component_state_ &= ~COMPONENT_STATE_MASK; + this->component_state_ |= COMPONENT_STATE_LOOP; + } +} void Component::reset_to_construction_state() { if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_FAILED) { ESP_LOGI(TAG, "Component %s is being reset to construction state.", this->get_component_source()); diff --git a/esphome/core/component.h b/esphome/core/component.h index 123ec92814..8ce2e87049 100644 --- a/esphome/core/component.h +++ b/esphome/core/component.h @@ -151,12 +151,19 @@ class Component { this->mark_failed(); } - /** Mark this component's loop as done. The loop will no longer be called. + /** Disable this component's loop. The loop() method will no longer be called. * * This is useful for components that only need to run for a certain period of time - * and then no longer need their loop() method called, saving CPU cycles. + * or when inactive, saving CPU cycles. */ - void mark_loop_done(); + void disable_loop(); + + /** Enable this component's loop. The loop() method will be called normally. + * + * This is useful for components that transition between active and inactive states + * and need to re-enable their loop() method when becoming active again. + */ + void enable_loop(); bool is_failed() const;