From a30d12fb898c9d46500a130c48f0233455e04a23 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 10 Jan 2026 20:34:05 -1000 Subject: [PATCH 1/2] [safe_mode] Conditionally compile callback when on_safe_mode is configured --- esphome/components/safe_mode/__init__.py | 8 +++++--- esphome/components/safe_mode/automation.h | 5 +++++ esphome/components/safe_mode/safe_mode.cpp | 2 ++ esphome/components/safe_mode/safe_mode.h | 4 ++++ esphome/core/defines.h | 1 + 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/esphome/components/safe_mode/__init__.py b/esphome/components/safe_mode/__init__.py index 9944d71722..d1754aaad7 100644 --- a/esphome/components/safe_mode/__init__.py +++ b/esphome/components/safe_mode/__init__.py @@ -59,9 +59,11 @@ async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) - for conf in config.get(CONF_ON_SAFE_MODE, []): - trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) - await automation.build_automation(trigger, [], conf) + if on_safe_mode_config := config.get(CONF_ON_SAFE_MODE): + cg.add_define("USE_SAFE_MODE_CALLBACK") + for conf in on_safe_mode_config: + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) + await automation.build_automation(trigger, [], conf) condition = var.should_enter_safe_mode( config[CONF_NUM_ATTEMPTS], diff --git a/esphome/components/safe_mode/automation.h b/esphome/components/safe_mode/automation.h index 1ffa86a588..22395a51f2 100644 --- a/esphome/components/safe_mode/automation.h +++ b/esphome/components/safe_mode/automation.h @@ -1,4 +1,7 @@ #pragma once +#include "esphome/core/defines.h" + +#ifdef USE_SAFE_MODE_CALLBACK #include "safe_mode.h" #include "esphome/core/automation.h" @@ -15,3 +18,5 @@ class SafeModeTrigger : public Trigger<> { } // namespace safe_mode } // namespace esphome + +#endif // USE_SAFE_MODE_CALLBACK diff --git a/esphome/components/safe_mode/safe_mode.cpp b/esphome/components/safe_mode/safe_mode.cpp index c7bd8748f5..48776c7983 100644 --- a/esphome/components/safe_mode/safe_mode.cpp +++ b/esphome/components/safe_mode/safe_mode.cpp @@ -126,7 +126,9 @@ bool SafeModeComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t en ESP_LOGW(TAG, "SAFE MODE IS ACTIVE"); +#ifdef USE_SAFE_MODE_CALLBACK this->safe_mode_callback_.call(); +#endif return true; } diff --git a/esphome/components/safe_mode/safe_mode.h b/esphome/components/safe_mode/safe_mode.h index 028b7b11cb..3b6c6ab07b 100644 --- a/esphome/components/safe_mode/safe_mode.h +++ b/esphome/components/safe_mode/safe_mode.h @@ -25,9 +25,11 @@ class SafeModeComponent : public Component { void on_safe_shutdown() override; +#ifdef USE_SAFE_MODE_CALLBACK void add_on_safe_mode_callback(std::function &&callback) { this->safe_mode_callback_.add(std::move(callback)); } +#endif protected: void write_rtc_(uint32_t val); @@ -43,7 +45,9 @@ class SafeModeComponent : public Component { uint8_t safe_mode_num_attempts_{0}; // Larger objects at the end ESPPreferenceObject rtc_; +#ifdef USE_SAFE_MODE_CALLBACK CallbackManager safe_mode_callback_{}; +#endif static const uint32_t ENTER_SAFE_MODE_MAGIC = 0x5afe5afe; ///< a magic number to indicate that safe mode should be entered on next boot diff --git a/esphome/core/defines.h b/esphome/core/defines.h index ae94f6ef5f..538629a54a 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -100,6 +100,7 @@ #define USE_OUTPUT #define USE_POWER_SUPPLY #define USE_QR_CODE +#define USE_SAFE_MODE_CALLBACK #define USE_SELECT #define USE_SENSOR #define USE_STATUS_LED From ce336b7745af19667426466d0821f6f4dbbb6f59 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 10 Jan 2026 20:35:11 -1000 Subject: [PATCH 2/2] [safe_mode] Conditionally compile callback when on_safe_mode is configured --- esphome/components/safe_mode/automation.h | 6 ++---- esphome/components/safe_mode/safe_mode.cpp | 6 ++---- esphome/components/safe_mode/safe_mode.h | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/esphome/components/safe_mode/automation.h b/esphome/components/safe_mode/automation.h index 22395a51f2..952ed4da33 100644 --- a/esphome/components/safe_mode/automation.h +++ b/esphome/components/safe_mode/automation.h @@ -6,8 +6,7 @@ #include "esphome/core/automation.h" -namespace esphome { -namespace safe_mode { +namespace esphome::safe_mode { class SafeModeTrigger : public Trigger<> { public: @@ -16,7 +15,6 @@ class SafeModeTrigger : public Trigger<> { } }; -} // namespace safe_mode -} // namespace esphome +} // 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 48776c7983..ef6ebea247 100644 --- a/esphome/components/safe_mode/safe_mode.cpp +++ b/esphome/components/safe_mode/safe_mode.cpp @@ -13,8 +13,7 @@ #include #endif -namespace esphome { -namespace safe_mode { +namespace esphome::safe_mode { static const char *const TAG = "safe_mode"; @@ -159,5 +158,4 @@ void SafeModeComponent::on_safe_shutdown() { this->clean_rtc(); } -} // namespace safe_mode -} // namespace esphome +} // namespace esphome::safe_mode diff --git a/esphome/components/safe_mode/safe_mode.h b/esphome/components/safe_mode/safe_mode.h index 3b6c6ab07b..4aefd11458 100644 --- a/esphome/components/safe_mode/safe_mode.h +++ b/esphome/components/safe_mode/safe_mode.h @@ -5,8 +5,7 @@ #include "esphome/core/helpers.h" #include "esphome/core/preferences.h" -namespace esphome { -namespace safe_mode { +namespace esphome::safe_mode { /// SafeModeComponent provides a safe way to recover from repeated boot failures class SafeModeComponent : public Component { @@ -53,5 +52,4 @@ class SafeModeComponent : public Component { 0x5afe5afe; ///< a magic number to indicate that safe mode should be entered on next boot }; -} // namespace safe_mode -} // namespace esphome +} // namespace esphome::safe_mode