ESPHome  1.15.2
component.cpp
Go to the documentation of this file.
2 #include "esphome/core/helpers.h"
3 #include "esphome/core/esphal.h"
4 #include "esphome/core/log.h"
6 
7 namespace esphome {
8 
9 static const char *TAG = "component";
10 
11 namespace setup_priority {
12 
13 const float BUS = 1000.0f;
14 const float IO = 900.0f;
15 const float HARDWARE = 800.0f;
16 const float DATA = 600.0f;
17 const float PROCESSOR = 400.0;
18 const float WIFI = 250.0f;
19 const float AFTER_WIFI = 200.0f;
20 const float AFTER_CONNECTION = 100.0f;
21 const float LATE = -100.0f;
22 
23 } // namespace setup_priority
24 
25 const uint32_t COMPONENT_STATE_MASK = 0xFF;
26 const uint32_t COMPONENT_STATE_CONSTRUCTION = 0x00;
27 const uint32_t COMPONENT_STATE_SETUP = 0x01;
28 const uint32_t COMPONENT_STATE_LOOP = 0x02;
29 const uint32_t COMPONENT_STATE_FAILED = 0x03;
30 const uint32_t STATUS_LED_MASK = 0xFF00;
31 const uint32_t STATUS_LED_OK = 0x0000;
32 const uint32_t STATUS_LED_WARNING = 0x0100;
33 const uint32_t STATUS_LED_ERROR = 0x0200;
34 
35 uint32_t global_state = 0;
36 
37 float Component::get_loop_priority() const { return 0.0f; }
38 
40 
42 
43 void Component::loop() {}
44 
45 void Component::set_interval(const std::string &name, uint32_t interval, std::function<void()> &&f) { // NOLINT
46  App.scheduler.set_interval(this, name, interval, std::move(f));
47 }
48 
49 bool Component::cancel_interval(const std::string &name) { // NOLINT
50  return App.scheduler.cancel_interval(this, name);
51 }
52 
53 void Component::set_timeout(const std::string &name, uint32_t timeout, std::function<void()> &&f) { // NOLINT
54  return App.scheduler.set_timeout(this, name, timeout, std::move(f));
55 }
56 
57 bool Component::cancel_timeout(const std::string &name) { // NOLINT
58  return App.scheduler.cancel_timeout(this, name);
59 }
60 
61 void Component::call_loop() { this->loop(); }
62 
63 void Component::call_setup() { this->setup(); }
64 uint32_t Component::get_component_state() const { return this->component_state_; }
66  uint32_t state = this->component_state_ & COMPONENT_STATE_MASK;
67  switch (state) {
69  // State Construction: Call setup and set state to setup
70  this->component_state_ &= ~COMPONENT_STATE_MASK;
71  this->component_state_ |= COMPONENT_STATE_SETUP;
72  this->call_setup();
73  break;
75  // State setup: Call first loop and set state to loop
76  this->component_state_ &= ~COMPONENT_STATE_MASK;
77  this->component_state_ |= COMPONENT_STATE_LOOP;
78  this->call_loop();
79  break;
81  // State loop: Call loop
82  this->call_loop();
83  break;
85  // State failed: Do nothing
86  break;
87  default:
88  break;
89  }
90 }
92  ESP_LOGE(TAG, "Component was marked as failed.");
93  this->component_state_ &= ~COMPONENT_STATE_MASK;
94  this->component_state_ |= COMPONENT_STATE_FAILED;
95  this->status_set_error();
96 }
97 void Component::defer(std::function<void()> &&f) { // NOLINT
98  App.scheduler.set_timeout(this, "", 0, std::move(f));
99 }
100 bool Component::cancel_defer(const std::string &name) { // NOLINT
101  return App.scheduler.cancel_timeout(this, name);
102 }
103 void Component::defer(const std::string &name, std::function<void()> &&f) { // NOLINT
104  App.scheduler.set_timeout(this, name, 0, std::move(f));
105 }
106 void Component::set_timeout(uint32_t timeout, std::function<void()> &&f) { // NOLINT
107  App.scheduler.set_timeout(this, "", timeout, std::move(f));
108 }
109 void Component::set_interval(uint32_t interval, std::function<void()> &&f) { // NOLINT
110  App.scheduler.set_interval(this, "", interval, std::move(f));
111 }
112 bool Component::is_failed() { return (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_FAILED; }
113 bool Component::can_proceed() { return true; }
114 bool Component::status_has_warning() { return this->component_state_ & STATUS_LED_WARNING; }
115 bool Component::status_has_error() { return this->component_state_ & STATUS_LED_ERROR; }
117  this->component_state_ |= STATUS_LED_WARNING;
119 }
121  this->component_state_ |= STATUS_LED_ERROR;
123 }
124 void Component::status_clear_warning() { this->component_state_ &= ~STATUS_LED_WARNING; }
125 void Component::status_clear_error() { this->component_state_ &= ~STATUS_LED_ERROR; }
126 void Component::status_momentary_warning(const std::string &name, uint32_t length) {
127  this->status_set_warning();
128  this->set_timeout(name, length, [this]() { this->status_clear_warning(); });
129 }
130 void Component::status_momentary_error(const std::string &name, uint32_t length) {
131  this->status_set_error();
132  this->set_timeout(name, length, [this]() { this->status_clear_error(); });
133 }
136  if (isnan(this->setup_priority_override_))
137  return this->get_setup_priority();
138  return this->setup_priority_override_;
139 }
140 void Component::set_setup_priority(float priority) { this->setup_priority_override_ = priority; }
141 
143 #ifdef CLANG_TIDY
144  bool loop_overridden = true;
145  bool call_loop_overridden = true;
146 #else
147 #pragma GCC diagnostic push
148 #pragma GCC diagnostic ignored "-Wpmf-conversions"
149  bool loop_overridden = (void *) (this->*(&Component::loop)) != (void *) (&Component::loop);
150  bool call_loop_overridden = (void *) (this->*(&Component::call_loop)) != (void *) (&Component::call_loop);
151 #pragma GCC diagnostic pop
152 #endif
153  return loop_overridden || call_loop_overridden;
154 }
155 
156 PollingComponent::PollingComponent(uint32_t update_interval) : Component(), update_interval_(update_interval) {}
157 
159  // Let the polling component subclass setup their HW.
160  this->setup();
161 
162  // Register interval.
163  this->set_interval("update", this->get_update_interval(), [this]() { this->update(); });
164 }
165 
166 uint32_t PollingComponent::get_update_interval() const { return this->update_interval_; }
167 void PollingComponent::set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
168 
169 const std::string &Nameable::get_name() const { return this->name_; }
170 void Nameable::set_name(const std::string &name) {
171  this->name_ = name;
172  this->calc_object_id_();
173 }
174 Nameable::Nameable(const std::string &name) : name_(name) { this->calc_object_id_(); }
175 
176 const std::string &Nameable::get_object_id() { return this->object_id_; }
177 bool Nameable::is_internal() const { return this->internal_; }
178 void Nameable::set_internal(bool internal) { this->internal_ = internal; }
181  // FNV-1 hash
182  this->object_id_hash_ = fnv1_hash(this->object_id_);
183 }
184 uint32_t Nameable::get_object_id_hash() { return this->object_id_hash_; }
185 
186 } // namespace esphome
const uint32_t COMPONENT_STATE_LOOP
Definition: component.cpp:28
const uint32_t COMPONENT_STATE_FAILED
Definition: component.cpp:29
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:16
virtual void loop()
This method will be called repeatedly.
Definition: component.cpp:43
void set_interval(const std::string &name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
Definition: component.cpp:45
const float AFTER_CONNECTION
For components that should be initialized after a data connection (API/MQTT) is connected.
Definition: component.cpp:20
virtual float get_loop_priority() const
priority of loop().
Definition: component.cpp:37
void set_name(const std::string &name)
Definition: component.cpp:170
bool cancel_timeout(const std::string &name)
Cancel a timeout function.
Definition: component.cpp:57
const char * HOSTNAME_CHARACTER_ALLOWLIST
The characters that are allowed in a hostname.
Definition: helpers.cpp:157
const float AFTER_WIFI
For components that should be initialized after WiFi is connected.
Definition: component.cpp:19
const char * TAG
Definition: tm1637.cpp:8
bool cancel_timeout(Component *component, const std::string &name)
Definition: scheduler.cpp:38
void status_momentary_warning(const std::string &name, uint32_t length=5000)
Definition: component.cpp:126
float get_actual_setup_priority() const
Definition: component.cpp:135
bool cancel_interval(const std::string &name)
Cancel an interval function.
Definition: component.cpp:49
const uint32_t STATUS_LED_OK
Definition: component.cpp:31
void set_setup_priority(float priority)
Definition: component.cpp:140
void defer(const std::string &name, std::function< void()> &&f)
Defer a callback to the next loop() call.
Definition: component.cpp:103
const float LATE
For components that should be initialized at the very end of the setup process.
Definition: component.cpp:21
std::string sanitize_string_allowlist(const std::string &s, const std::string &allowlist)
Sanitizes the input string with the allowlist.
Definition: helpers.cpp:88
bool has_overridden_loop() const
Definition: component.cpp:142
bool status_has_warning()
Definition: component.cpp:114
virtual void dump_config()
Definition: component.cpp:134
uint32_t object_id_hash_
Definition: component.h:264
void set_interval(Component *component, const std::string &name, uint32_t interval, std::function< void()> &&func)
Definition: scheduler.cpp:41
void status_momentary_error(const std::string &name, uint32_t length=5000)
Definition: component.cpp:130
uint32_t global_state
Definition: component.cpp:35
void calc_object_id_()
Definition: component.cpp:179
virtual void call_setup()
Definition: component.cpp:63
uint32_t get_component_state() const
Definition: component.cpp:64
const float BUS
For communication buses like i2c/spi.
Definition: component.cpp:13
virtual void setup()
Where the component&#39;s initialization should happen.
Definition: component.cpp:41
const uint32_t COMPONENT_STATE_SETUP
Definition: component.cpp:27
virtual float get_setup_priority() const
priority of setup().
Definition: component.cpp:39
void status_clear_warning()
Definition: component.cpp:124
const uint32_t COMPONENT_STATE_CONSTRUCTION
Definition: component.cpp:26
bool cancel_defer(const std::string &name)
Cancel a defer callback using the specified name, name must not be empty.
Definition: component.cpp:100
void set_timeout(uint32_t timeout, std::function< void()> &&f)
Definition: component.cpp:106
virtual void update()=0
const float PROCESSOR
For components that use data from sensors like displays.
Definition: component.cpp:17
Application App
Global storage of Application pointer - only one Application can exist.
virtual bool can_proceed()
Definition: component.cpp:113
const std::string & get_name() const
Definition: component.cpp:169
std::string name_
Definition: component.h:262
bool is_internal() const
Definition: component.cpp:177
void set_timeout(Component *component, const std::string &name, uint32_t timeout, std::function< void()> &&func)
Definition: scheduler.cpp:15
void status_set_warning()
Definition: component.cpp:116
std::string object_id_
Definition: component.h:263
const uint32_t COMPONENT_STATE_MASK
Definition: component.cpp:25
virtual uint32_t get_update_interval() const
Get the update interval in ms of this sensor.
Definition: component.cpp:166
const uint32_t STATUS_LED_WARNING
Definition: component.cpp:32
const std::string & get_object_id()
Get the sanitized name of this nameable as an ID. Caching it internally.
Definition: component.cpp:176
uint8_t priority
void status_clear_error()
Definition: component.cpp:125
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition: component.cpp:15
uint32_t get_object_id_hash()
Definition: component.cpp:184
void call_setup() override
Definition: component.cpp:158
uint32_t fnv1_hash(const std::string &str)
Definition: helpers.cpp:249
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:91
bool cancel_interval(Component *component, const std::string &name)
Definition: scheduler.cpp:71
const float IO
For components that represent GPIO pins like PCF8573.
Definition: component.cpp:14
std::string to_lowercase_underscore(std::string s)
Convert the string to lowercase_underscore.
Definition: helpers.cpp:82
const uint32_t STATUS_LED_ERROR
Definition: component.cpp:33
Definition: a4988.cpp:4
virtual void call_loop()
Definition: component.cpp:61
const uint32_t STATUS_LED_MASK
Definition: component.cpp:30
void set_internal(bool internal)
Definition: component.cpp:178
virtual void set_update_interval(uint32_t update_interval)
Manually set the update interval in ms for this polling object.
Definition: component.cpp:167