mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Reduce number of calls to fetch time in the main loop (#8804)
This commit is contained in:
		
				
					committed by
					
						 Jesse Hills
						Jesse Hills
					
				
			
			
				
	
			
			
			
						parent
						
							316fe2f06c
						
					
				
				
					commit
					15d0b4355e
				
			| @@ -8,6 +8,7 @@ | |||||||
| #include "esphome/core/hal.h" | #include "esphome/core/hal.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/version.h" | #include "esphome/core/version.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| #ifdef USE_DEEP_SLEEP | #ifdef USE_DEEP_SLEEP | ||||||
| #include "esphome/components/deep_sleep/deep_sleep_component.h" | #include "esphome/components/deep_sleep/deep_sleep_component.h" | ||||||
| @@ -146,7 +147,7 @@ void APIConnection::loop() { | |||||||
|     } |     } | ||||||
|     return; |     return; | ||||||
|   } else { |   } else { | ||||||
|     this->last_traffic_ = millis(); |     this->last_traffic_ = App.get_loop_component_start_time(); | ||||||
|     // read a packet |     // read a packet | ||||||
|     this->read_message(buffer.data_len, buffer.type, &buffer.container[buffer.data_offset]); |     this->read_message(buffer.data_len, buffer.type, &buffer.container[buffer.data_offset]); | ||||||
|     if (this->remove_) |     if (this->remove_) | ||||||
| @@ -163,7 +164,7 @@ void APIConnection::loop() { | |||||||
|   static uint32_t keepalive = 60000; |   static uint32_t keepalive = 60000; | ||||||
|   static uint8_t max_ping_retries = 60; |   static uint8_t max_ping_retries = 60; | ||||||
|   static uint16_t ping_retry_interval = 1000; |   static uint16_t ping_retry_interval = 1000; | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (this->sent_ping_) { |   if (this->sent_ping_) { | ||||||
|     // Disconnect if not responded within 2.5*keepalive |     // Disconnect if not responded within 2.5*keepalive | ||||||
|     if (now - this->last_traffic_ > (keepalive * 5) / 2) { |     if (now - this->last_traffic_ > (keepalive * 5) / 2) { | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| #include "bedjet_hub.h" | #include "bedjet_hub.h" | ||||||
| #include "bedjet_child.h" | #include "bedjet_child.h" | ||||||
| #include "bedjet_const.h" | #include "bedjet_const.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
| #include <cinttypes> | #include <cinttypes> | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/macros.h" | #include "esphome/core/macros.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| #ifdef USE_ESP32 | #ifdef USE_ESP32 | ||||||
|  |  | ||||||
| @@ -177,7 +178,7 @@ void BluetoothProxy::loop() { | |||||||
|   // Flush any pending BLE advertisements that have been accumulated but not yet sent |   // Flush any pending BLE advertisements that have been accumulated but not yet sent | ||||||
|   if (this->raw_advertisements_) { |   if (this->raw_advertisements_) { | ||||||
|     static uint32_t last_flush_time = 0; |     static uint32_t last_flush_time = 0; | ||||||
|     uint32_t now = millis(); |     uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|     // Flush accumulated advertisements every 100ms |     // Flush accumulated advertisements every 100ms | ||||||
|     if (now - last_flush_time >= 100) { |     if (now - last_flush_time >= 100) { | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "cse7766.h" | #include "cse7766.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace cse7766 { | namespace cse7766 { | ||||||
| @@ -7,7 +8,7 @@ namespace cse7766 { | |||||||
| static const char *const TAG = "cse7766"; | static const char *const TAG = "cse7766"; | ||||||
|  |  | ||||||
| void CSE7766Component::loop() { | void CSE7766Component::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (now - this->last_transmission_ >= 500) { |   if (now - this->last_transmission_ >= 500) { | ||||||
|     // last transmission too long ago. Reset RX index. |     // last transmission too long ago. Reset RX index. | ||||||
|     this->raw_data_index_ = 0; |     this->raw_data_index_ = 0; | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #include "current_based_cover.h" | #include "current_based_cover.h" | ||||||
| #include "esphome/core/hal.h" | #include "esphome/core/hal.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
| #include <cfloat> | #include <cfloat> | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| @@ -60,7 +61,7 @@ void CurrentBasedCover::loop() { | |||||||
|   if (this->current_operation == COVER_OPERATION_IDLE) |   if (this->current_operation == COVER_OPERATION_IDLE) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   if (this->current_operation == COVER_OPERATION_OPENING) { |   if (this->current_operation == COVER_OPERATION_OPENING) { | ||||||
|     if (this->malfunction_detection_ && this->is_closing_()) {  // Malfunction |     if (this->malfunction_detection_ && this->is_closing_()) {  // Malfunction | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #include "daly_bms.h" | #include "daly_bms.h" | ||||||
| #include <vector> | #include <vector> | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace daly_bms { | namespace daly_bms { | ||||||
| @@ -32,7 +33,7 @@ void DalyBmsComponent::update() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void DalyBmsComponent::loop() { | void DalyBmsComponent::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (this->receiving_ && (now - this->last_transmission_ >= 200)) { |   if (this->receiving_ && (now - this->last_transmission_ >= 200)) { | ||||||
|     // last transmission too long ago. Reset RX index. |     // last transmission too long ago. Reset RX index. | ||||||
|     ESP_LOGW(TAG, "Last transmission too long ago. Reset RX index."); |     ESP_LOGW(TAG, "Last transmission too long ago. Reset RX index."); | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ void DebugComponent::loop() { | |||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
|   // calculate loop time - from last call to this one |   // calculate loop time - from last call to this one | ||||||
|   if (this->loop_time_sensor_ != nullptr) { |   if (this->loop_time_sensor_ != nullptr) { | ||||||
|     uint32_t now = millis(); |     uint32_t now = App.get_loop_component_start_time(); | ||||||
|     uint32_t loop_time = now - this->last_loop_timetag_; |     uint32_t loop_time = now - this->last_loop_timetag_; | ||||||
|     this->max_loop_time_ = std::max(this->max_loop_time_, loop_time); |     this->max_loop_time_ = std::max(this->max_loop_time_, loop_time); | ||||||
|     this->last_loop_timetag_ = now; |     this->last_loop_timetag_ = now; | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #include "endstop_cover.h" | #include "endstop_cover.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/hal.h" | #include "esphome/core/hal.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace endstop { | namespace endstop { | ||||||
| @@ -65,7 +66,7 @@ void EndstopCover::loop() { | |||||||
|   if (this->current_operation == COVER_OPERATION_IDLE) |   if (this->current_operation == COVER_OPERATION_IDLE) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   if (this->current_operation == COVER_OPERATION_OPENING && this->is_open_()) { |   if (this->current_operation == COVER_OPERATION_OPENING && this->is_open_()) { | ||||||
|     float dur = (now - this->start_dir_time_) / 1e3f; |     float dur = (now - this->start_dir_time_) / 1e3f; | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
| #include <cstring> | #include <cstring> | ||||||
| #include "ble_uuid.h" | #include "ble_uuid.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace esp32_ble { | namespace esp32_ble { | ||||||
| @@ -143,7 +144,7 @@ void BLEAdvertising::loop() { | |||||||
|   if (this->raw_advertisements_callbacks_.empty()) { |   if (this->raw_advertisements_callbacks_.empty()) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (now - this->last_advertisement_time_ > this->advertising_cycle_time_) { |   if (now - this->last_advertisement_time_ > this->advertising_cycle_time_) { | ||||||
|     this->stop(); |     this->stop(); | ||||||
|     this->current_adv_index_ += 1; |     this->current_adv_index_ += 1; | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| #include "esp32_camera.h" | #include "esp32_camera.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/hal.h" | #include "esphome/core/hal.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| #include <freertos/task.h> | #include <freertos/task.h> | ||||||
|  |  | ||||||
| @@ -162,7 +163,7 @@ void ESP32Camera::loop() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // request idle image every idle_update_interval |   // request idle image every idle_update_interval | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (this->idle_update_interval_ != 0 && now - this->last_idle_request_ > this->idle_update_interval_) { |   if (this->idle_update_interval_ != 0 && now - this->last_idle_request_ > this->idle_update_interval_) { | ||||||
|     this->last_idle_request_ = now; |     this->last_idle_request_ = now; | ||||||
|     this->request_image(IDLE); |     this->request_image(IDLE); | ||||||
|   | |||||||
| @@ -92,7 +92,7 @@ void ESP32ImprovComponent::loop() { | |||||||
|  |  | ||||||
|   if (!this->incoming_data_.empty()) |   if (!this->incoming_data_.empty()) | ||||||
|     this->process_incoming_data_(); |     this->process_incoming_data_(); | ||||||
|   uint32_t now = millis(); |   uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   switch (this->state_) { |   switch (this->state_) { | ||||||
|     case improv::STATE_STOPPED: |     case improv::STATE_STOPPED: | ||||||
|   | |||||||
| @@ -288,7 +288,7 @@ uint32_t ESP32TouchComponent::component_touch_pad_read(touch_pad_t tp) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void ESP32TouchComponent::loop() { | void ESP32TouchComponent::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   bool should_print = this->setup_mode_ && now - this->setup_mode_last_log_print_ > 250; |   bool should_print = this->setup_mode_ && now - this->setup_mode_last_log_print_ > 250; | ||||||
|   for (auto *child : this->children_) { |   for (auto *child : this->children_) { | ||||||
|     child->value_ = this->component_touch_pad_read(child->get_touch_pad()); |     child->value_ = this->component_touch_pad_read(child->get_touch_pad()); | ||||||
|   | |||||||
| @@ -240,7 +240,7 @@ void EthernetComponent::setup() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void EthernetComponent::loop() { | void EthernetComponent::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   switch (this->state_) { |   switch (this->state_) { | ||||||
|     case EthernetComponentState::STOPPED: |     case EthernetComponentState::STOPPED: | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #include "feedback_cover.h" | #include "feedback_cover.h" | ||||||
| #include "esphome/core/hal.h" | #include "esphome/core/hal.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace feedback { | namespace feedback { | ||||||
| @@ -220,7 +221,7 @@ void FeedbackCover::set_open_obstacle_sensor(binary_sensor::BinarySensor *open_o | |||||||
| void FeedbackCover::loop() { | void FeedbackCover::loop() { | ||||||
|   if (this->current_operation == COVER_OPERATION_IDLE) |   if (this->current_operation == COVER_OPERATION_IDLE) | ||||||
|     return; |     return; | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   // Recompute position every loop cycle |   // Recompute position every loop cycle | ||||||
|   this->recompute_position_(); |   this->recompute_position_(); | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
|  */ |  */ | ||||||
| #include "gcja5.h" | #include "gcja5.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
| #include <cstring> | #include <cstring> | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| @@ -16,7 +17,7 @@ static const char *const TAG = "gcja5"; | |||||||
| void GCJA5Component::setup() { ESP_LOGCONFIG(TAG, "Setting up gcja5..."); } | void GCJA5Component::setup() { ESP_LOGCONFIG(TAG, "Setting up gcja5..."); } | ||||||
|  |  | ||||||
| void GCJA5Component::loop() { | void GCJA5Component::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (now - this->last_transmission_ >= 500) { |   if (now - this->last_transmission_ >= 500) { | ||||||
|     // last transmission too long ago. Reset RX index. |     // last transmission too long ago. Reset RX index. | ||||||
|     this->rx_message_.clear(); |     this->rx_message_.clear(); | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "growatt_solar.h" | #include "growatt_solar.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace growatt_solar { | namespace growatt_solar { | ||||||
| @@ -18,7 +19,7 @@ void GrowattSolar::loop() { | |||||||
|  |  | ||||||
| void GrowattSolar::update() { | void GrowattSolar::update() { | ||||||
|   // If our last send has had no reply yet, and it wasn't that long ago, do nothing. |   // If our last send has had no reply yet, and it wasn't that long ago, do nothing. | ||||||
|   uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (now - this->last_send_ < this->get_update_interval() / 2) { |   if (now - this->last_send_ < this->get_update_interval() / 2) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "kuntze.h" | #include "kuntze.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace kuntze { | namespace kuntze { | ||||||
| @@ -60,7 +61,7 @@ void Kuntze::on_modbus_data(const std::vector<uint8_t> &data) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void Kuntze::loop() { | void Kuntze::loop() { | ||||||
|   uint32_t now = millis(); |   uint32_t now = App.get_loop_component_start_time(); | ||||||
|   // timeout after 15 seconds |   // timeout after 15 seconds | ||||||
|   if (this->waiting_ && (now - this->last_send_ > 15000)) { |   if (this->waiting_ && (now - this->last_send_ > 15000)) { | ||||||
|     ESP_LOGW(TAG, "timed out waiting for response"); |     ESP_LOGW(TAG, "timed out waiting for response"); | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "matrix_keypad.h" | #include "matrix_keypad.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace matrix_keypad { | namespace matrix_keypad { | ||||||
| @@ -28,7 +29,7 @@ void MatrixKeypad::setup() { | |||||||
| void MatrixKeypad::loop() { | void MatrixKeypad::loop() { | ||||||
|   static uint32_t active_start = 0; |   static uint32_t active_start = 0; | ||||||
|   static int active_key = -1; |   static int active_key = -1; | ||||||
|   uint32_t now = millis(); |   uint32_t now = App.get_loop_component_start_time(); | ||||||
|   int key = -1; |   int key = -1; | ||||||
|   bool error = false; |   bool error = false; | ||||||
|   int pos = 0, row, col; |   int pos = 0, row, col; | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/helpers.h" | #include "esphome/core/helpers.h" | ||||||
| #include "esphome/core/hal.h" | #include "esphome/core/hal.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
| #include "max7219font.h" | #include "max7219font.h" | ||||||
|  |  | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| @@ -63,7 +64,7 @@ void MAX7219Component::dump_config() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void MAX7219Component::loop() { | void MAX7219Component::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   const uint32_t millis_since_last_scroll = now - this->last_scroll_; |   const uint32_t millis_since_last_scroll = now - this->last_scroll_; | ||||||
|   const size_t first_line_size = this->max_displaybuffer_[0].size(); |   const size_t first_line_size = this->max_displaybuffer_[0].size(); | ||||||
|   // check if the buffer has shrunk past the current position since last update |   // check if the buffer has shrunk past the current position since last update | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #include "modbus.h" | #include "modbus.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/helpers.h" | #include "esphome/core/helpers.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace modbus { | namespace modbus { | ||||||
| @@ -13,7 +14,7 @@ void Modbus::setup() { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| void Modbus::loop() { | void Modbus::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   while (this->available()) { |   while (this->available()) { | ||||||
|     uint8_t byte; |     uint8_t byte; | ||||||
|   | |||||||
| @@ -345,7 +345,7 @@ void MQTTClientComponent::loop() { | |||||||
|     this->disconnect_reason_.reset(); |     this->disconnect_reason_.reset(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   switch (this->state_) { |   switch (this->state_) { | ||||||
|     case MQTT_CLIENT_DISABLED: |     case MQTT_CLIENT_DISABLED: | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "pmsx003.h" | #include "pmsx003.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace pmsx003 { | namespace pmsx003 { | ||||||
| @@ -42,7 +43,7 @@ void PMSX003Component::dump_config() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void PMSX003Component::loop() { | void PMSX003Component::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   // If we update less often than it takes the device to stabilise, spin the fan down |   // If we update less often than it takes the device to stabilise, spin the fan down | ||||||
|   // rather than running it constantly. It does take some time to stabilise, so we |   // rather than running it constantly. It does take some time to stabilise, so we | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "pzem004t.h" | #include "pzem004t.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
| #include <cinttypes> | #include <cinttypes> | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| @@ -16,7 +17,7 @@ void PZEM004T::setup() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void PZEM004T::loop() { | void PZEM004T::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (now - this->last_read_ > 500 && this->available() < 7) { |   if (now - this->last_read_ > 500 && this->available() < 7) { | ||||||
|     while (this->available()) |     while (this->available()) | ||||||
|       this->read(); |       this->read(); | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "rf_bridge.h" | #include "rf_bridge.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
| #include <cinttypes> | #include <cinttypes> | ||||||
| #include <cstring> | #include <cstring> | ||||||
|  |  | ||||||
| @@ -128,7 +129,7 @@ void RFBridgeComponent::write_byte_str_(const std::string &codes) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void RFBridgeComponent::loop() { | void RFBridgeComponent::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if (now - this->last_bridge_byte_ > 50) { |   if (now - this->last_bridge_byte_ > 50) { | ||||||
|     this->rx_buffer_.clear(); |     this->rx_buffer_.clear(); | ||||||
|     this->last_bridge_byte_ = now; |     this->last_bridge_byte_ = now; | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "sds011.h" | #include "sds011.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace sds011 { | namespace sds011 { | ||||||
| @@ -75,7 +76,7 @@ void SDS011Component::dump_config() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void SDS011Component::loop() { | void SDS011Component::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|   if ((now - this->last_transmission_ >= 500) && this->data_index_) { |   if ((now - this->last_transmission_ >= 500) && this->data_index_) { | ||||||
|     // last transmission too long ago. Reset RX index. |     // last transmission too long ago. Reset RX index. | ||||||
|     ESP_LOGV(TAG, "Last transmission too long ago. Reset RX index."); |     ESP_LOGV(TAG, "Last transmission too long ago. Reset RX index."); | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "slow_pwm_output.h" | #include "slow_pwm_output.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace slow_pwm { | namespace slow_pwm { | ||||||
| @@ -39,7 +40,7 @@ void SlowPWMOutput::set_output_state_(bool new_state) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void SlowPWMOutput::loop() { | void SlowPWMOutput::loop() { | ||||||
|   uint32_t now = millis(); |   uint32_t now = App.get_loop_component_start_time(); | ||||||
|   float scaled_state = this->state_ * this->period_; |   float scaled_state = this->state_ * this->period_; | ||||||
|  |  | ||||||
|   if (now - this->period_start_time_ >= this->period_) { |   if (now - this->period_start_time_ >= this->period_) { | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ SprinklerSwitch::SprinklerSwitch(switch_::Switch *off_switch, switch_::Switch *o | |||||||
| bool SprinklerSwitch::is_latching_valve() { return (this->off_switch_ != nullptr) && (this->on_switch_ != nullptr); } | bool SprinklerSwitch::is_latching_valve() { return (this->off_switch_ != nullptr) && (this->on_switch_ != nullptr); } | ||||||
|  |  | ||||||
| void SprinklerSwitch::loop() { | void SprinklerSwitch::loop() { | ||||||
|   if ((this->pinned_millis_) && (millis() > this->pinned_millis_ + this->pulse_duration_)) { |   if ((this->pinned_millis_) && (App.get_loop_component_start_time() > this->pinned_millis_ + this->pulse_duration_)) { | ||||||
|     this->pinned_millis_ = 0;  // reset tracker |     this->pinned_millis_ = 0;  // reset tracker | ||||||
|     if (this->off_switch_->state) { |     if (this->off_switch_->state) { | ||||||
|       this->off_switch_->turn_off(); |       this->off_switch_->turn_off(); | ||||||
| @@ -148,22 +148,23 @@ SprinklerValveOperator::SprinklerValveOperator(SprinklerValve *valve, Sprinkler | |||||||
|     : controller_(controller), valve_(valve) {} |     : controller_(controller), valve_(valve) {} | ||||||
|  |  | ||||||
| void SprinklerValveOperator::loop() { | void SprinklerValveOperator::loop() { | ||||||
|   if (millis() >= this->start_millis_) {  // dummy check |   uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |   if (now >= this->start_millis_) {  // dummy check | ||||||
|     switch (this->state_) { |     switch (this->state_) { | ||||||
|       case STARTING: |       case STARTING: | ||||||
|         if (millis() > (this->start_millis_ + this->start_delay_)) { |         if (now > (this->start_millis_ + this->start_delay_)) { | ||||||
|           this->run_();  // start_delay_ has been exceeded, so ensure both valves are on and update the state |           this->run_();  // start_delay_ has been exceeded, so ensure both valves are on and update the state | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|       case ACTIVE: |       case ACTIVE: | ||||||
|         if (millis() > (this->start_millis_ + this->start_delay_ + this->run_duration_)) { |         if (now > (this->start_millis_ + this->start_delay_ + this->run_duration_)) { | ||||||
|           this->stop();  // start_delay_ + run_duration_ has been exceeded, start shutting down |           this->stop();  // start_delay_ + run_duration_ has been exceeded, start shutting down | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|       case STOPPING: |       case STOPPING: | ||||||
|         if (millis() > (this->stop_millis_ + this->stop_delay_)) { |         if (now > (this->stop_millis_ + this->stop_delay_)) { | ||||||
|           this->kill_();  // stop_delay_has been exceeded, ensure all valves are off |           this->kill_();  // stop_delay_has been exceeded, ensure all valves are off | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #include "time_based_cover.h" | #include "time_based_cover.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/hal.h" | #include "esphome/core/hal.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace time_based { | namespace time_based { | ||||||
| @@ -26,7 +27,7 @@ void TimeBasedCover::loop() { | |||||||
|   if (this->current_operation == COVER_OPERATION_IDLE) |   if (this->current_operation == COVER_OPERATION_IDLE) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   // Recompute position every loop cycle |   // Recompute position every loop cycle | ||||||
|   this->recompute_position_(); |   this->recompute_position_(); | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "uart_switch.h" | #include "uart_switch.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace uart { | namespace uart { | ||||||
| @@ -8,7 +9,7 @@ static const char *const TAG = "uart.switch"; | |||||||
|  |  | ||||||
| void UARTSwitch::loop() { | void UARTSwitch::loop() { | ||||||
|   if (this->send_every_) { |   if (this->send_every_) { | ||||||
|     const uint32_t now = millis(); |     const uint32_t now = App.get_loop_component_start_time(); | ||||||
|     if (now - this->last_transmission_ > this->send_every_) { |     if (now - this->last_transmission_ > this->send_every_) { | ||||||
|       this->write_command_(this->state); |       this->write_command_(this->state); | ||||||
|       this->last_transmission_ = now; |       this->last_transmission_ = now; | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #include "uponor_smatrix_climate.h" | #include "uponor_smatrix_climate.h" | ||||||
| #include "esphome/core/helpers.h" | #include "esphome/core/helpers.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace uponor_smatrix { | namespace uponor_smatrix { | ||||||
| @@ -13,7 +14,7 @@ void UponorSmatrixClimate::dump_config() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void UponorSmatrixClimate::loop() { | void UponorSmatrixClimate::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   // Publish state after all update packets are processed |   // Publish state after all update packets are processed | ||||||
|   if (this->last_data_ != 0 && (now - this->last_data_ > 100) && this->target_temperature_raw_ != 0) { |   if (this->last_data_ != 0 && (now - this->last_data_ > 100) && this->target_temperature_raw_ != 0) { | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "uponor_smatrix.h" | #include "uponor_smatrix.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace uponor_smatrix { | namespace uponor_smatrix { | ||||||
| @@ -35,7 +36,7 @@ void UponorSmatrixComponent::dump_config() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void UponorSmatrixComponent::loop() { | void UponorSmatrixComponent::loop() { | ||||||
|   const uint32_t now = millis(); |   const uint32_t now = App.get_loop_component_start_time(); | ||||||
|  |  | ||||||
|   // Discard stale data |   // Discard stale data | ||||||
|   if (!this->rx_buffer_.empty() && (now - this->last_rx_ > 50)) { |   if (!this->rx_buffer_.empty() && (now - this->last_rx_ > 50)) { | ||||||
|   | |||||||
| @@ -67,22 +67,32 @@ void Application::loop() { | |||||||
|   uint32_t new_app_state = 0; |   uint32_t new_app_state = 0; | ||||||
|  |  | ||||||
|   this->scheduler.call(); |   this->scheduler.call(); | ||||||
|   this->feed_wdt(); |  | ||||||
|  |   // Get the initial loop time at the start | ||||||
|  |   uint32_t last_op_end_time = millis(); | ||||||
|  |  | ||||||
|  |   // Feed WDT with time | ||||||
|  |   this->feed_wdt(last_op_end_time); | ||||||
|  |  | ||||||
|   for (Component *component : this->looping_components_) { |   for (Component *component : this->looping_components_) { | ||||||
|  |     // Update the cached time before each component runs | ||||||
|  |     this->loop_component_start_time_ = last_op_end_time; | ||||||
|  |  | ||||||
|     { |     { | ||||||
|       this->set_current_component(component); |       this->set_current_component(component); | ||||||
|       WarnIfComponentBlockingGuard guard{component}; |       WarnIfComponentBlockingGuard guard{component, last_op_end_time}; | ||||||
|       component->call(); |       component->call(); | ||||||
|  |       // Use the finish method to get the current time as the end time | ||||||
|  |       last_op_end_time = guard.finish(); | ||||||
|     } |     } | ||||||
|     new_app_state |= component->get_component_state(); |     new_app_state |= component->get_component_state(); | ||||||
|     this->app_state_ |= new_app_state; |     this->app_state_ |= new_app_state; | ||||||
|     this->feed_wdt(); |     this->feed_wdt(last_op_end_time); | ||||||
|   } |   } | ||||||
|   this->app_state_ = new_app_state; |   this->app_state_ = new_app_state; | ||||||
|  |  | ||||||
|   const uint32_t now = millis(); |   // Use the last component's end time instead of calling millis() again | ||||||
|  |   auto elapsed = last_op_end_time - this->last_loop_; | ||||||
|   auto elapsed = now - this->last_loop_; |  | ||||||
|   if (elapsed >= this->loop_interval_ || HighFrequencyLoopRequester::is_high_frequency()) { |   if (elapsed >= this->loop_interval_ || HighFrequencyLoopRequester::is_high_frequency()) { | ||||||
|     yield(); |     yield(); | ||||||
|   } else { |   } else { | ||||||
| @@ -94,7 +104,7 @@ void Application::loop() { | |||||||
|     delay_time = std::min(next_schedule, delay_time); |     delay_time = std::min(next_schedule, delay_time); | ||||||
|     delay(delay_time); |     delay(delay_time); | ||||||
|   } |   } | ||||||
|   this->last_loop_ = now; |   this->last_loop_ = last_op_end_time; | ||||||
|  |  | ||||||
|   if (this->dump_config_at_ < this->components_.size()) { |   if (this->dump_config_at_ < this->components_.size()) { | ||||||
|     if (this->dump_config_at_ == 0) { |     if (this->dump_config_at_ == 0) { | ||||||
| @@ -109,10 +119,12 @@ void Application::loop() { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void IRAM_ATTR HOT Application::feed_wdt() { | void IRAM_ATTR HOT Application::feed_wdt(uint32_t time) { | ||||||
|   static uint32_t last_feed = 0; |   static uint32_t last_feed = 0; | ||||||
|   uint32_t now = micros(); |   // Use provided time if available, otherwise get current time | ||||||
|   if (now - last_feed > 3000) { |   uint32_t now = time ? time : millis(); | ||||||
|  |   // Compare in milliseconds (3ms threshold) | ||||||
|  |   if (now - last_feed > 3) { | ||||||
|     arch_feed_wdt(); |     arch_feed_wdt(); | ||||||
|     last_feed = now; |     last_feed = now; | ||||||
| #ifdef USE_STATUS_LED | #ifdef USE_STATUS_LED | ||||||
|   | |||||||
| @@ -217,6 +217,9 @@ class Application { | |||||||
|  |  | ||||||
|   std::string get_compilation_time() const { return this->compilation_time_; } |   std::string get_compilation_time() const { return this->compilation_time_; } | ||||||
|  |  | ||||||
|  |   /// Get the cached time in milliseconds from when the current component started its loop execution | ||||||
|  |   inline uint32_t IRAM_ATTR HOT get_loop_component_start_time() const { return this->loop_component_start_time_; } | ||||||
|  |  | ||||||
|   /** Set the target interval with which to run the loop() calls. |   /** Set the target interval with which to run the loop() calls. | ||||||
|    * If the loop() method takes longer than the target interval, ESPHome won't |    * If the loop() method takes longer than the target interval, ESPHome won't | ||||||
|    * sleep in loop(), but if the time spent in loop() is small than the target, ESPHome |    * sleep in loop(), but if the time spent in loop() is small than the target, ESPHome | ||||||
| @@ -236,7 +239,7 @@ class Application { | |||||||
|  |  | ||||||
|   void schedule_dump_config() { this->dump_config_at_ = 0; } |   void schedule_dump_config() { this->dump_config_at_ = 0; } | ||||||
|  |  | ||||||
|   void feed_wdt(); |   void feed_wdt(uint32_t time = 0); | ||||||
|  |  | ||||||
|   void reboot(); |   void reboot(); | ||||||
|  |  | ||||||
| @@ -551,6 +554,7 @@ class Application { | |||||||
|   size_t dump_config_at_{SIZE_MAX}; |   size_t dump_config_at_{SIZE_MAX}; | ||||||
|   uint32_t app_state_{0}; |   uint32_t app_state_{0}; | ||||||
|   Component *current_component_{nullptr}; |   Component *current_component_{nullptr}; | ||||||
|  |   uint32_t loop_component_start_time_{0}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /// Global storage of Application pointer - only one Application can exist. | /// Global storage of Application pointer - only one Application can exist. | ||||||
|   | |||||||
| @@ -240,10 +240,12 @@ void PollingComponent::stop_poller() { | |||||||
| uint32_t PollingComponent::get_update_interval() const { return this->update_interval_; } | uint32_t PollingComponent::get_update_interval() const { return this->update_interval_; } | ||||||
| void PollingComponent::set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; } | void PollingComponent::set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; } | ||||||
|  |  | ||||||
| WarnIfComponentBlockingGuard::WarnIfComponentBlockingGuard(Component *component) | WarnIfComponentBlockingGuard::WarnIfComponentBlockingGuard(Component *component, uint32_t start_time) | ||||||
|     : started_(millis()), component_(component) {} |     : started_(start_time), component_(component) {} | ||||||
| WarnIfComponentBlockingGuard::~WarnIfComponentBlockingGuard() { | uint32_t WarnIfComponentBlockingGuard::finish() { | ||||||
|   uint32_t blocking_time = millis() - this->started_; |   uint32_t curr_time = millis(); | ||||||
|  |  | ||||||
|  |   uint32_t blocking_time = curr_time - this->started_; | ||||||
|   bool should_warn; |   bool should_warn; | ||||||
|   if (this->component_ != nullptr) { |   if (this->component_ != nullptr) { | ||||||
|     should_warn = this->component_->should_warn_of_blocking(blocking_time); |     should_warn = this->component_->should_warn_of_blocking(blocking_time); | ||||||
| @@ -254,8 +256,11 @@ WarnIfComponentBlockingGuard::~WarnIfComponentBlockingGuard() { | |||||||
|     const char *src = component_ == nullptr ? "<null>" : component_->get_component_source(); |     const char *src = component_ == nullptr ? "<null>" : component_->get_component_source(); | ||||||
|     ESP_LOGW(TAG, "Component %s took a long time for an operation (%" PRIu32 " ms).", src, blocking_time); |     ESP_LOGW(TAG, "Component %s took a long time for an operation (%" PRIu32 " ms).", src, blocking_time); | ||||||
|     ESP_LOGW(TAG, "Components should block for at most 30 ms."); |     ESP_LOGW(TAG, "Components should block for at most 30 ms."); | ||||||
|     ; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   return curr_time; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | WarnIfComponentBlockingGuard::~WarnIfComponentBlockingGuard() {} | ||||||
|  |  | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
| @@ -339,7 +339,11 @@ class PollingComponent : public Component { | |||||||
|  |  | ||||||
| class WarnIfComponentBlockingGuard { | class WarnIfComponentBlockingGuard { | ||||||
|  public: |  public: | ||||||
|   WarnIfComponentBlockingGuard(Component *component); |   WarnIfComponentBlockingGuard(Component *component, uint32_t start_time); | ||||||
|  |  | ||||||
|  |   // Finish the timing operation and return the current time | ||||||
|  |   uint32_t finish(); | ||||||
|  |  | ||||||
|   ~WarnIfComponentBlockingGuard(); |   ~WarnIfComponentBlockingGuard(); | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   | |||||||
| @@ -229,8 +229,11 @@ void HOT Scheduler::call() { | |||||||
|       //  - timeouts/intervals get added, potentially invalidating vector pointers |       //  - timeouts/intervals get added, potentially invalidating vector pointers | ||||||
|       //  - timeouts/intervals get cancelled |       //  - timeouts/intervals get cancelled | ||||||
|       { |       { | ||||||
|         WarnIfComponentBlockingGuard guard{item->component}; |         uint32_t now_ms = millis(); | ||||||
|  |         WarnIfComponentBlockingGuard guard{item->component, now_ms}; | ||||||
|         item->callback(); |         item->callback(); | ||||||
|  |         // Call finish to ensure blocking time is properly calculated and reported | ||||||
|  |         guard.finish(); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user