mirror of
https://github.com/esphome/esphome.git
synced 2025-09-11 15:52:20 +01:00
Reduce CPU overhead by allowing components to disable their loop() (#9089)
This commit is contained in:
@@ -30,17 +30,18 @@ const float LATE = -100.0f;
|
||||
|
||||
} // namespace setup_priority
|
||||
|
||||
// Component state uses bits 0-1 (4 states)
|
||||
const uint8_t COMPONENT_STATE_MASK = 0x03;
|
||||
// Component state uses bits 0-2 (8 states, 5 used)
|
||||
const uint8_t COMPONENT_STATE_MASK = 0x07;
|
||||
const uint8_t COMPONENT_STATE_CONSTRUCTION = 0x00;
|
||||
const uint8_t COMPONENT_STATE_SETUP = 0x01;
|
||||
const uint8_t COMPONENT_STATE_LOOP = 0x02;
|
||||
const uint8_t COMPONENT_STATE_FAILED = 0x03;
|
||||
// Status LED uses bits 2-3
|
||||
const uint8_t STATUS_LED_MASK = 0x0C;
|
||||
const uint8_t COMPONENT_STATE_LOOP_DONE = 0x04;
|
||||
// Status LED uses bits 3-4
|
||||
const uint8_t STATUS_LED_MASK = 0x18;
|
||||
const uint8_t STATUS_LED_OK = 0x00;
|
||||
const uint8_t STATUS_LED_WARNING = 0x04; // Bit 2
|
||||
const uint8_t STATUS_LED_ERROR = 0x08; // Bit 3
|
||||
const uint8_t STATUS_LED_WARNING = 0x08; // Bit 3
|
||||
const uint8_t STATUS_LED_ERROR = 0x10; // Bit 4
|
||||
|
||||
const uint16_t WARN_IF_BLOCKING_OVER_MS = 50U; ///< Initial blocking time allowed without warning
|
||||
const uint16_t WARN_IF_BLOCKING_INCREMENT_MS = 10U; ///< How long the blocking time must be larger to warn again
|
||||
@@ -113,6 +114,9 @@ void Component::call() {
|
||||
case COMPONENT_STATE_FAILED: // NOLINT(bugprone-branch-clone)
|
||||
// State failed: Do nothing
|
||||
break;
|
||||
case COMPONENT_STATE_LOOP_DONE: // NOLINT(bugprone-branch-clone)
|
||||
// State loop done: Do nothing, component has finished its work
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -136,14 +140,30 @@ bool Component::should_warn_of_blocking(uint32_t blocking_time) {
|
||||
return false;
|
||||
}
|
||||
void Component::mark_failed() {
|
||||
ESP_LOGE(TAG, "Component %s was marked as failed.", this->get_component_source());
|
||||
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();
|
||||
// Also remove from loop since failed components shouldn't loop
|
||||
App.disable_component_loop_(this);
|
||||
}
|
||||
void Component::disable_loop() {
|
||||
ESP_LOGD(TAG, "%s loop disabled", this->get_component_source());
|
||||
this->component_state_ &= ~COMPONENT_STATE_MASK;
|
||||
this->component_state_ |= COMPONENT_STATE_LOOP_DONE;
|
||||
App.disable_component_loop_(this);
|
||||
}
|
||||
void Component::enable_loop() {
|
||||
if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) {
|
||||
ESP_LOGD(TAG, "%s loop enabled", this->get_component_source());
|
||||
this->component_state_ &= ~COMPONENT_STATE_MASK;
|
||||
this->component_state_ |= COMPONENT_STATE_LOOP;
|
||||
App.enable_component_loop_(this);
|
||||
}
|
||||
}
|
||||
void Component::reset_to_construction_state() {
|
||||
if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_FAILED) {
|
||||
ESP_LOGI(TAG, "Component %s is being reset to construction state.", this->get_component_source());
|
||||
ESP_LOGI(TAG, "Component %s is being reset to construction state", this->get_component_source());
|
||||
this->component_state_ &= ~COMPONENT_STATE_MASK;
|
||||
this->component_state_ |= COMPONENT_STATE_CONSTRUCTION;
|
||||
// Clear error status when resetting
|
||||
@@ -276,8 +296,8 @@ uint32_t WarnIfComponentBlockingGuard::finish() {
|
||||
}
|
||||
if (should_warn) {
|
||||
const char *src = component_ == nullptr ? "<null>" : component_->get_component_source();
|
||||
ESP_LOGW(TAG, "Component %s took a long time for an operation (%" PRIu32 " ms).", src, blocking_time);
|
||||
ESP_LOGW(TAG, "Components should block for at most 30 ms.");
|
||||
ESP_LOGW(TAG, "Component %s took a long time for an operation (%" PRIu32 " ms)", src, blocking_time);
|
||||
ESP_LOGW(TAG, "Components should block for at most 30 ms");
|
||||
}
|
||||
|
||||
return curr_time;
|
||||
|
Reference in New Issue
Block a user