1
0
mirror of https://github.com/esphome/esphome.git synced 2025-06-15 06:46:59 +02:00

Ensure components only powerdown after teardown (#9044)

This commit is contained in:
J. Nick Koston 2025-06-10 23:21:22 -05:00 committed by GitHub
parent ad37f103fa
commit 0e27ac281f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 22 additions and 5 deletions

View File

@ -67,6 +67,7 @@ void DeepSleepComponent::begin_sleep(bool manual) {
// It's critical to teardown components cleanly for deep sleep to ensure
// Home Assistant sees a clean disconnect instead of marking the device unavailable
App.teardown_components(TEARDOWN_TIMEOUT_DEEP_SLEEP_MS);
App.run_powerdown_hooks();
this->deep_sleep_();
}

View File

@ -56,7 +56,7 @@ class EthernetComponent : public Component {
void dump_config() override;
float get_setup_priority() const override;
bool can_proceed() override;
void on_shutdown() override { powerdown(); }
void on_powerdown() override { powerdown(); }
bool is_connected();
#ifdef USE_ETHERNET_SPI

View File

@ -89,7 +89,7 @@ class ILI9XXXDisplay : public display::DisplayBuffer,
void dump_config() override;
void setup() override;
void on_shutdown() override { this->command(ILI9XXX_SLPIN); }
void on_powerdown() override { this->command(ILI9XXX_SLPIN); }
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }
void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order,

View File

@ -38,7 +38,7 @@ class PN532 : public PollingComponent {
float get_setup_priority() const override;
void loop() override;
void on_shutdown() override { powerdown(); }
void on_powerdown() override { powerdown(); }
void register_tag(PN532BinarySensor *tag) { this->binary_sensors_.push_back(tag); }
void register_ontag_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontag_.push_back(trig); }

View File

@ -52,7 +52,7 @@ void PowerSupply::unrequest_high_power() {
});
}
}
void PowerSupply::on_shutdown() {
void PowerSupply::on_powerdown() {
this->active_requests_ = 0;
this->pin_->digital_write(false);
}

View File

@ -32,7 +32,7 @@ class PowerSupply : public Component {
/// Hardware setup priority (+1).
float get_setup_priority() const override;
void on_shutdown() override;
void on_powerdown() override;
protected:
GPIOPin *pin_;

View File

@ -169,6 +169,7 @@ void Application::safe_reboot() {
ESP_LOGI(TAG, "Rebooting safely");
run_safe_shutdown_hooks();
teardown_components(TEARDOWN_TIMEOUT_REBOOT_MS);
run_powerdown_hooks();
arch_restart();
}
@ -181,6 +182,12 @@ void Application::run_safe_shutdown_hooks() {
}
}
void Application::run_powerdown_hooks() {
for (auto it = this->components_.rbegin(); it != this->components_.rend(); ++it) {
(*it)->on_powerdown();
}
}
void Application::teardown_components(uint32_t timeout_ms) {
uint32_t start_time = millis();

View File

@ -257,6 +257,8 @@ class Application {
void run_safe_shutdown_hooks();
void run_powerdown_hooks();
/** Teardown all components with a timeout.
*
* @param timeout_ms Maximum time to wait for teardown in milliseconds

View File

@ -116,6 +116,13 @@ class Component {
*/
virtual bool teardown() { return true; }
/** Called after teardown is complete to power down hardware.
*
* This is called after all components have finished their teardown process,
* making it safe to power down hardware like ethernet PHY.
*/
virtual void on_powerdown() {}
uint32_t get_component_state() const;
/** Mark this component as failed. Any future timeouts/intervals/setup/loop will no longer be called.