mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	[interval] Fix startup behaviour (#9793)
This commit is contained in:
		| @@ -1,6 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "esphome/core/component.h" | #include "esphome/core/component.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/automation.h" | #include "esphome/core/automation.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| @@ -8,16 +9,12 @@ namespace interval { | |||||||
|  |  | ||||||
| class IntervalTrigger : public Trigger<>, public PollingComponent { | class IntervalTrigger : public Trigger<>, public PollingComponent { | ||||||
|  public: |  public: | ||||||
|   void update() override { |   void update() override { this->trigger(); } | ||||||
|     if (this->started_) |  | ||||||
|       this->trigger(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   void setup() override { |   void setup() override { | ||||||
|     if (this->startup_delay_ == 0) { |     if (this->startup_delay_ != 0) { | ||||||
|       this->started_ = true; |       this->stop_poller(); | ||||||
|     } else { |       this->set_timeout(this->startup_delay_, [this] { this->start_poller(); }); | ||||||
|       this->set_timeout(this->startup_delay_, [this] { this->started_ = true; }); |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -25,7 +22,6 @@ class IntervalTrigger : public Trigger<>, public PollingComponent { | |||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   uint32_t startup_delay_{0}; |   uint32_t startup_delay_{0}; | ||||||
|   bool started_{false}; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace interval | }  // namespace interval | ||||||
|   | |||||||
| @@ -373,11 +373,10 @@ bool Component::has_overridden_loop() const { | |||||||
| PollingComponent::PollingComponent(uint32_t update_interval) : update_interval_(update_interval) {} | PollingComponent::PollingComponent(uint32_t update_interval) : update_interval_(update_interval) {} | ||||||
|  |  | ||||||
| void PollingComponent::call_setup() { | void PollingComponent::call_setup() { | ||||||
|  |   // init the poller before calling setup, allowing setup to cancel it if desired | ||||||
|  |   this->start_poller(); | ||||||
|   // Let the polling component subclass setup their HW. |   // Let the polling component subclass setup their HW. | ||||||
|   this->setup(); |   this->setup(); | ||||||
|  |  | ||||||
|   // init the poller |  | ||||||
|   this->start_poller(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void PollingComponent::start_poller() { | void PollingComponent::start_poller() { | ||||||
|   | |||||||
| @@ -17,6 +17,8 @@ static const char *const TAG = "scheduler"; | |||||||
| static const uint32_t MAX_LOGICALLY_DELETED_ITEMS = 10; | static const uint32_t MAX_LOGICALLY_DELETED_ITEMS = 10; | ||||||
| // Half the 32-bit range - used to detect rollovers vs normal time progression | // Half the 32-bit range - used to detect rollovers vs normal time progression | ||||||
| static constexpr uint32_t HALF_MAX_UINT32 = std::numeric_limits<uint32_t>::max() / 2; | static constexpr uint32_t HALF_MAX_UINT32 = std::numeric_limits<uint32_t>::max() / 2; | ||||||
|  | // max delay to start an interval sequence | ||||||
|  | static constexpr uint32_t MAX_INTERVAL_DELAY = 5000; | ||||||
|  |  | ||||||
| // Uncomment to debug scheduler | // Uncomment to debug scheduler | ||||||
| // #define ESPHOME_DEBUG_SCHEDULER | // #define ESPHOME_DEBUG_SCHEDULER | ||||||
| @@ -100,9 +102,11 @@ void HOT Scheduler::set_timer_common_(Component *component, SchedulerItem::Type | |||||||
|   // Type-specific setup |   // Type-specific setup | ||||||
|   if (type == SchedulerItem::INTERVAL) { |   if (type == SchedulerItem::INTERVAL) { | ||||||
|     item->interval = delay; |     item->interval = delay; | ||||||
|     // Calculate random offset (0 to interval/2) |     // first execution happens immediately after a random smallish offset | ||||||
|     uint32_t offset = (delay != 0) ? (random_uint32() % delay) / 2 : 0; |     // Calculate random offset (0 to min(interval/2, 5s)) | ||||||
|  |     uint32_t offset = (uint32_t) (std::min(delay / 2, MAX_INTERVAL_DELAY) * random_float()); | ||||||
|     item->next_execution_ = now + offset; |     item->next_execution_ = now + offset; | ||||||
|  |     ESP_LOGV(TAG, "Scheduler interval for %s is %" PRIu32 "ms, offset %" PRIu32 "ms", name_cstr, delay, offset); | ||||||
|   } else { |   } else { | ||||||
|     item->interval = 0; |     item->interval = 0; | ||||||
|     item->next_execution_ = now + delay; |     item->next_execution_ = now + delay; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user