mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-27 13:13:50 +00:00 
			
		
		
		
	mark_loop_done
This commit is contained in:
		| @@ -17,7 +17,11 @@ void Anova::setup() { | ||||
|   this->current_request_ = 0; | ||||
| } | ||||
|  | ||||
| void Anova::loop() {} | ||||
| 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(); | ||||
| } | ||||
|  | ||||
| void Anova::control(const ClimateCall &call) { | ||||
|   if (call.get_mode().has_value()) { | ||||
|   | ||||
| @@ -480,7 +480,11 @@ void BedJetHub::set_clock(uint8_t hour, uint8_t minute) { | ||||
|  | ||||
| /* Internal */ | ||||
|  | ||||
| void BedJetHub::loop() {} | ||||
| 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(); | ||||
| } | ||||
| void BedJetHub::update() { this->dispatch_status_(); } | ||||
|  | ||||
| void BedJetHub::dump_config() { | ||||
|   | ||||
| @@ -83,7 +83,11 @@ void BedJetClimate::reset_state_() { | ||||
|   this->publish_state(); | ||||
| } | ||||
|  | ||||
| void BedJetClimate::loop() {} | ||||
| 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(); | ||||
| } | ||||
|  | ||||
| void BedJetClimate::control(const ClimateCall &call) { | ||||
|   ESP_LOGD(TAG, "Received BedJetClimate::control"); | ||||
|   | ||||
| @@ -11,7 +11,11 @@ namespace ble_client { | ||||
|  | ||||
| static const char *const TAG = "ble_rssi_sensor"; | ||||
|  | ||||
| void BLEClientRSSISensor::loop() {} | ||||
| 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(); | ||||
| } | ||||
|  | ||||
| void BLEClientRSSISensor::dump_config() { | ||||
|   LOG_SENSOR("", "BLE Client RSSI Sensor", this); | ||||
|   | ||||
| @@ -11,7 +11,11 @@ namespace ble_client { | ||||
|  | ||||
| static const char *const TAG = "ble_sensor"; | ||||
|  | ||||
| void BLESensor::loop() {} | ||||
| 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(); | ||||
| } | ||||
|  | ||||
| void BLESensor::dump_config() { | ||||
|   LOG_SENSOR("", "BLE Sensor", this); | ||||
|   | ||||
| @@ -14,7 +14,11 @@ static const char *const TAG = "ble_text_sensor"; | ||||
|  | ||||
| static const std::string EMPTY = ""; | ||||
|  | ||||
| void BLETextSensor::loop() {} | ||||
| 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(); | ||||
| } | ||||
|  | ||||
| void BLETextSensor::dump_config() { | ||||
|   LOG_TEXT_SENSOR("", "BLE Text Sensor", this); | ||||
|   | ||||
| @@ -168,6 +168,8 @@ void ESP32ImprovComponent::loop() { | ||||
|     case improv::STATE_PROVISIONED: { | ||||
|       this->incoming_data_.clear(); | ||||
|       this->set_status_indicator_state_(false); | ||||
|       // Provisioning complete, no further loop execution needed | ||||
|       this->mark_loop_done(); | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -42,6 +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(); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -67,6 +67,9 @@ void SNTPComponent::loop() { | ||||
|            time.minute, time.second); | ||||
|   this->time_sync_callback_.call(); | ||||
|   this->has_time_ = true; | ||||
|  | ||||
|   // Time is now synchronized, no need to check anymore | ||||
|   this->mark_loop_done(); | ||||
| } | ||||
|  | ||||
| }  // namespace sntp | ||||
|   | ||||
| @@ -29,17 +29,18 @@ const float LATE = -100.0f; | ||||
|  | ||||
| }  // namespace setup_priority | ||||
|  | ||||
| // Component state uses bits 0-1 (4 states) | ||||
| const uint8_t COMPONENT_STATE_MASK = 0x03; | ||||
| // Component state uses bits 0-2 (8 states, 5 used) | ||||
| const uint8_t COMPONENT_STATE_MASK = 0x07; | ||||
| const uint8_t COMPONENT_STATE_CONSTRUCTION = 0x00; | ||||
| const uint8_t COMPONENT_STATE_SETUP = 0x01; | ||||
| const uint8_t COMPONENT_STATE_LOOP = 0x02; | ||||
| const uint8_t COMPONENT_STATE_FAILED = 0x03; | ||||
| // Status LED uses bits 2-3 | ||||
| const uint8_t STATUS_LED_MASK = 0x0C; | ||||
| const uint8_t COMPONENT_STATE_LOOP_DONE = 0x04; | ||||
| // Status LED uses bits 3-4 | ||||
| const uint8_t STATUS_LED_MASK = 0x18; | ||||
| const uint8_t STATUS_LED_OK = 0x00; | ||||
| const uint8_t STATUS_LED_WARNING = 0x04;  // Bit 2 | ||||
| const uint8_t STATUS_LED_ERROR = 0x08;    // Bit 3 | ||||
| const uint8_t STATUS_LED_WARNING = 0x08;  // Bit 3 | ||||
| const uint8_t STATUS_LED_ERROR = 0x10;    // Bit 4 | ||||
|  | ||||
| const uint32_t WARN_IF_BLOCKING_OVER_MS = 50U;       ///< Initial blocking time allowed without warning | ||||
| const uint32_t WARN_IF_BLOCKING_INCREMENT_MS = 10U;  ///< How long the blocking time must be larger to warn again | ||||
| @@ -111,6 +112,9 @@ void Component::call() { | ||||
|     case COMPONENT_STATE_FAILED:  // NOLINT(bugprone-branch-clone) | ||||
|       // State failed: Do nothing | ||||
|       break; | ||||
|     case COMPONENT_STATE_LOOP_DONE:  // NOLINT(bugprone-branch-clone) | ||||
|       // State loop done: Do nothing, component has finished its work | ||||
|       break; | ||||
|     default: | ||||
|       break; | ||||
|   } | ||||
| @@ -133,6 +137,11 @@ 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()); | ||||
|   this->component_state_ &= ~COMPONENT_STATE_MASK; | ||||
|   this->component_state_ |= COMPONENT_STATE_LOOP_DONE; | ||||
| } | ||||
| 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()); | ||||
| @@ -169,6 +178,10 @@ bool Component::is_ready() const { | ||||
|   return (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP || | ||||
|          (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_SETUP; | ||||
| } | ||||
| bool Component::should_skip_loop() const { | ||||
|   uint8_t state = this->component_state_ & COMPONENT_STATE_MASK; | ||||
|   return state == COMPONENT_STATE_FAILED || state == COMPONENT_STATE_LOOP_DONE; | ||||
| } | ||||
| bool Component::can_proceed() { return true; } | ||||
| bool Component::status_has_warning() const { return this->component_state_ & STATUS_LED_WARNING; } | ||||
| bool Component::status_has_error() const { return this->component_state_ & STATUS_LED_ERROR; } | ||||
|   | ||||
| @@ -58,6 +58,7 @@ extern const uint8_t COMPONENT_STATE_CONSTRUCTION; | ||||
| extern const uint8_t COMPONENT_STATE_SETUP; | ||||
| extern const uint8_t COMPONENT_STATE_LOOP; | ||||
| extern const uint8_t COMPONENT_STATE_FAILED; | ||||
| extern const uint8_t COMPONENT_STATE_LOOP_DONE; | ||||
| extern const uint8_t STATUS_LED_MASK; | ||||
| extern const uint8_t STATUS_LED_OK; | ||||
| extern const uint8_t STATUS_LED_WARNING; | ||||
| @@ -150,10 +151,23 @@ class Component { | ||||
|     this->mark_failed(); | ||||
|   } | ||||
|  | ||||
|   /** Mark this component's loop as done. The loop 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. | ||||
|    */ | ||||
|   void mark_loop_done(); | ||||
|  | ||||
|   bool is_failed() const; | ||||
|  | ||||
|   bool is_ready() const; | ||||
|  | ||||
|   /** Check if this component should skip its loop execution. | ||||
|    * | ||||
|    * @return True if the component is in FAILED or LOOP_DONE state | ||||
|    */ | ||||
|   bool should_skip_loop() const; | ||||
|  | ||||
|   virtual bool can_proceed(); | ||||
|  | ||||
|   bool status_has_warning() const; | ||||
|   | ||||
| @@ -211,8 +211,8 @@ void HOT Scheduler::call() { | ||||
|         // Not reached timeout yet, done for this call | ||||
|         break; | ||||
|       } | ||||
|       // Don't run on failed components | ||||
|       if (item->component != nullptr && item->component->is_failed()) { | ||||
|       // Don't run on failed or loop-done components | ||||
|       if (item->component != nullptr && item->component->should_skip_loop()) { | ||||
|         LockGuard guard{this->lock_}; | ||||
|         this->pop_raw_(); | ||||
|         continue; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user