ESPHome 2026.3.0
Loading...
Searching...
No Matches
component.cpp
Go to the documentation of this file.
2
3#include <cinttypes>
4#include <limits>
5#include <memory>
6#include <utility>
7#include <vector>
9#include "esphome/core/hal.h"
11#include "esphome/core/log.h"
12#ifdef USE_RUNTIME_STATS
14#endif
15
16namespace esphome {
17
18static const char *const TAG = "component";
19
20// Global vectors for component data that doesn't belong in every instance.
21// Using vector instead of unordered_map for both because:
22// - Much lower memory overhead (8 bytes per entry vs 20+ for unordered_map)
23// - Linear search is fine for small n (typically < 5 entries)
24// - These are rarely accessed (setup only or error cases only)
25
26// Component error messages - only stores messages for failed components
27// Lazy allocated since most configs have zero failures
28// Note: We don't clear this vector because:
29// 1. Components are never destroyed in ESPHome
30// 2. Failed components remain failed (no recovery mechanism)
31// 3. Memory usage is minimal (only failures with custom messages are stored)
32
33// Using namespace-scope static to avoid guard variables (saves 16 bytes total)
34// This is safe because ESPHome is single-threaded during initialization
35namespace {
36struct ComponentErrorMessage {
37 const Component *component;
38 const char *message;
39 // Track if message is flash pointer (needs LOG_STR_ARG) or RAM pointer
40 // Remove before 2026.6.0 when deprecated const char* API is removed
42};
43
44#ifdef USE_SETUP_PRIORITY_OVERRIDE
45struct ComponentPriorityOverride {
46 const Component *component;
47 float priority;
48};
49
50// Setup priority overrides - freed after setup completes
51// Using raw pointer instead of unique_ptr to avoid global constructor/destructor overhead
52// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
53std::vector<ComponentPriorityOverride> *setup_priority_overrides = nullptr;
54#endif
55
56// Error messages for failed components
57// Using raw pointer instead of unique_ptr to avoid global constructor/destructor overhead
58// This is never freed as error messages persist for the lifetime of the device
59// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
60std::vector<ComponentErrorMessage> *component_error_messages = nullptr;
61
62// Helper to store error messages - reduces duplication between deprecated and new API
63// Remove before 2026.6.0 when deprecated const char* API is removed
64void store_component_error_message(const Component *component, const char *message, bool is_flash_ptr) {
65 // Lazy allocate the error messages vector if needed
66 if (!component_error_messages) {
67 component_error_messages = new std::vector<ComponentErrorMessage>();
68 }
69 // Check if this component already has an error message
70 for (auto &entry : *component_error_messages) {
71 if (entry.component == component) {
72 entry.message = message;
73 entry.is_flash_ptr = is_flash_ptr;
74 return;
75 }
76 }
77 // Add new error message
78 component_error_messages->emplace_back(ComponentErrorMessage{component, message, is_flash_ptr});
79}
80} // namespace
81
82// setup_priority, component state, and status LED constants are now
83// constexpr in component.h
84
85static constexpr uint16_t WARN_IF_BLOCKING_INCREMENT_MS =
86 10U;
87
88#ifdef USE_LOOP_PRIORITY
89float Component::get_loop_priority() const { return 0.0f; }
90#endif
91
93
95
97
98void Component::set_interval(const std::string &name, uint32_t interval, std::function<void()> &&f) { // NOLINT
99#pragma GCC diagnostic push
100#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
101 App.scheduler.set_interval(this, name, interval, std::move(f));
102#pragma GCC diagnostic pop
103}
104
105void Component::set_interval(const char *name, uint32_t interval, std::function<void()> &&f) { // NOLINT
106 App.scheduler.set_interval(this, name, interval, std::move(f));
107}
108
109bool Component::cancel_interval(const std::string &name) { // NOLINT
110#pragma GCC diagnostic push
111#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
112 return App.scheduler.cancel_interval(this, name);
113#pragma GCC diagnostic pop
114}
115
116bool Component::cancel_interval(const char *name) { // NOLINT
117 return App.scheduler.cancel_interval(this, name);
118}
119
120void Component::set_retry(const std::string &name, uint32_t initial_wait_time, uint8_t max_attempts,
121 std::function<RetryResult(uint8_t)> &&f, float backoff_increase_factor) { // NOLINT
122#pragma GCC diagnostic push
123#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
124 App.scheduler.set_retry(this, name, initial_wait_time, max_attempts, std::move(f), backoff_increase_factor);
125#pragma GCC diagnostic pop
126}
127
128void Component::set_retry(const char *name, uint32_t initial_wait_time, uint8_t max_attempts,
129 std::function<RetryResult(uint8_t)> &&f, float backoff_increase_factor) { // NOLINT
130#pragma GCC diagnostic push
131#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
132 App.scheduler.set_retry(this, name, initial_wait_time, max_attempts, std::move(f), backoff_increase_factor);
133#pragma GCC diagnostic pop
134}
135
136bool Component::cancel_retry(const std::string &name) { // NOLINT
137#pragma GCC diagnostic push
138#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
139 return App.scheduler.cancel_retry(this, name);
140#pragma GCC diagnostic pop
141}
142
143bool Component::cancel_retry(const char *name) { // NOLINT
144#pragma GCC diagnostic push
145#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
146 return App.scheduler.cancel_retry(this, name);
147#pragma GCC diagnostic pop
148}
149
150void Component::set_timeout(const std::string &name, uint32_t timeout, std::function<void()> &&f) { // NOLINT
151#pragma GCC diagnostic push
152#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
153 App.scheduler.set_timeout(this, name, timeout, std::move(f));
154#pragma GCC diagnostic pop
155}
156
157void Component::set_timeout(const char *name, uint32_t timeout, std::function<void()> &&f) { // NOLINT
158 App.scheduler.set_timeout(this, name, timeout, std::move(f));
159}
160
161bool Component::cancel_timeout(const std::string &name) { // NOLINT
162#pragma GCC diagnostic push
163#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
164 return App.scheduler.cancel_timeout(this, name);
165#pragma GCC diagnostic pop
166}
167
168bool Component::cancel_timeout(const char *name) { // NOLINT
169 return App.scheduler.cancel_timeout(this, name);
170}
171
172// uint32_t (numeric ID) overloads - zero heap allocation
173void Component::set_timeout(uint32_t id, uint32_t timeout, std::function<void()> &&f) { // NOLINT
174 App.scheduler.set_timeout(this, id, timeout, std::move(f));
175}
176
177bool Component::cancel_timeout(uint32_t id) { return App.scheduler.cancel_timeout(this, id); }
178
179void Component::set_timeout(InternalSchedulerID id, uint32_t timeout, std::function<void()> &&f) { // NOLINT
180 App.scheduler.set_timeout(this, id, timeout, std::move(f));
181}
182
183bool Component::cancel_timeout(InternalSchedulerID id) { return App.scheduler.cancel_timeout(this, id); }
184
185void Component::set_interval(uint32_t id, uint32_t interval, std::function<void()> &&f) { // NOLINT
186 App.scheduler.set_interval(this, id, interval, std::move(f));
187}
188
189bool Component::cancel_interval(uint32_t id) { return App.scheduler.cancel_interval(this, id); }
190
191void Component::set_interval(InternalSchedulerID id, uint32_t interval, std::function<void()> &&f) { // NOLINT
192 App.scheduler.set_interval(this, id, interval, std::move(f));
193}
194
195bool Component::cancel_interval(InternalSchedulerID id) { return App.scheduler.cancel_interval(this, id); }
196
197void Component::set_retry(uint32_t id, uint32_t initial_wait_time, uint8_t max_attempts,
198 std::function<RetryResult(uint8_t)> &&f, float backoff_increase_factor) { // NOLINT
199#pragma GCC diagnostic push
200#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
201 App.scheduler.set_retry(this, id, initial_wait_time, max_attempts, std::move(f), backoff_increase_factor);
202#pragma GCC diagnostic pop
203}
204
205bool Component::cancel_retry(uint32_t id) {
206#pragma GCC diagnostic push
207#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
208 return App.scheduler.cancel_retry(this, id);
209#pragma GCC diagnostic pop
210}
211
212void Component::call_loop_() { this->loop(); }
213void Component::call_setup() { this->setup(); }
215 this->dump_config();
216 if (this->is_failed()) {
217 // Look up error message from global vector
218 const char *error_msg = nullptr;
219 bool is_flash_ptr = false;
220 if (component_error_messages) {
221 for (const auto &entry : *component_error_messages) {
222 if (entry.component == this) {
223 error_msg = entry.message;
224 is_flash_ptr = entry.is_flash_ptr;
225 break;
226 }
227 }
228 }
229 // Log with appropriate format based on pointer type
230 ESP_LOGE(TAG, " %s is marked FAILED: %s", LOG_STR_ARG(this->get_component_log_str()),
231 error_msg ? (is_flash_ptr ? LOG_STR_ARG((const LogString *) error_msg) : error_msg)
232 : LOG_STR_LITERAL("unspecified"));
233 }
234}
235
238 switch (state) {
240 // State Construction: Call setup and set state to setup
242 ESP_LOGV(TAG, "Setup %s", LOG_STR_ARG(this->get_component_log_str()));
243#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
244 uint32_t start_time = millis();
245#endif
246 this->call_setup();
247#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
248 uint32_t setup_time = millis() - start_time;
249 // Only log at CONFIG level if setup took longer than the blocking threshold
250 // to avoid spamming the log and blocking the event loop
251 if (setup_time >= WARN_IF_BLOCKING_OVER_MS) {
252 ESP_LOGCONFIG(TAG, "Setup %s took %ums", LOG_STR_ARG(this->get_component_log_str()), (unsigned) setup_time);
253 } else {
254 ESP_LOGV(TAG, "Setup %s took %ums", LOG_STR_ARG(this->get_component_log_str()), (unsigned) setup_time);
255 }
256#endif
257 break;
258 }
260 // State setup: Call first loop and set state to loop
262 this->call_loop_();
263 break;
265 // State loop: Call loop
266 this->call_loop_();
267 break;
269 // State failed: Do nothing
271 // State loop done: Do nothing, component has finished its work
272 default:
273 break;
274 }
275}
276const LogString *Component::get_component_log_str() const {
277 return this->component_source_ == nullptr ? LOG_STR("<unknown>") : this->component_source_;
278}
280 if (blocking_time > this->warn_if_blocking_over_) {
281 // Prevent overflow when adding increment - if we're about to overflow, just max out
282 if (blocking_time + WARN_IF_BLOCKING_INCREMENT_MS < blocking_time ||
283 blocking_time + WARN_IF_BLOCKING_INCREMENT_MS > std::numeric_limits<uint16_t>::max()) {
284 this->warn_if_blocking_over_ = std::numeric_limits<uint16_t>::max();
285 } else {
286 this->warn_if_blocking_over_ = static_cast<uint16_t>(blocking_time + WARN_IF_BLOCKING_INCREMENT_MS);
287 }
288 return true;
289 }
290 return false;
291}
293 ESP_LOGE(TAG, "%s was marked as failed", LOG_STR_ARG(this->get_component_log_str()));
295 this->status_set_error();
296 // Also remove from loop since failed components shouldn't loop
298}
301 ESP_LOGVV(TAG, "%s loop disabled", LOG_STR_ARG(this->get_component_log_str()));
304 }
305}
308 ESP_LOGVV(TAG, "%s loop enabled", LOG_STR_ARG(this->get_component_log_str()));
311 }
312}
314 // This method is thread and ISR-safe because:
315 // 1. Only performs simple assignments to volatile variables (atomic on all platforms)
316 // 2. No read-modify-write operations that could be interrupted
317 // 3. No memory allocation or object construction; on ESP32 the only call (wake_loop_any_context) is ISR-safe
318 // 4. IRAM_ATTR ensures code is in IRAM, not flash (required for ISR execution)
319 // 5. Components are never destroyed, so no use-after-free concerns
320 // 6. App is guaranteed to be initialized before any ISR could fire
321 // 7. Multiple ISR/thread calls are safe - just sets the same flags to true
322 // 8. Race condition with main loop is handled by clearing flag before processing
323 this->pending_enable_loop_ = true;
325#if (defined(USE_LWIP_FAST_SELECT) && defined(USE_ESP32)) || \
326 ((defined(USE_ESP8266) || defined(USE_RP2040)) && defined(USE_SOCKET_IMPL_LWIP_TCP))
327 // Wake the main loop from sleep. Without this, the main loop would not
328 // wake until the select/delay timeout expires (~16ms).
329 // ESP32: uses xPortInIsrContext() to choose the correct FreeRTOS notify API.
330 // ESP8266: sets socket wake flag and calls esp_schedule() to exit esp_delay() early.
331 // RP2040: sets socket wake flag and calls __sev() to exit __wfe() early.
333#endif
334}
337 ESP_LOGI(TAG, "%s is being reset to construction state", LOG_STR_ARG(this->get_component_log_str()));
339 // Clear error status when resetting
340 this->status_clear_error();
341 }
342}
343void Component::defer(std::function<void()> &&f) { // NOLINT
344 App.scheduler.set_timeout(this, static_cast<const char *>(nullptr), 0, std::move(f));
345}
346bool Component::cancel_defer(const std::string &name) { // NOLINT
347#pragma GCC diagnostic push
348#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
349 return App.scheduler.cancel_timeout(this, name);
350#pragma GCC diagnostic pop
351}
352bool Component::cancel_defer(const char *name) { // NOLINT
353 return App.scheduler.cancel_timeout(this, name);
354}
355void Component::defer(const std::string &name, std::function<void()> &&f) { // NOLINT
356#pragma GCC diagnostic push
357#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
358 App.scheduler.set_timeout(this, name, 0, std::move(f));
359#pragma GCC diagnostic pop
360}
361void Component::defer(const char *name, std::function<void()> &&f) { // NOLINT
362 App.scheduler.set_timeout(this, name, 0, std::move(f));
363}
364void Component::defer(uint32_t id, std::function<void()> &&f) { // NOLINT
365 App.scheduler.set_timeout(this, id, 0, std::move(f));
366}
367bool Component::cancel_defer(uint32_t id) { return App.scheduler.cancel_timeout(this, id); }
368void Component::set_timeout(uint32_t timeout, std::function<void()> &&f) { // NOLINT
369 App.scheduler.set_timeout(this, static_cast<const char *>(nullptr), timeout, std::move(f));
370}
371void Component::set_interval(uint32_t interval, std::function<void()> &&f) { // NOLINT
372 App.scheduler.set_interval(this, static_cast<const char *>(nullptr), interval, std::move(f));
373}
374void Component::set_retry(uint32_t initial_wait_time, uint8_t max_attempts, std::function<RetryResult(uint8_t)> &&f,
375 float backoff_increase_factor) { // NOLINT
376#pragma GCC diagnostic push
377#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
378 App.scheduler.set_retry(this, "", initial_wait_time, max_attempts, std::move(f), backoff_increase_factor);
379#pragma GCC diagnostic pop
380}
386bool Component::can_proceed() { return true; }
387bool Component::set_status_flag_(uint8_t flag) {
388 if ((this->component_state_ & flag) != 0)
389 return false;
390 this->component_state_ |= flag;
391 App.app_state_ |= flag;
392 return true;
393}
394
397 return;
398 ESP_LOGW(TAG, "%s set Warning flag: %s", LOG_STR_ARG(this->get_component_log_str()),
399 message ? message : LOG_STR_LITERAL("unspecified"));
400}
403 return;
404 ESP_LOGW(TAG, "%s set Warning flag: %s", LOG_STR_ARG(this->get_component_log_str()),
405 message ? LOG_STR_ARG(message) : LOG_STR_LITERAL("unspecified"));
406}
407void Component::status_set_error() { this->status_set_error((const LogString *) nullptr); }
408void Component::status_set_error(const char *message) {
410 return;
411 ESP_LOGE(TAG, "%s set Error flag: %s", LOG_STR_ARG(this->get_component_log_str()),
412 message ? message : LOG_STR_LITERAL("unspecified"));
413 if (message != nullptr) {
414 store_component_error_message(this, message, false);
415 }
416}
417void Component::status_set_error(const LogString *message) {
419 return;
420 ESP_LOGE(TAG, "%s set Error flag: %s", LOG_STR_ARG(this->get_component_log_str()),
421 message ? LOG_STR_ARG(message) : LOG_STR_LITERAL("unspecified"));
422 if (message != nullptr) {
423 // Store the LogString pointer directly (safe because LogString is always in flash/static memory)
424 store_component_error_message(this, LOG_STR_ARG(message), true);
425 }
426}
428 this->component_state_ &= ~STATUS_LED_WARNING;
429 ESP_LOGW(TAG, "%s cleared Warning flag", LOG_STR_ARG(this->get_component_log_str()));
430}
432 this->component_state_ &= ~STATUS_LED_ERROR;
433 ESP_LOGE(TAG, "%s cleared Error flag", LOG_STR_ARG(this->get_component_log_str()));
434}
436 this->status_set_warning();
437 this->set_timeout(name, length, [this]() { this->status_clear_warning(); });
438}
440 this->status_set_error();
441 this->set_timeout(name, length, [this]() { this->status_clear_error(); });
442}
444
445// Function implementation of LOG_UPDATE_INTERVAL macro to reduce code size
447 uint32_t update_interval = component->get_update_interval();
448 if (update_interval == SCHEDULER_DONT_RUN) {
449 ESP_LOGCONFIG(tag, " Update Interval: never");
450 } else if (update_interval < 100) {
451 ESP_LOGCONFIG(tag, " Update Interval: %.3fs", update_interval / 1000.0f);
452 } else {
453 ESP_LOGCONFIG(tag, " Update Interval: %.1fs", update_interval / 1000.0f);
454 }
455}
457#ifdef USE_SETUP_PRIORITY_OVERRIDE
458 // Check if there's an override in the global vector
459 if (setup_priority_overrides) {
460 // Linear search is fine for small n (typically < 5 overrides)
461 for (const auto &entry : *setup_priority_overrides) {
462 if (entry.component == this) {
463 return entry.priority;
464 }
465 }
466 }
467#endif
468 return this->get_setup_priority();
469}
470#ifdef USE_SETUP_PRIORITY_OVERRIDE
472 // Lazy allocate the vector if needed
473 if (!setup_priority_overrides) {
474 setup_priority_overrides = new std::vector<ComponentPriorityOverride>();
475 }
476
477 // Check if this component already has an override
478 for (auto &entry : *setup_priority_overrides) {
479 if (entry.component == this) {
480 entry.priority = priority;
481 return;
482 }
483 }
484
485 // Add new override
486 setup_priority_overrides->emplace_back(ComponentPriorityOverride{this, priority});
487}
488#endif
489
490PollingComponent::PollingComponent(uint32_t update_interval) : update_interval_(update_interval) {}
491
493 // init the poller before calling setup, allowing setup to cancel it if desired
494 this->start_poller();
495 // Let the polling component subclass setup their HW.
496 this->setup();
497}
498
500 // Register interval.
501 this->set_interval(InternalSchedulerID::POLLING_UPDATE, this->get_update_interval(), [this]() { this->update(); });
502}
503
505 // Clear the interval to suspend component
507}
508
510void PollingComponent::set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
511
512static void __attribute__((noinline, cold)) warn_blocking(Component *component, uint32_t blocking_time) {
513 bool should_warn;
514 if (component != nullptr) {
516 } else {
517 should_warn = true; // Already checked > WARN_IF_BLOCKING_OVER_MS in caller
518 }
519 if (should_warn) {
520 ESP_LOGW(TAG, "%s took a long time for an operation (%" PRIu32 " ms), max is 30 ms",
521 component == nullptr ? LOG_STR_LITERAL("<null>") : LOG_STR_ARG(component->get_component_log_str()),
523 }
524}
525
526uint32_t WarnIfComponentBlockingGuard::finish() {
527 uint32_t curr_time = millis();
528 uint32_t blocking_time = curr_time - this->started_;
529#ifdef USE_RUNTIME_STATS
530 // Use micros() for accurate sub-millisecond timing. millis() has insufficient
531 // resolution — most components complete in microseconds but millis() only has
532 // 1ms granularity, so results were essentially random noise.
533 if (global_runtime_stats != nullptr) {
534 uint32_t duration_us = micros() - this->started_us_;
536 }
537#endif
539 warn_blocking(this->component_, blocking_time);
540 }
541 return curr_time;
542}
543
544#ifdef USE_SETUP_PRIORITY_OVERRIDE
546 // Free the setup priority map completely
547 delete setup_priority_overrides;
548 setup_priority_overrides = nullptr;
549}
550#endif
551
552} // namespace esphome
static void IRAM_ATTR wake_loop_any_context()
Wake the main event loop from any context (ISR, thread, or main loop).
void enable_component_loop_(Component *component)
void disable_component_loop_(Component *component)
volatile bool has_pending_enable_loop_requests_
void mark_failed()
Mark this component as failed.
void status_momentary_error(const char *name, uint32_t length=5000)
Set error status flag and automatically clear it after a timeout.
virtual float get_setup_priority() const
priority of setup().
Definition component.cpp:92
virtual void setup()
Where the component's initialization should happen.
Definition component.cpp:94
float get_actual_setup_priority() const
const LogString * get_component_log_str() const
Get the integration where this component was declared as a LogString for logging.
ESPDEPRECATED("Use const char* overload instead. Removed in 2026.7.0", "2026.1.0") void defer(const std voi defer)(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call.
Definition component.h:501
const LogString * component_source_
Definition component.h:520
bool set_status_flag_(uint8_t flag)
Helper to set a status LED flag on both this component and the app.
bool is_failed() const
Definition component.h:233
void status_set_warning(const char *message=nullptr)
bool should_warn_of_blocking(uint32_t blocking_time)
volatile bool pending_enable_loop_
ISR-safe flag for enable_loop_soon_any_context.
Definition component.h:529
virtual bool can_proceed()
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_timeout(const std voi set_timeout)(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition component.h:451
virtual float get_loop_priority() const
priority of loop().
Definition component.cpp:89
void status_clear_error()
Definition component.h:260
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_interval(const std voi set_interval)(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
Definition component.h:358
void enable_loop_soon_any_context()
Thread and ISR-safe version of enable_loop() that can be called from any context.
ESPDEPRECATED("Use const char* overload instead. Removed in 2026.7.0", "2026.1.0") bool cancel_defer(const std boo cancel_defer)(const char *name)
Cancel a defer callback using the specified name, name must not be empty.
Definition component.h:513
uint16_t warn_if_blocking_over_
Warn if blocked for this many ms (max 65.5s)
Definition component.h:521
uint8_t component_state_
State of this component - each bit has a purpose: Bits 0-2: Component state (0x00=CONSTRUCTION,...
Definition component.h:528
void status_momentary_warning(const char *name, uint32_t length=5000)
Set warning status flag and automatically clear it after a timeout.
bool is_ready() const
virtual void dump_config()
void enable_loop()
Enable this component's loop.
void status_clear_warning_slow_path_()
void set_component_state_(uint8_t state)
Helper to set component state (clears state bits and sets new state)
Definition component.h:307
ESPDEPRECATED("set_retry is deprecated and will be removed in 2026.8.0. Use set_timeout or set_interval instead.", "2026.2.0") void set_retry(const std uint32_t uint8_t std::function< RetryResult(uint8_t)> float backoff_increase_factor
Definition component.h:395
void status_clear_error_slow_path_()
void disable_loop()
Disable this component's loop.
ESPDEPRECATED("set_retry is deprecated and will be removed in 2026.8.0. Use set_timeout or set_interval instead.", "2026.2.0") void set_retry(const std uint32_t initial_wait_time
Definition component.h:394
virtual void loop()
This method will be called repeatedly.
Definition component.cpp:96
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") bool cancel_timeout(const std boo cancel_timeout)(const char *name)
Cancel a timeout function.
Definition component.h:473
ESPDEPRECATED("set_retry is deprecated and will be removed in 2026.8.0. Use set_timeout or set_interval instead.", "2026.2.0") void set_retry(const std uint32_t uint8_t max_attempts
Definition component.h:394
void reset_to_construction_state()
Reset this component back to the construction state to allow setup to run again.
void set_setup_priority(float priority)
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") bool cancel_interval(const std boo cancel_interval)(const char *name)
Cancel an interval function.
Definition component.h:380
ESPDEPRECATED("set_retry is deprecated and will be removed in 2026.8.0. Use set_timeout or set_interval instead.", "2026.2.0") void set_retry(const std uint32_t uint8_t std::function< RetryResult(uint8_t)> && f
Definition component.h:395
void status_clear_warning()
Definition component.h:254
virtual void call_setup()
This class simplifies creating components that periodically check a state.
Definition component.h:538
virtual uint32_t get_update_interval() const
Get the update interval in ms of this sensor.
void call_setup() override
virtual void set_update_interval(uint32_t update_interval)
Manually set the update interval in ms for this polling object.
virtual void update()=0
void record_component_time(Component *component, uint32_t duration_us)
struct @65::@66 __attribute__
const Component * component
Definition component.cpp:37
const char * message
Definition component.cpp:38
bool is_flash_ptr
Definition component.cpp:41
uint8_t priority
bool state
Definition fan.h:2
constexpr float DATA
For components that import data from directly connected sensors like DHT.
Definition component.h:31
const char *const TAG
Definition spi.cpp:7
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
const char * tag
Definition log.h:74
constexpr uint8_t COMPONENT_STATE_FAILED
Definition component.h:72
runtime_stats::RuntimeStatsCollector * global_runtime_stats
InternalSchedulerID
Type-safe scheduler IDs for core base classes.
Definition component.h:54
constexpr uint8_t COMPONENT_STATE_LOOP
Definition component.h:71
constexpr uint8_t STATUS_LED_WARNING
Definition component.h:77
constexpr uint8_t COMPONENT_STATE_MASK
Definition component.h:68
void log_update_interval(const char *tag, PollingComponent *component)
void clear_setup_priority_overrides()
uint32_t IRAM_ATTR HOT micros()
Definition core.cpp:29
static void uint32_t blocking_time
constexpr uint16_t WARN_IF_BLOCKING_OVER_MS
Definition component.h:85
constexpr uint8_t COMPONENT_STATE_LOOP_DONE
Definition component.h:73
uint32_t IRAM_ATTR HOT millis()
Definition core.cpp:26
Application App
Global storage of Application pointer - only one Application can exist.
constexpr uint8_t COMPONENT_STATE_SETUP
Definition component.h:70
constexpr uint8_t COMPONENT_STATE_CONSTRUCTION
Definition component.h:69
constexpr uint8_t STATUS_LED_ERROR
Definition component.h:78
constexpr uint32_t SCHEDULER_DONT_RUN
Definition component.h:49
static void uint32_t
uint16_t length
Definition tt21100.cpp:0