diff --git a/esphome/components/modem/__init__.py b/esphome/components/modem/__init__.py index 1cc4f4b9bf..9bd96d533a 100644 --- a/esphome/components/modem/__init__.py +++ b/esphome/components/modem/__init__.py @@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(__name__) CODEOWNERS = ["@oarcher"] DEPENDENCIES = ["esp32"] -AUTO_LOAD = ["network"] +AUTO_LOAD = ["network", "watchdog"] # following should be removed if conflicts are resolved (so we can have a wifi ap using modem) CONFLICTS_WITH = ["captive_portal", "ethernet"] diff --git a/esphome/components/modem/helpers.cpp b/esphome/components/modem/helpers.cpp index adeb905510..5a83261290 100644 --- a/esphome/components/modem/helpers.cpp +++ b/esphome/components/modem/helpers.cpp @@ -12,31 +12,6 @@ namespace esphome { namespace modem { -Watchdog::Watchdog(u_int32_t timeout_s) { - this->timeout_s_ = timeout_s; - this->start_time_ms_ = millis(); - this->set_wdt_(timeout_s); - ESP_LOGV(TAG, "Watchog timeout init: %" PRIu32 "s", timeout_s); -} - -Watchdog::~Watchdog() { - this->set_wdt_(CONFIG_TASK_WDT_TIMEOUT_S); - ESP_LOGV(TAG, "Watchog timeout reset to default after %.1fs", float(millis() - this->start_time_ms_) / 1000); -} - -void Watchdog::set_wdt_(uint32_t timeout_s) { -#if ESP_IDF_VERSION_MAJOR >= 5 - esp_task_wdt_config_t wdt_config = { - .timeout_ms = timeout_s * 1000, - .idle_core_mask = 0x03, - .trigger_panic = true, - }; - esp_task_wdt_reconfigure(&wdt_config); -#else - esp_task_wdt_init(timeout_s, true); -#endif // ESP_IDF_VERSION_MAJOR -} - std::string command_result_to_string(command_result err) { std::string res = "UNKNOWN"; switch (err) { diff --git a/esphome/components/modem/helpers.h b/esphome/components/modem/helpers.h index 3947e1eedd..92b9b718f5 100644 --- a/esphome/components/modem/helpers.h +++ b/esphome/components/modem/helpers.h @@ -13,21 +13,6 @@ std::string command_result_to_string(command_result err); std::string state_to_string(ModemComponentState state); -// While instanciated, will set the WDT to timeout_s -// When deleted, will restore default WDT -class Watchdog { - public: - Watchdog(u_int32_t timeout_s); - - ~Watchdog(); - - private: - uint32_t timeout_s_; - uint64_t start_time_ms_; - - void set_wdt_(uint32_t timeout_s); -}; - } // namespace modem } // namespace esphome #endif // USE_ESP_IDF diff --git a/esphome/components/modem/modem_component.cpp b/esphome/components/modem/modem_component.cpp index a84f122a72..2712916d65 100644 --- a/esphome/components/modem/modem_component.cpp +++ b/esphome/components/modem/modem_component.cpp @@ -6,6 +6,7 @@ #include "esphome/core/application.h" #include "esphome/core/defines.h" #include "esphome/components/network/util.h" +#include "esphome/components/watchdog/watchdog.h" #include #include @@ -128,12 +129,14 @@ void ModemComponent::setup() { this->create_dte_dce_(); + watchdog::WatchdogManager wdt(60000); + if (this->enabled_ && !this->get_power_status()) { ESP_LOGI(TAG, "Powering up modem"); this->poweron_(); } - + App.feed_wdt(); ESP_LOGV(TAG, "Setup finished"); } @@ -185,7 +188,7 @@ void ModemComponent::create_dte_dce_() { // Try to exit CMUX_MANUAL_DATA or DATA_MODE, if any // No error check done. It can take some times if the commands fail // but this allow to recover from a previous session. - Watchdog wdt(60); + watchdog::WatchdogManager wdt(60000); if (this->cmux_) { this->dce->set_mode(modem_mode::CMUX_MANUAL_MODE); this->dce->set_mode(modem_mode::CMUX_MANUAL_COMMAND); @@ -193,6 +196,7 @@ void ModemComponent::create_dte_dce_() { this->dce->set_mode(modem_mode::COMMAND_MODE); } + // App.feed_wdt(); if (this->modem_ready()) { ESP_LOGD(TAG, "modem ready after exiting cmux/data mode"); } else { @@ -200,6 +204,7 @@ void ModemComponent::create_dte_dce_() { // we can be sure of the cause. ESP_LOGD(TAG, "modem *not* ready after exiting cmux/data mode"); } + ESP_LOGV(TAG, "DTE and CDE created"); } bool ModemComponent::prepare_sim_() { @@ -233,7 +238,7 @@ bool ModemComponent::prepare_sim_() { void ModemComponent::send_init_at_() { // send initial AT commands from yaml - Watchdog wdt(60); + watchdog::WatchdogManager wdt(60000); for (const auto &cmd : this->init_at_commands_) { std::string result = this->send_at(cmd); if (result == "ERROR") { @@ -241,11 +246,12 @@ void ModemComponent::send_init_at_() { } else { ESP_LOGI(TAG, "'init_at' '%s' result: %s", cmd.c_str(), result.c_str()); } + yield(); } } void ModemComponent::start_connect_() { - Watchdog wdt(60); + watchdog::WatchdogManager wdt(60000); this->connect_begin_ = millis(); this->status_set_warning("Starting connection"); @@ -299,6 +305,7 @@ void ModemComponent::loop() { if (this->power_transition_) { // No loop on power transition + yield(); return; } @@ -307,7 +314,7 @@ void ModemComponent::loop() { switch (this->state_) { case ModemComponentState::NOT_RESPONDING: if (this->start_) { - Watchdog wdt(60); + watchdog::WatchdogManager wdt(60000); if (this->modem_ready()) { ESP_LOGI(TAG, "Modem recovered"); this->status_clear_warning(); @@ -332,7 +339,7 @@ void ModemComponent::loop() { case ModemComponentState::DISCONNECTED: if (this->enabled_) { if (this->start_) { - Watchdog wdt(60); + watchdog::WatchdogManager wdt(60000); if (this->modem_ready()) { this->send_init_at_(); if (this->prepare_sim_()) { @@ -384,7 +391,7 @@ void ModemComponent::loop() { case ModemComponentState::DISCONNECTING: if (this->start_) { if (this->connected_) { - Watchdog wdt(60); + watchdog::WatchdogManager wdt(60000); ESP_LOGD(TAG, "Going to hang up..."); this->dump_connect_params_(); if (this->cmux_) { @@ -471,7 +478,7 @@ bool ModemComponent::get_power_status() { void ModemComponent::poweron_() { #ifdef USE_MODEM_POWER if (this->power_pin_) { - Watchdog wdt(60); + App.feed_wdt(); ESP_LOGV(TAG, "Powering up modem with power_pin..."); this->power_transition_ = true; this->power_pin_->digital_write(false); @@ -480,7 +487,7 @@ void ModemComponent::poweron_() { // use a timout for long wait delay ESP_LOGD(TAG, "Will check that the modem is on in %.1fs...", float(USE_MODEM_POWER_TONUART) / 1000); this->set_timeout("wait_poweron", USE_MODEM_POWER_TONUART, [this]() { - Watchdog wdt(60); + watchdog::WatchdogManager wdt(60000); this->create_dte_dce_(); delay(500); // NOLINT if (!this->modem_ready()) { @@ -491,6 +498,12 @@ void ModemComponent::poweron_() { this->power_transition_ = false; }); } +#else + if (this->modem_ready()) { + ESP_LOGV(TAG, "Modem is already ON"); + } else { + ESP_LOGW(TAG, "No 'power_pin' defined: Not able to poweron the modem"); + } #endif // USE_MODEM_POWER } @@ -499,7 +512,7 @@ void ModemComponent::poweroff_() { if (this->power_pin_) { ESP_LOGV(TAG, "Powering off modem with power pin..."); this->power_transition_ = true; - Watchdog wdt(60); + watchdog::WatchdogManager wdt(60000); this->power_pin_->digital_write(true); delay(10); this->power_pin_->digital_write(false); @@ -508,7 +521,7 @@ void ModemComponent::poweroff_() { ESP_LOGD(TAG, "Will check that the modem is off in %.1fs...", float(USE_MODEM_POWER_TOFFUART) / 1000); this->set_timeout("wait_poweroff", USE_MODEM_POWER_TOFFUART, [this]() { - Watchdog wdt(60); + watchdog::WatchdogManager wdt(60000); if (this->modem_ready()) { ESP_LOGE(TAG, "Unable to power off the modem");