12#ifdef USE_RUNTIME_STATS
18static const char *
const TAG =
"component";
36struct ComponentErrorMessage {
44struct ComponentPriorityOverride {
53std::vector<ComponentErrorMessage> *component_error_messages =
nullptr;
57std::vector<ComponentPriorityOverride> *setup_priority_overrides =
nullptr;
63 if (!component_error_messages) {
64 component_error_messages =
new std::vector<ComponentErrorMessage>();
67 for (
auto &entry : *component_error_messages) {
79namespace setup_priority {
81const float BUS = 1000.0f;
82const float IO = 900.0f;
124#pragma GCC diagnostic push
125#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
126 App.scheduler.set_interval(
this, name, interval, std::move(
f));
127#pragma GCC diagnostic pop
131 App.scheduler.set_interval(
this, name, interval, std::move(
f));
135#pragma GCC diagnostic push
136#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
137 return App.scheduler.cancel_interval(
this, name);
138#pragma GCC diagnostic pop
142 return App.scheduler.cancel_interval(
this, name);
145void Component::set_retry(
const std::string &name, uint32_t initial_wait_time, uint8_t max_attempts,
146 std::function<
RetryResult(uint8_t)> &&f,
float backoff_increase_factor) {
147#pragma GCC diagnostic push
148#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
150#pragma GCC diagnostic pop
153void Component::set_retry(
const char *name, uint32_t initial_wait_time, uint8_t max_attempts,
154 std::function<
RetryResult(uint8_t)> &&f,
float backoff_increase_factor) {
155#pragma GCC diagnostic push
156#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
158#pragma GCC diagnostic pop
161bool Component::cancel_retry(
const std::string &name) {
162#pragma GCC diagnostic push
163#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
164 return App.scheduler.cancel_retry(
this, name);
165#pragma GCC diagnostic pop
168bool Component::cancel_retry(
const char *name) {
169#pragma GCC diagnostic push
170#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
171 return App.scheduler.cancel_retry(
this, name);
172#pragma GCC diagnostic pop
176#pragma GCC diagnostic push
177#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
178 App.scheduler.set_timeout(
this, name, timeout, std::move(
f));
179#pragma GCC diagnostic pop
183 App.scheduler.set_timeout(
this, name, timeout, std::move(
f));
187#pragma GCC diagnostic push
188#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
189 return App.scheduler.cancel_timeout(
this, name);
190#pragma GCC diagnostic pop
194 return App.scheduler.cancel_timeout(
this, name);
199 App.scheduler.set_timeout(
this,
id, timeout, std::move(
f));
205 App.scheduler.set_timeout(
this,
id, timeout, std::move(
f));
211 App.scheduler.set_interval(
this,
id, interval, std::move(
f));
217 App.scheduler.set_interval(
this,
id, interval, std::move(
f));
222void Component::set_retry(uint32_t
id, uint32_t initial_wait_time, uint8_t max_attempts,
223 std::function<
RetryResult(uint8_t)> &&f,
float backoff_increase_factor) {
224#pragma GCC diagnostic push
225#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
227#pragma GCC diagnostic pop
230bool Component::cancel_retry(uint32_t
id) {
231#pragma GCC diagnostic push
232#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
233 return App.scheduler.cancel_retry(
this,
id);
234#pragma GCC diagnostic pop
243 const char *error_msg =
nullptr;
245 if (component_error_messages) {
246 for (
const auto &entry : *component_error_messages) {
247 if (entry.component ==
this) {
248 error_msg = entry.message;
256 error_msg ? (
is_flash_ptr ? LOG_STR_ARG((
const LogString *) error_msg) : error_msg)
257 : LOG_STR_LITERAL(
"unspecified"));
269#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
270 uint32_t start_time =
millis();
273#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
274 uint32_t setup_time =
millis() - start_time;
278 ESP_LOGCONFIG(TAG,
"Setup %s took %ums", LOG_STR_ARG(this->
get_component_log_str()), (
unsigned) setup_time);
280 ESP_LOGV(TAG,
"Setup %s took %ums", LOG_STR_ARG(this->
get_component_log_str()), (
unsigned) setup_time);
358 ESP_LOGI(TAG,
"%s is being reset to construction state", LOG_STR_ARG(this->
get_component_log_str()));
368 App.scheduler.set_timeout(
this,
static_cast<const char *
>(
nullptr), 0, std::move(
f));
371#pragma GCC diagnostic push
372#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
373 return App.scheduler.cancel_timeout(
this, name);
374#pragma GCC diagnostic pop
377 return App.scheduler.cancel_timeout(
this, name);
380#pragma GCC diagnostic push
381#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
382 App.scheduler.set_timeout(
this, name, 0, std::move(
f));
383#pragma GCC diagnostic pop
386 App.scheduler.set_timeout(
this, name, 0, std::move(
f));
389 App.scheduler.set_timeout(
this,
id, 0, std::move(
f));
393 App.scheduler.set_timeout(
this,
static_cast<const char *
>(
nullptr), timeout, std::move(
f));
396 App.scheduler.set_interval(
this,
static_cast<const char *
>(
nullptr), interval, std::move(
f));
398void Component::set_retry(uint32_t initial_wait_time, uint8_t max_attempts, std::function<
RetryResult(uint8_t)> &&f,
399 float backoff_increase_factor) {
400#pragma GCC diagnostic push
401#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
403#pragma GCC diagnostic pop
423 message ?
message : LOG_STR_LITERAL(
"unspecified"));
432 message ? LOG_STR_ARG(
message) : LOG_STR_LITERAL(
"unspecified"));
441 message ?
message : LOG_STR_LITERAL(
"unspecified"));
443 store_component_error_message(
this,
message,
false);
452 message ? LOG_STR_ARG(
message) : LOG_STR_LITERAL(
"unspecified"));
455 store_component_error_message(
this, LOG_STR_ARG(
message),
true);
482 uint32_t update_interval =
component->get_update_interval();
483 if (update_interval == SCHEDULER_DONT_RUN) {
484 ESP_LOGCONFIG(tag,
" Update Interval: never");
485 }
else if (update_interval < 100) {
486 ESP_LOGCONFIG(tag,
" Update Interval: %.3fs", update_interval / 1000.0f);
488 ESP_LOGCONFIG(tag,
" Update Interval: %.1fs", update_interval / 1000.0f);
493 if (setup_priority_overrides) {
495 for (
const auto &entry : *setup_priority_overrides) {
496 if (entry.component ==
this) {
497 return entry.priority;
505 if (!setup_priority_overrides) {
506 setup_priority_overrides =
new std::vector<ComponentPriorityOverride>();
508 setup_priority_overrides->reserve(10);
512 for (
auto &entry : *setup_priority_overrides) {
513 if (entry.component ==
this) {
520 setup_priority_overrides->emplace_back(ComponentPriorityOverride{
this,
priority});
524#if defined(USE_HOST) || defined(CLANG_TIDY)
525 bool loop_overridden =
true;
526 bool call_loop_overridden =
true;
528#pragma GCC diagnostic push
529#pragma GCC diagnostic ignored "-Wpmf-conversions"
532#pragma GCC diagnostic pop
534 return loop_overridden || call_loop_overridden;
560 : started_(start_time), component_(
component) {}
562 uint32_t curr_time =
millis();
564 uint32_t blocking_time = curr_time - this->
started_;
566#ifdef USE_RUNTIME_STATS
579 ESP_LOGW(TAG,
"%s took a long time for an operation (%" PRIu32
" ms)",
582 ESP_LOGW(TAG,
"Components should block for at most 30 ms");
592 delete setup_priority_overrides;
593 setup_priority_overrides =
nullptr;
void enable_component_loop_(Component *component)
void disable_component_loop_(Component *component)
volatile bool has_pending_enable_loop_requests_
virtual void mark_failed()
Mark this component as failed.
virtual void call_dump_config()
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().
virtual void setup()
Where the component's initialization should happen.
float get_actual_setup_priority() const
bool has_overridden_loop() 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.
const LogString * component_source_
uint8_t get_component_state() const
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.
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.
virtual float get_loop_priority() const
priority of loop().
void status_clear_error()
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.
void enable_loop_soon_any_context()
Thread and ISR-safe version of enable_loop() that can be called from any context.
bool is_in_loop_state() const
Check if this component has completed setup and is in the loop state.
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.
uint16_t warn_if_blocking_over_
Warn if blocked for this many ms (max 65.5s)
uint8_t component_state_
State of this component - each bit has a purpose: Bits 0-2: Component state (0x00=CONSTRUCTION,...
void status_momentary_warning(const char *name, uint32_t length=5000)
Set warning status flag and automatically clear it after a timeout.
virtual void dump_config()
void enable_loop()
Enable this component's loop.
void set_component_state_(uint8_t state)
Helper to set component state (clears state bits and sets new state)
bool status_has_warning() const
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
bool status_has_error() const
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
virtual void loop()
This method will be called repeatedly.
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.
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
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.
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
void status_clear_warning()
virtual void call_setup()
bool is_idle() const
Check if this component is idle.
This class simplifies creating components that periodically check a state.
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.
uint32_t update_interval_
~WarnIfComponentBlockingGuard()
WarnIfComponentBlockingGuard(Component *component, uint32_t start_time)
void record_component_time(Component *component, uint32_t duration_ms, uint32_t current_time)
const Component * component
const float BUS
For communication buses like i2c/spi.
const float AFTER_CONNECTION
For components that should be initialized after a data connection (API/MQTT) is connected.
const float DATA
For components that import data from directly connected sensors like DHT.
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
const float BEFORE_CONNECTION
For components that should be initialized after WiFi and before API is connected.
const float IO
For components that represent GPIO pins like PCF8573.
const float LATE
For components that should be initialized at the very end of the setup process.
const float AFTER_WIFI
For components that should be initialized after WiFi is connected.
const float PROCESSOR
For components that use data from sensors like displays.
const float AFTER_BLUETOOTH
Providing packet encoding functions for exchanging data with a remote host.
const uint8_t COMPONENT_STATE_SETUP
const uint8_t COMPONENT_STATE_CONSTRUCTION
const uint8_t STATUS_LED_MASK
const uint16_t WARN_IF_BLOCKING_INCREMENT_MS
How long the blocking time must be larger to warn again.
runtime_stats::RuntimeStatsCollector * global_runtime_stats
InternalSchedulerID
Type-safe scheduler IDs for core base classes.
const uint8_t COMPONENT_STATE_FAILED
const uint8_t COMPONENT_STATE_MASK
void log_update_interval(const char *tag, PollingComponent *component)
const uint8_t COMPONENT_STATE_LOOP
const uint16_t WARN_IF_BLOCKING_OVER_MS
Initial blocking time allowed without warning.
void clear_setup_priority_overrides()
const uint8_t STATUS_LED_OK
const uint8_t STATUS_LED_WARNING
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.
const uint8_t COMPONENT_STATE_LOOP_DONE
const uint8_t STATUS_LED_ERROR