ESPHome 2026.8.0-dev
Loading...
Searching...
No Matches
component.h
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <cstdint>
5#include <functional>
6#include <string>
7
9#include "esphome/core/hal.h"
11#include "esphome/core/log.h"
14
15// Forward declarations for friend access from codegen-generated setup()
16void setup(); // NOLINT(readability-redundant-declaration) - may be declared in Arduino.h
17void original_setup(); // NOLINT(readability-redundant-declaration)
18
19namespace esphome {
20
21// Forward declaration for LogString
22struct LogString;
23
24#ifdef USE_RUNTIME_STATS
25namespace runtime_stats {
26class RuntimeStatsCollector;
27} // namespace runtime_stats
28#endif
29
34namespace setup_priority {
35
37inline constexpr float POWER = 1200.0f;
39inline constexpr float BUS = 1000.0f;
41inline constexpr float IO = 900.0f;
43inline constexpr float HARDWARE = 800.0f;
45inline constexpr float DATA = 600.0f;
47inline constexpr float PROCESSOR = 400.0f;
48inline constexpr float BLUETOOTH = 350.0f;
49inline constexpr float AFTER_BLUETOOTH = 300.0f;
50inline constexpr float WIFI = 250.0f;
51inline constexpr float ETHERNET = 250.0f;
53inline constexpr float BEFORE_CONNECTION = 220.0f;
55inline constexpr float AFTER_WIFI = 200.0f;
57inline constexpr float AFTER_CONNECTION = 100.0f;
59inline constexpr float LATE = -100.0f;
60
61} // namespace setup_priority
62
63inline constexpr uint32_t SCHEDULER_DONT_RUN = 4294967295UL;
64
69 POLLING_UPDATE = 0, // PollingComponent interval
70};
71
72// Forward declaration
73class PollingComponent;
74
75// Function declaration for LOG_UPDATE_INTERVAL
76void log_update_interval(const char *tag, PollingComponent *component);
77
78#define LOG_UPDATE_INTERVAL(this) log_update_interval(TAG, this)
79
80// Component state uses bits 0-2 (8 states, 5 used)
81inline constexpr uint8_t COMPONENT_STATE_MASK = 0x07;
82inline constexpr uint8_t COMPONENT_STATE_CONSTRUCTION = 0x00;
83inline constexpr uint8_t COMPONENT_STATE_SETUP = 0x01;
84inline constexpr uint8_t COMPONENT_STATE_LOOP = 0x02;
85inline constexpr uint8_t COMPONENT_STATE_FAILED = 0x03;
86inline constexpr uint8_t COMPONENT_STATE_LOOP_DONE = 0x04;
87// Status LED uses bits 3-4
88inline constexpr uint8_t STATUS_LED_MASK = 0x18;
89inline constexpr uint8_t STATUS_LED_OK = 0x00;
90inline constexpr uint8_t STATUS_LED_WARNING = 0x08;
91inline constexpr uint8_t STATUS_LED_ERROR = 0x10;
92// Component loop override flag uses bit 5 (set at registration time)
93inline constexpr uint8_t COMPONENT_HAS_LOOP = 0x20;
94// Bit 6 on Application::app_state_ (ONLY) — set at the end of
95// Application::setup(). Component::status_clear_*_slow_path_() uses this to
96// decide whether to propagate clears to App.app_state_. Never set on a
97// Component's component_state_.
98inline constexpr uint8_t APP_STATE_SETUP_COMPLETE = 0x40;
99
100inline constexpr uint8_t WARN_IF_BLOCKING_OVER_CS = 5U; // 50ms in centiseconds (1cs = 10ms)
101
104const LogString *component_source_lookup(uint8_t index);
105
106#ifdef USE_RUNTIME_STATS
110 // Period stats (reset each logging interval)
114 // Total stats (persistent until reboot, uint64_t to avoid overflow)
116 uint64_t total_time_us{0};
118
119 // Cumulative sum of every record_time() duration since boot, across all
120 // components. Used by Application::loop() to snapshot time spent inside
121 // LoopBlockingGuard (including guards constructed by the
122 // scheduler at scheduler.cpp) so main-loop overhead accounting can
123 // subtract scheduled-callback time from the before_loop_tasks_ wall time.
124 static uint64_t global_recorded_us; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
125
126 void record_time(uint32_t duration_us) {
127 this->period_count++;
128 this->period_time_us += duration_us;
129 if (duration_us > this->period_max_time_us)
130 this->period_max_time_us = duration_us;
131 this->total_count++;
132 this->total_time_us += duration_us;
133 if (duration_us > this->total_max_time_us)
134 this->total_max_time_us = duration_us;
135 global_recorded_us += duration_us;
136 }
138 this->period_count = 0;
139 this->period_time_us = 0;
140 this->period_max_time_us = 0;
141 }
142};
143#endif
144
146 public:
152 virtual void setup();
153
159 virtual void loop();
160
161 virtual void dump_config();
162
169 virtual float get_setup_priority() const;
170
171 float get_actual_setup_priority() const;
172
173 void set_setup_priority(float priority);
174
175 void call();
176
177 virtual void on_shutdown() {}
178 virtual void on_safe_shutdown() {}
179
184 virtual bool teardown() { return true; }
185
191 virtual void on_powerdown() {}
192
193 uint8_t get_component_state() const { return this->component_state_; }
194
200
205 bool is_in_loop_state() const { return (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP; }
206
213 bool is_idle() const { return (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE; }
214
221 void mark_failed();
222
223 void mark_failed(const LogString *message) {
224 this->status_set_error(message);
225 this->mark_failed();
226 }
227
236 void disable_loop();
237
246 void enable_loop() {
247 if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE)
249 }
250
271
272 bool is_failed() const { return (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_FAILED; }
273
274 bool is_ready() const;
275
276 virtual bool can_proceed();
277
279
280 bool status_has_error() const { return this->component_state_ & STATUS_LED_ERROR; }
281
282 void status_set_warning(); // Set warning flag without message
283 void status_set_warning(const char *message);
284 void status_set_warning(const LogString *message);
285
286 void status_set_error(); // Set error flag without message
287 void status_set_error(const LogString *message);
288
290 if ((this->component_state_ & STATUS_LED_WARNING) == 0)
291 return;
293 }
294
296 if ((this->component_state_ & STATUS_LED_ERROR) == 0)
297 return;
299 }
300
308 void status_momentary_warning(const char *name, uint32_t length = 5000);
309
317 void status_momentary_error(const char *name, uint32_t length = 5000);
318
319 bool has_overridden_loop() const { return (this->component_state_ & COMPONENT_HAS_LOOP) != 0; }
320
325 inline const LogString *get_component_log_str() const ESPHOME_ALWAYS_INLINE {
327 }
328
329 bool should_warn_of_blocking(uint32_t blocking_time, uint32_t &threshold_ms_out);
330
331 protected:
332 friend class Application;
333 friend void ::setup();
334 friend void ::original_setup();
335
341 void set_component_source_(uint8_t index) { this->component_source_index_ = index; }
342
343 virtual void call_setup();
344 void call_dump_config_();
345
347
349 inline void set_component_state_(uint8_t state) {
350 this->component_state_ &= ~COMPONENT_STATE_MASK;
351 this->component_state_ |= state;
352 }
353
358 bool set_status_flag_(uint8_t flag);
359
388 void set_interval(const char *name, uint32_t interval, std::function<void()> &&f); // NOLINT
389
396 void set_interval(uint32_t id, uint32_t interval, std::function<void()> &&f); // NOLINT
397
398 void set_interval(InternalSchedulerID id, uint32_t interval, std::function<void()> &&f); // NOLINT
399
400 void set_interval(uint32_t interval, std::function<void()> &&f); // NOLINT
401
407 bool cancel_interval(const char *name); // NOLINT
408 bool cancel_interval(uint32_t id); // NOLINT
409 bool cancel_interval(InternalSchedulerID id); // NOLINT
410
433 void set_timeout(const char *name, uint32_t timeout, std::function<void()> &&f); // NOLINT
434
441 void set_timeout(uint32_t id, uint32_t timeout, std::function<void()> &&f); // NOLINT
442
443 void set_timeout(InternalSchedulerID id, uint32_t timeout, std::function<void()> &&f); // NOLINT
444
445 void set_timeout(uint32_t timeout, std::function<void()> &&f); // NOLINT
446
452 bool cancel_timeout(const char *name); // NOLINT
453 bool cancel_timeout(uint32_t id); // NOLINT
454 bool cancel_timeout(InternalSchedulerID id); // NOLINT
455
471 void defer(const char *name, std::function<void()> &&f); // NOLINT
472
474 void defer(std::function<void()> &&f); // NOLINT
475
477 void defer(uint32_t id, std::function<void()> &&f); // NOLINT
478
480 bool cancel_defer(const char *name); // NOLINT
481 bool cancel_defer(uint32_t id); // NOLINT
482
485
486 // Ordered for optimal packing on 32-bit systems (8 bytes total with vtable)
495 uint8_t component_state_{0x00};
496 volatile bool pending_enable_loop_{false};
497#ifdef USE_RUNTIME_STATS
499 friend class LoopBlockingGuard;
501#endif
502};
503
511 public:
513
518 explicit PollingComponent(uint32_t update_interval);
519
524 void set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
525
526 // ========== OVERRIDE METHODS ==========
527 // (You'll only need this when creating your own custom sensor)
528 virtual void update() = 0;
529
530 // ========== INTERNAL METHODS ==========
531 // (In most use cases you won't need these)
532 void call_setup() override;
533
535 virtual uint32_t get_update_interval() const;
536
537 // Start the poller, used for component.suspend
538 void start_poller();
539
540 // Stop the poller, used for component.suspend
541 void stop_poller();
542
543 protected:
545};
546
547// LoopBlockingGuard lives in application.h because it reads its state from App.
548
549// Function to clear setup priority overrides after all components are set up
550// Only has an implementation when USE_SETUP_PRIORITY_OVERRIDE is defined
552
553} // namespace esphome
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:82
virtual void setup()
Where the component's initialization should happen.
Definition component.cpp:84
float get_actual_setup_priority() const
bool has_overridden_loop() const
Definition component.h:319
void mark_failed(const LogString *message)
Definition component.h:223
virtual void on_powerdown()
Called after teardown is complete to power down hardware.
Definition component.h:191
bool set_status_flag_(uint8_t flag)
Helper to set a status LED flag on both this component and the app.
ComponentRuntimeStats runtime_stats_
Definition component.h:500
bool is_failed() const
Definition component.h:272
uint8_t get_component_state() const
Definition component.h:193
void enable_loop_slow_path_()
volatile bool pending_enable_loop_
ISR-safe flag for enable_loop_soon_any_context.
Definition component.h:496
virtual bool can_proceed()
virtual void on_safe_shutdown()
Definition component.h:178
bool cancel_interval(const char *name)
Cancel an interval function.
Definition component.cpp:92
void status_clear_error()
Definition component.h:295
void set_component_source_(uint8_t index)
Set where this component was loaded from for some debug messages.
Definition component.h:341
bool is_in_loop_state() const
Check if this component has completed setup and is in the loop state.
Definition component.h:205
virtual bool teardown()
Called during teardown to allow component to gracefully finish operations.
Definition component.h:184
void enable_loop_soon_any_context()
Thread and ISR-safe version of enable_loop() that can be called from any context.
uint8_t component_state_
State of this component - each bit has a purpose: Bits 0-2: Component state (0x00=CONSTRUCTION,...
Definition component.h:495
bool should_warn_of_blocking(uint32_t blocking_time, uint32_t &threshold_ms_out)
bool cancel_timeout(const char *name)
Cancel a timeout function.
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.
Definition component.h:246
const LogString * get_component_log_str() const ESPHOME_ALWAYS_INLINE
Get the integration where this component was declared as a LogString for logging.
Definition component.h:325
uint8_t component_source_index_
Index into component source PROGMEM lookup table (0 = not set)
Definition component.h:487
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:349
bool status_has_warning() const
Definition component.h:278
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
Definition component.cpp:96
void defer(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call with a const char* name.
bool status_has_error() const
Definition component.h:280
void status_clear_error_slow_path_()
void disable_loop()
Disable this component's loop.
virtual void on_shutdown()
Definition component.h:177
void set_interval(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a const char* name.
Definition component.cpp:88
virtual void loop()
This method will be called repeatedly.
Definition component.cpp:86
void reset_to_construction_state()
Reset this component back to the construction state to allow setup to run again.
uint8_t warn_if_blocking_over_
Warn threshold in centiseconds (max 2550ms)
Definition component.h:488
void set_setup_priority(float priority)
bool cancel_defer(const char *name)
Cancel a defer callback using the specified name, name must not be empty.
void status_clear_warning()
Definition component.h:289
virtual void call_setup()
bool is_idle() const
Check if this component is idle.
Definition component.h:213
This class simplifies creating components that periodically check a state.
Definition component.h:510
virtual uint32_t get_update_interval() const
Get the update interval in ms of this sensor.
void call_setup() override
void set_update_interval(uint32_t update_interval)
Manually set the update interval in ms for this polling object.
Definition component.h:524
virtual void update()=0
const Component * component
Definition component.cpp:34
const LogString * message
Definition component.cpp:35
void original_setup()
void setup()
uint8_t priority
bool state
Definition fan.h:2
constexpr float BEFORE_CONNECTION
For components that should be initialized after WiFi and before API is connected.
Definition component.h:53
constexpr float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition component.h:43
constexpr float WIFI
Definition component.h:50
constexpr float ETHERNET
Definition component.h:51
constexpr float AFTER_BLUETOOTH
Definition component.h:49
constexpr float AFTER_WIFI
For components that should be initialized after WiFi is connected.
Definition component.h:55
constexpr float LATE
For components that should be initialized at the very end of the setup process.
Definition component.h:59
constexpr float DATA
For components that import data from directly connected sensors like DHT.
Definition component.h:45
constexpr float PROCESSOR
For components that use data from sensors like displays.
Definition component.h:47
constexpr float POWER
For power supply components that must be on before buses like i2c can work.
Definition component.h:37
constexpr float BLUETOOTH
Definition component.h:48
constexpr float BUS
For communication buses like i2c/spi.
Definition component.h:39
constexpr float IO
For components that represent GPIO pins like PCF8573.
Definition component.h:41
constexpr float AFTER_CONNECTION
For components that should be initialized after a data connection (API/MQTT) is connected.
Definition component.h:57
const char * tag
Definition log.h:74
constexpr uint8_t COMPONENT_STATE_FAILED
Definition component.h:85
constexpr uint8_t WARN_IF_BLOCKING_OVER_CS
Definition component.h:100
constexpr uint8_t COMPONENT_HAS_LOOP
Definition component.h:93
InternalSchedulerID
Type-safe scheduler IDs for core base classes.
Definition component.h:68
constexpr uint8_t STATUS_LED_MASK
Definition component.h:88
constexpr uint8_t COMPONENT_STATE_LOOP
Definition component.h:84
constexpr uint8_t APP_STATE_SETUP_COMPLETE
Definition component.h:98
constexpr uint8_t STATUS_LED_WARNING
Definition component.h:90
constexpr uint8_t COMPONENT_STATE_MASK
Definition component.h:81
void log_update_interval(const char *tag, PollingComponent *component)
void clear_setup_priority_overrides()
const LogString * component_source_lookup(uint8_t index)
Lookup component source name by index (1-based).
constexpr uint8_t COMPONENT_STATE_LOOP_DONE
Definition component.h:86
constexpr uint8_t COMPONENT_STATE_SETUP
Definition component.h:83
constexpr uint8_t COMPONENT_STATE_CONSTRUCTION
Definition component.h:82
constexpr uint8_t STATUS_LED_OK
Definition component.h:89
constexpr uint8_t STATUS_LED_ERROR
Definition component.h:91
constexpr uint32_t SCHEDULER_DONT_RUN
Definition component.h:63
static void uint32_t
Inline runtime statistics — eliminates std::map lookup on every loop iteration.
Definition component.h:109
static uint64_t global_recorded_us
Definition component.h:124
void record_time(uint32_t duration_us)
Definition component.h:126
uint16_t length
Definition tt21100.cpp:0