mirror of
https://github.com/Threnklyn/esphome-dev.git
synced 2026-05-31 02:08:26 +02:00
Store source package in Component for debugging (#2070)
This commit is contained in:
@@ -19,7 +19,7 @@ void Application::register_component_(Component *comp) {
|
||||
|
||||
for (auto *c : this->components_) {
|
||||
if (comp == c) {
|
||||
ESP_LOGW(TAG, "Component already registered! (%p)", c);
|
||||
ESP_LOGW(TAG, "Component %s already registered! (%p)", c->get_component_source(), c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -66,23 +66,19 @@ void Application::setup() {
|
||||
}
|
||||
void Application::loop() {
|
||||
uint32_t new_app_state = 0;
|
||||
const uint32_t start = millis();
|
||||
|
||||
this->scheduler.call();
|
||||
for (Component *component : this->looping_components_) {
|
||||
component->call();
|
||||
{
|
||||
WarnIfComponentBlockingGuard guard{component};
|
||||
component->call();
|
||||
}
|
||||
new_app_state |= component->get_component_state();
|
||||
this->app_state_ |= new_app_state;
|
||||
this->feed_wdt();
|
||||
}
|
||||
this->app_state_ = new_app_state;
|
||||
|
||||
const uint32_t end = millis();
|
||||
if (end - start > 200) {
|
||||
ESP_LOGV(TAG, "A component took a long time in a loop() cycle (%.2f s).", (end - start) / 1e3f);
|
||||
ESP_LOGV(TAG, "Components should block for at most 20-30ms in loop().");
|
||||
}
|
||||
|
||||
const uint32_t now = millis();
|
||||
|
||||
if (HighFrequencyLoopRequester::is_high_frequency()) {
|
||||
|
||||
@@ -92,8 +92,13 @@ void Component::call() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char *Component::get_component_source() const {
|
||||
if (this->component_source_ == nullptr)
|
||||
return "<unknown>";
|
||||
return this->component_source_;
|
||||
}
|
||||
void Component::mark_failed() {
|
||||
ESP_LOGE(TAG, "Component was marked as failed.");
|
||||
ESP_LOGE(TAG, "Component %s was marked as failed.", this->get_component_source());
|
||||
this->component_state_ &= ~COMPONENT_STATE_MASK;
|
||||
this->component_state_ |= COMPONENT_STATE_FAILED;
|
||||
this->status_set_error();
|
||||
@@ -190,4 +195,18 @@ uint32_t Nameable::get_object_id_hash() { return this->object_id_hash_; }
|
||||
bool Nameable::is_disabled_by_default() const { return this->disabled_by_default_; }
|
||||
void Nameable::set_disabled_by_default(bool disabled_by_default) { this->disabled_by_default_ = disabled_by_default; }
|
||||
|
||||
WarnIfComponentBlockingGuard::WarnIfComponentBlockingGuard(Component *component) {
|
||||
component_ = component;
|
||||
started_ = millis();
|
||||
}
|
||||
WarnIfComponentBlockingGuard::~WarnIfComponentBlockingGuard() {
|
||||
uint32_t now = millis();
|
||||
if (now - started_ > 50) {
|
||||
const char *src = component_ == nullptr ? "<null>" : component_->get_component_source();
|
||||
ESP_LOGV(TAG, "Component %s took a long time for an operation (%.2f s).", src, (now - started_) / 1e3f);
|
||||
ESP_LOGV(TAG, "Components should block for at most 20-30ms.");
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
@@ -130,6 +130,17 @@ class Component {
|
||||
|
||||
bool has_overridden_loop() const;
|
||||
|
||||
/** Set where this component was loaded from for some debug messages.
|
||||
*
|
||||
* This is set by the ESPHome core, and should not be called manually.
|
||||
*/
|
||||
void set_component_source(const char *source) { component_source_ = source; }
|
||||
/** Get the integration where this component was declared as a string.
|
||||
*
|
||||
* Returns "<unknown>" if source not set
|
||||
*/
|
||||
const char *get_component_source() const;
|
||||
|
||||
protected:
|
||||
virtual void call_loop();
|
||||
virtual void call_setup();
|
||||
@@ -201,6 +212,7 @@ class Component {
|
||||
|
||||
uint32_t component_state_{0x0000}; ///< State of this component.
|
||||
float setup_priority_override_{NAN};
|
||||
const char *component_source_ = nullptr;
|
||||
};
|
||||
|
||||
/** This class simplifies creating components that periodically check a state.
|
||||
@@ -276,4 +288,14 @@ class Nameable {
|
||||
bool disabled_by_default_{false};
|
||||
};
|
||||
|
||||
class WarnIfComponentBlockingGuard {
|
||||
public:
|
||||
WarnIfComponentBlockingGuard(Component *component);
|
||||
~WarnIfComponentBlockingGuard();
|
||||
|
||||
protected:
|
||||
uint32_t started_;
|
||||
Component *component_;
|
||||
};
|
||||
|
||||
} // namespace esphome
|
||||
|
||||
@@ -155,7 +155,10 @@ void ICACHE_RAM_ATTR HOT Scheduler::call() {
|
||||
// Warning: During f(), a lot of stuff can happen, including:
|
||||
// - timeouts/intervals get added, potentially invalidating vector pointers
|
||||
// - timeouts/intervals get cancelled
|
||||
item->f();
|
||||
{
|
||||
WarnIfComponentBlockingGuard guard{item->component};
|
||||
item->f();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user