diff --git a/esphome/components/mqtt/mqtt_component.cpp b/esphome/components/mqtt/mqtt_component.cpp index 09570106df..f49069960b 100644 --- a/esphome/components/mqtt/mqtt_component.cpp +++ b/esphome/components/mqtt/mqtt_component.cpp @@ -405,12 +405,6 @@ void MQTTComponent::process_resend() { this->schedule_resend_state(); } } -void MQTTComponent::call_dump_config() { - if (this->is_internal()) - return; - - this->dump_config(); -} void MQTTComponent::schedule_resend_state() { this->resend_state_ = true; } bool MQTTComponent::is_connected_() const { return global_mqtt_client->is_connected(); } diff --git a/esphome/components/mqtt/mqtt_component.h b/esphome/components/mqtt/mqtt_component.h index 853712940a..0ffe6341d3 100644 --- a/esphome/components/mqtt/mqtt_component.h +++ b/esphome/components/mqtt/mqtt_component.h @@ -98,8 +98,6 @@ class MQTTComponent : public Component { /// Override setup_ so that we can call send_discovery() when needed. void call_setup() override; - void call_dump_config() override; - /// Send discovery info the Home Assistant, override this. virtual void send_discovery(JsonObject root, SendDiscoveryConfig &config) = 0; diff --git a/esphome/components/safe_mode/__init__.py b/esphome/components/safe_mode/__init__.py index d1754aaad7..f54151b746 100644 --- a/esphome/components/safe_mode/__init__.py +++ b/esphome/components/safe_mode/__init__.py @@ -21,6 +21,7 @@ CONF_ON_SAFE_MODE = "on_safe_mode" safe_mode_ns = cg.esphome_ns.namespace("safe_mode") SafeModeComponent = safe_mode_ns.class_("SafeModeComponent", cg.Component) SafeModeTrigger = safe_mode_ns.class_("SafeModeTrigger", automation.Trigger.template()) +MarkSuccessfulAction = safe_mode_ns.class_("MarkSuccessfulAction", automation.Action) def _remove_id_if_disabled(value): @@ -53,6 +54,22 @@ CONFIG_SCHEMA = cv.All( ) +@automation.register_action( + "safe_mode.mark_successful", + MarkSuccessfulAction, + cv.Schema( + { + cv.GenerateID(): cv.use_id(SafeModeComponent), + } + ), +) +async def safe_mode_mark_successful_to_code(config, action_id, template_arg, args): + parent = await cg.get_variable(config[CONF_ID]) + var = cg.new_Pvariable(action_id, template_arg) + cg.add(var.set_parent(parent)) + return var + + @coroutine_with_priority(CoroPriority.APPLICATION) async def to_code(config): if not config[CONF_DISABLED]: diff --git a/esphome/components/safe_mode/automation.h b/esphome/components/safe_mode/automation.h index 1d82ac45f1..dee02c64a0 100644 --- a/esphome/components/safe_mode/automation.h +++ b/esphome/components/safe_mode/automation.h @@ -1,20 +1,22 @@ #pragma once #include "esphome/core/defines.h" - -#ifdef USE_SAFE_MODE_CALLBACK -#include "safe_mode.h" - #include "esphome/core/automation.h" +#include "safe_mode.h" namespace esphome::safe_mode { +#ifdef USE_SAFE_MODE_CALLBACK class SafeModeTrigger final : public Trigger<> { public: explicit SafeModeTrigger(SafeModeComponent *parent) { parent->add_on_safe_mode_callback([this]() { trigger(); }); } }; +#endif // USE_SAFE_MODE_CALLBACK + +template class MarkSuccessfulAction : public Action, public Parented { + public: + void play(const Ts &...x) override { this->parent_->mark_successful(); } +}; } // namespace esphome::safe_mode - -#endif // USE_SAFE_MODE_CALLBACK diff --git a/esphome/components/safe_mode/safe_mode.cpp b/esphome/components/safe_mode/safe_mode.cpp index aa4fdb8291..fe2acd9612 100644 --- a/esphome/components/safe_mode/safe_mode.cpp +++ b/esphome/components/safe_mode/safe_mode.cpp @@ -63,18 +63,22 @@ void SafeModeComponent::dump_config() { float SafeModeComponent::get_setup_priority() const { return setup_priority::AFTER_WIFI; } +void SafeModeComponent::mark_successful() { + this->clean_rtc(); + this->boot_successful_ = true; +#if defined(USE_ESP32) && defined(USE_OTA_ROLLBACK) + // Mark OTA partition as valid to prevent rollback + esp_ota_mark_app_valid_cancel_rollback(); +#endif + // Disable loop since we no longer need to check + this->disable_loop(); +} + void SafeModeComponent::loop() { if (!this->boot_successful_ && (millis() - this->safe_mode_start_time_) > this->safe_mode_boot_is_good_after_) { // successful boot, reset counter ESP_LOGI(TAG, "Boot seems successful; resetting boot loop counter"); - this->clean_rtc(); - this->boot_successful_ = true; -#if defined(USE_ESP32) && defined(USE_OTA_ROLLBACK) - // Mark OTA partition as valid to prevent rollback - esp_ota_mark_app_valid_cancel_rollback(); -#endif - // Disable loop since we no longer need to check - this->disable_loop(); + this->mark_successful(); } } diff --git a/esphome/components/safe_mode/safe_mode.h b/esphome/components/safe_mode/safe_mode.h index 902b8c415d..1b28ea28f2 100644 --- a/esphome/components/safe_mode/safe_mode.h +++ b/esphome/components/safe_mode/safe_mode.h @@ -31,6 +31,8 @@ class SafeModeComponent final : public Component { void on_safe_shutdown() override; + void mark_successful(); + #ifdef USE_SAFE_MODE_CALLBACK void add_on_safe_mode_callback(std::function &&callback) { this->safe_mode_callback_.add(std::move(callback)); diff --git a/esphome/core/application.cpp b/esphome/core/application.cpp index c40fb0721a..2be5a6c0f5 100644 --- a/esphome/core/application.cpp +++ b/esphome/core/application.cpp @@ -273,7 +273,7 @@ void Application::process_dump_config_() { #endif } - this->components_[this->dump_config_at_]->call_dump_config(); + this->components_[this->dump_config_at_]->call_dump_config_(); this->dump_config_at_++; } diff --git a/esphome/core/component.cpp b/esphome/core/component.cpp index 49f3c590a7..8ad16e06ea 100644 --- a/esphome/core/component.cpp +++ b/esphome/core/component.cpp @@ -214,7 +214,7 @@ bool Component::cancel_retry(uint32_t id) { void Component::call_loop_() { this->loop(); } void Component::call_setup() { this->setup(); } -void Component::call_dump_config() { +void Component::call_dump_config_() { this->dump_config(); if (this->is_failed()) { // Look up error message from global vector diff --git a/esphome/core/component.h b/esphome/core/component.h index 7ea9fdf3b3..2620e8eb2a 100644 --- a/esphome/core/component.h +++ b/esphome/core/component.h @@ -291,7 +291,7 @@ class Component { void call_loop_(); virtual void call_setup(); - virtual void call_dump_config(); + void call_dump_config_(); /// Helper to set component state (clears state bits and sets new state) void set_component_state_(uint8_t state); diff --git a/tests/components/safe_mode/common-enabled.yaml b/tests/components/safe_mode/common-enabled.yaml index c24f49e6b6..43025c60db 100644 --- a/tests/components/safe_mode/common-enabled.yaml +++ b/tests/components/safe_mode/common-enabled.yaml @@ -16,3 +16,7 @@ button: switch: - platform: safe_mode name: Safe Mode Switch + +esphome: + on_boot: + - safe_mode.mark_successful