mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[interval] Fix startup behaviour (#9793)
This commit is contained in:
		| @@ -1,6 +1,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/core/log.h" | ||||
| #include "esphome/core/automation.h" | ||||
|  | ||||
| namespace esphome { | ||||
| @@ -8,16 +9,12 @@ namespace interval { | ||||
|  | ||||
| class IntervalTrigger : public Trigger<>, public PollingComponent { | ||||
|  public: | ||||
|   void update() override { | ||||
|     if (this->started_) | ||||
|       this->trigger(); | ||||
|   } | ||||
|   void update() override { this->trigger(); } | ||||
|  | ||||
|   void setup() override { | ||||
|     if (this->startup_delay_ == 0) { | ||||
|       this->started_ = true; | ||||
|     } else { | ||||
|       this->set_timeout(this->startup_delay_, [this] { this->started_ = true; }); | ||||
|     if (this->startup_delay_ != 0) { | ||||
|       this->stop_poller(); | ||||
|       this->set_timeout(this->startup_delay_, [this] { this->start_poller(); }); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -25,7 +22,6 @@ class IntervalTrigger : public Trigger<>, public PollingComponent { | ||||
|  | ||||
|  protected: | ||||
|   uint32_t startup_delay_{0}; | ||||
|   bool started_{false}; | ||||
| }; | ||||
|  | ||||
| }  // namespace interval | ||||
|   | ||||
| @@ -373,11 +373,10 @@ bool Component::has_overridden_loop() const { | ||||
| PollingComponent::PollingComponent(uint32_t update_interval) : update_interval_(update_interval) {} | ||||
|  | ||||
| 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. | ||||
|   this->setup(); | ||||
|  | ||||
|   // init the poller | ||||
|   this->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; | ||||
| // 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; | ||||
| // max delay to start an interval sequence | ||||
| static constexpr uint32_t MAX_INTERVAL_DELAY = 5000; | ||||
|  | ||||
| // Uncomment to debug scheduler | ||||
| // #define ESPHOME_DEBUG_SCHEDULER | ||||
| @@ -100,9 +102,11 @@ void HOT Scheduler::set_timer_common_(Component *component, SchedulerItem::Type | ||||
|   // Type-specific setup | ||||
|   if (type == SchedulerItem::INTERVAL) { | ||||
|     item->interval = delay; | ||||
|     // Calculate random offset (0 to interval/2) | ||||
|     uint32_t offset = (delay != 0) ? (random_uint32() % delay) / 2 : 0; | ||||
|     // first execution happens immediately after a random smallish offset | ||||
|     // 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; | ||||
|     ESP_LOGV(TAG, "Scheduler interval for %s is %" PRIu32 "ms, offset %" PRIu32 "ms", name_cstr, delay, offset); | ||||
|   } else { | ||||
|     item->interval = 0; | ||||
|     item->next_execution_ = now + delay; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user