mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 06:58:11 +01:00
[safe_mode] Allow user-defined interval for successful boot (#6882)
Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
This commit is contained in:
parent
562700bd2c
commit
7b60543afd
4 changed files with 21 additions and 9 deletions
|
@ -16,6 +16,7 @@ from esphome import automation
|
||||||
|
|
||||||
CODEOWNERS = ["@paulmonigatti", "@jsuanet", "@kbx81"]
|
CODEOWNERS = ["@paulmonigatti", "@jsuanet", "@kbx81"]
|
||||||
|
|
||||||
|
CONF_BOOT_IS_GOOD_AFTER = "boot_is_good_after"
|
||||||
CONF_ON_SAFE_MODE = "on_safe_mode"
|
CONF_ON_SAFE_MODE = "on_safe_mode"
|
||||||
|
|
||||||
safe_mode_ns = cg.esphome_ns.namespace("safe_mode")
|
safe_mode_ns = cg.esphome_ns.namespace("safe_mode")
|
||||||
|
@ -34,6 +35,9 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(SafeModeComponent),
|
cv.GenerateID(): cv.declare_id(SafeModeComponent),
|
||||||
|
cv.Optional(
|
||||||
|
CONF_BOOT_IS_GOOD_AFTER, default="1min"
|
||||||
|
): cv.positive_time_period_milliseconds,
|
||||||
cv.Optional(CONF_DISABLED, default=False): cv.boolean,
|
cv.Optional(CONF_DISABLED, default=False): cv.boolean,
|
||||||
cv.Optional(CONF_NUM_ATTEMPTS, default="10"): cv.positive_not_null_int,
|
cv.Optional(CONF_NUM_ATTEMPTS, default="10"): cv.positive_not_null_int,
|
||||||
cv.Optional(
|
cv.Optional(
|
||||||
|
@ -63,7 +67,9 @@ async def to_code(config):
|
||||||
await automation.build_automation(trigger, [], conf)
|
await automation.build_automation(trigger, [], conf)
|
||||||
|
|
||||||
condition = var.should_enter_safe_mode(
|
condition = var.should_enter_safe_mode(
|
||||||
config[CONF_NUM_ATTEMPTS], config[CONF_REBOOT_TIMEOUT]
|
config[CONF_NUM_ATTEMPTS],
|
||||||
|
config[CONF_REBOOT_TIMEOUT],
|
||||||
|
config[CONF_BOOT_IS_GOOD_AFTER],
|
||||||
)
|
)
|
||||||
cg.add(RawExpression(f"if ({condition}) return"))
|
cg.add(RawExpression(f"if ({condition}) return"))
|
||||||
CORE.data[CONF_SAFE_MODE] = {}
|
CORE.data[CONF_SAFE_MODE] = {}
|
||||||
|
|
|
@ -16,6 +16,8 @@ static const char *const TAG = "safe_mode";
|
||||||
|
|
||||||
void SafeModeComponent::dump_config() {
|
void SafeModeComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "Safe Mode:");
|
ESP_LOGCONFIG(TAG, "Safe Mode:");
|
||||||
|
ESP_LOGCONFIG(TAG, " Boot considered successful after %" PRIu32 " seconds",
|
||||||
|
this->safe_mode_boot_is_good_after_ / 1000); // because milliseconds
|
||||||
ESP_LOGCONFIG(TAG, " Invoke after %u boot attempts", this->safe_mode_num_attempts_);
|
ESP_LOGCONFIG(TAG, " Invoke after %u boot attempts", this->safe_mode_num_attempts_);
|
||||||
ESP_LOGCONFIG(TAG, " Remain in safe mode for %" PRIu32 " seconds",
|
ESP_LOGCONFIG(TAG, " Remain in safe mode for %" PRIu32 " seconds",
|
||||||
this->safe_mode_enable_time_ / 1000); // because milliseconds
|
this->safe_mode_enable_time_ / 1000); // because milliseconds
|
||||||
|
@ -34,7 +36,7 @@ void SafeModeComponent::dump_config() {
|
||||||
float SafeModeComponent::get_setup_priority() const { return setup_priority::AFTER_WIFI; }
|
float SafeModeComponent::get_setup_priority() const { return setup_priority::AFTER_WIFI; }
|
||||||
|
|
||||||
void SafeModeComponent::loop() {
|
void SafeModeComponent::loop() {
|
||||||
if (!this->boot_successful_ && (millis() - this->safe_mode_start_time_) > this->safe_mode_enable_time_) {
|
if (!this->boot_successful_ && (millis() - this->safe_mode_start_time_) > this->safe_mode_boot_is_good_after_) {
|
||||||
// successful boot, reset counter
|
// successful boot, reset counter
|
||||||
ESP_LOGI(TAG, "Boot seems successful; resetting boot loop counter");
|
ESP_LOGI(TAG, "Boot seems successful; resetting boot loop counter");
|
||||||
this->clean_rtc();
|
this->clean_rtc();
|
||||||
|
@ -60,9 +62,11 @@ bool SafeModeComponent::get_safe_mode_pending() {
|
||||||
return this->read_rtc_() == SafeModeComponent::ENTER_SAFE_MODE_MAGIC;
|
return this->read_rtc_() == SafeModeComponent::ENTER_SAFE_MODE_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SafeModeComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time) {
|
bool SafeModeComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time,
|
||||||
|
uint32_t boot_is_good_after) {
|
||||||
this->safe_mode_start_time_ = millis();
|
this->safe_mode_start_time_ = millis();
|
||||||
this->safe_mode_enable_time_ = enable_time;
|
this->safe_mode_enable_time_ = enable_time;
|
||||||
|
this->safe_mode_boot_is_good_after_ = boot_is_good_after;
|
||||||
this->safe_mode_num_attempts_ = num_attempts;
|
this->safe_mode_num_attempts_ = num_attempts;
|
||||||
this->rtc_ = global_preferences->make_preference<uint32_t>(233825507UL, false);
|
this->rtc_ = global_preferences->make_preference<uint32_t>(233825507UL, false);
|
||||||
this->safe_mode_rtc_value_ = this->read_rtc_();
|
this->safe_mode_rtc_value_ = this->read_rtc_();
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace safe_mode {
|
||||||
/// SafeModeComponent provides a safe way to recover from repeated boot failures
|
/// SafeModeComponent provides a safe way to recover from repeated boot failures
|
||||||
class SafeModeComponent : public Component {
|
class SafeModeComponent : public Component {
|
||||||
public:
|
public:
|
||||||
bool should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time);
|
bool should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time, uint32_t boot_is_good_after);
|
||||||
|
|
||||||
/// Set to true if the next startup will enter safe mode
|
/// Set to true if the next startup will enter safe mode
|
||||||
void set_safe_mode_pending(const bool &pending);
|
void set_safe_mode_pending(const bool &pending);
|
||||||
|
@ -33,11 +33,12 @@ class SafeModeComponent : public Component {
|
||||||
void write_rtc_(uint32_t val);
|
void write_rtc_(uint32_t val);
|
||||||
uint32_t read_rtc_();
|
uint32_t read_rtc_();
|
||||||
|
|
||||||
bool boot_successful_{false}; ///< set to true after boot is considered successful
|
bool boot_successful_{false}; ///< set to true after boot is considered successful
|
||||||
uint32_t safe_mode_start_time_; ///< stores when safe mode was enabled
|
uint32_t safe_mode_boot_is_good_after_{60000}; ///< The amount of time after which the boot is considered successful
|
||||||
uint32_t safe_mode_enable_time_{60000}; ///< The time safe mode should remain active for
|
uint32_t safe_mode_enable_time_{60000}; ///< The time safe mode should remain active for
|
||||||
uint32_t safe_mode_rtc_value_;
|
uint32_t safe_mode_rtc_value_{0};
|
||||||
uint8_t safe_mode_num_attempts_;
|
uint32_t safe_mode_start_time_{0}; ///< stores when safe mode was enabled
|
||||||
|
uint8_t safe_mode_num_attempts_{0};
|
||||||
ESPPreferenceObject rtc_;
|
ESPPreferenceObject rtc_;
|
||||||
CallbackManager<void()> safe_mode_callback_{};
|
CallbackManager<void()> safe_mode_callback_{};
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ wifi:
|
||||||
password: password1
|
password: password1
|
||||||
|
|
||||||
safe_mode:
|
safe_mode:
|
||||||
|
boot_is_good_after: 2min
|
||||||
num_attempts: 3
|
num_attempts: 3
|
||||||
reboot_timeout: 2min
|
reboot_timeout: 2min
|
||||||
on_safe_mode:
|
on_safe_mode:
|
||||||
|
|
Loading…
Reference in a new issue