mirror of
https://github.com/esphome/esphome.git
synced 2025-09-30 09:02:17 +01:00
Add Safe Mode Restart Switch (#2437)
This commit is contained in:
@@ -89,7 +89,8 @@ void OTAComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, " Using Password.");
|
||||
}
|
||||
#endif
|
||||
if (this->has_safe_mode_ && this->safe_mode_rtc_value_ > 1) {
|
||||
if (this->has_safe_mode_ && this->safe_mode_rtc_value_ > 1 &&
|
||||
this->safe_mode_rtc_value_ != esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC) {
|
||||
ESP_LOGW(TAG, "Last Boot was an unhandled reset, will proceed to safe mode in %d restarts",
|
||||
this->safe_mode_num_attempts_ - this->safe_mode_rtc_value_);
|
||||
}
|
||||
@@ -401,6 +402,27 @@ bool OTAComponent::writeall_(const uint8_t *buf, size_t len) {
|
||||
float OTAComponent::get_setup_priority() const { return setup_priority::AFTER_WIFI; }
|
||||
uint16_t OTAComponent::get_port() const { return this->port_; }
|
||||
void OTAComponent::set_port(uint16_t port) { this->port_ = port; }
|
||||
|
||||
void OTAComponent::set_safe_mode_pending(const bool &pending) {
|
||||
if (!this->has_safe_mode_)
|
||||
return;
|
||||
|
||||
uint32_t current_rtc = this->read_rtc_();
|
||||
|
||||
if (pending && current_rtc != esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC) {
|
||||
ESP_LOGI(TAG, "Device will enter safe mode on next boot.");
|
||||
this->write_rtc_(esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC);
|
||||
}
|
||||
|
||||
if (!pending && current_rtc == esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC) {
|
||||
ESP_LOGI(TAG, "Safe mode pending has been cleared");
|
||||
this->clean_rtc();
|
||||
}
|
||||
}
|
||||
bool OTAComponent::get_safe_mode_pending() {
|
||||
return this->has_safe_mode_ && this->read_rtc_() == esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC;
|
||||
}
|
||||
|
||||
bool OTAComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time) {
|
||||
this->has_safe_mode_ = true;
|
||||
this->safe_mode_start_time_ = millis();
|
||||
@@ -409,12 +431,18 @@ bool OTAComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_
|
||||
this->rtc_ = global_preferences->make_preference<uint32_t>(233825507UL, false);
|
||||
this->safe_mode_rtc_value_ = this->read_rtc_();
|
||||
|
||||
ESP_LOGCONFIG(TAG, "There have been %u suspected unsuccessful boot attempts.", this->safe_mode_rtc_value_);
|
||||
bool is_manual_safe_mode = this->safe_mode_rtc_value_ == esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC;
|
||||
|
||||
if (this->safe_mode_rtc_value_ >= num_attempts) {
|
||||
if (is_manual_safe_mode)
|
||||
ESP_LOGI(TAG, "Safe mode has been entered manually");
|
||||
else
|
||||
ESP_LOGCONFIG(TAG, "There have been %u suspected unsuccessful boot attempts.", this->safe_mode_rtc_value_);
|
||||
|
||||
if (this->safe_mode_rtc_value_ >= num_attempts || is_manual_safe_mode) {
|
||||
this->clean_rtc();
|
||||
|
||||
ESP_LOGE(TAG, "Boot loop detected. Proceeding to safe mode.");
|
||||
if (!is_manual_safe_mode)
|
||||
ESP_LOGE(TAG, "Boot loop detected. Proceeding to safe mode.");
|
||||
|
||||
this->status_set_error();
|
||||
this->set_timeout(enable_time, []() {
|
||||
@@ -445,7 +473,7 @@ uint32_t OTAComponent::read_rtc_() {
|
||||
}
|
||||
void OTAComponent::clean_rtc() { this->write_rtc_(0); }
|
||||
void OTAComponent::on_safe_shutdown() {
|
||||
if (this->has_safe_mode_)
|
||||
if (this->has_safe_mode_ && this->read_rtc_() != esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC)
|
||||
this->clean_rtc();
|
||||
}
|
||||
|
||||
|
@@ -48,6 +48,10 @@ class OTAComponent : public Component {
|
||||
|
||||
bool should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time);
|
||||
|
||||
/// Set to true if the next startup will enter safe mode
|
||||
void set_safe_mode_pending(const bool &pending);
|
||||
bool get_safe_mode_pending();
|
||||
|
||||
#ifdef USE_OTA_STATE_CALLBACK
|
||||
void add_on_state_callback(std::function<void(OTAState, float, uint8_t)> &&callback);
|
||||
#endif
|
||||
@@ -89,6 +93,9 @@ class OTAComponent : public Component {
|
||||
uint8_t safe_mode_num_attempts_;
|
||||
ESPPreferenceObject rtc_;
|
||||
|
||||
static const uint32_t ENTER_SAFE_MODE_MAGIC =
|
||||
0x5afe5afe; ///< a magic number to indicate that safe mode should be entered on next boot
|
||||
|
||||
#ifdef USE_OTA_STATE_CALLBACK
|
||||
CallbackManager<void(OTAState, float, uint8_t)> state_callback_{};
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user