use new watchdog component

This commit is contained in:
oarcher 2024-07-30 14:46:27 +02:00
parent 00aab9ce8d
commit e4d6f5e58d
4 changed files with 25 additions and 52 deletions

View file

@ -25,7 +25,7 @@ _LOGGER = logging.getLogger(__name__)
CODEOWNERS = ["@oarcher"] CODEOWNERS = ["@oarcher"]
DEPENDENCIES = ["esp32"] 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) # following should be removed if conflicts are resolved (so we can have a wifi ap using modem)
CONFLICTS_WITH = ["captive_portal", "ethernet"] CONFLICTS_WITH = ["captive_portal", "ethernet"]

View file

@ -12,31 +12,6 @@
namespace esphome { namespace esphome {
namespace modem { 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 command_result_to_string(command_result err) {
std::string res = "UNKNOWN"; std::string res = "UNKNOWN";
switch (err) { switch (err) {

View file

@ -13,21 +13,6 @@ std::string command_result_to_string(command_result err);
std::string state_to_string(ModemComponentState state); 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 modem
} // namespace esphome } // namespace esphome
#endif // USE_ESP_IDF #endif // USE_ESP_IDF

View file

@ -6,6 +6,7 @@
#include "esphome/core/application.h" #include "esphome/core/application.h"
#include "esphome/core/defines.h" #include "esphome/core/defines.h"
#include "esphome/components/network/util.h" #include "esphome/components/network/util.h"
#include "esphome/components/watchdog/watchdog.h"
#include <esp_netif.h> #include <esp_netif.h>
#include <esp_netif_ppp.h> #include <esp_netif_ppp.h>
@ -128,12 +129,14 @@ void ModemComponent::setup() {
this->create_dte_dce_(); this->create_dte_dce_();
watchdog::WatchdogManager wdt(60000);
if (this->enabled_ && !this->get_power_status()) { if (this->enabled_ && !this->get_power_status()) {
ESP_LOGI(TAG, "Powering up modem"); ESP_LOGI(TAG, "Powering up modem");
this->poweron_(); this->poweron_();
} }
App.feed_wdt();
ESP_LOGV(TAG, "Setup finished"); 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 // Try to exit CMUX_MANUAL_DATA or DATA_MODE, if any
// No error check done. It can take some times if the commands fail // No error check done. It can take some times if the commands fail
// but this allow to recover from a previous session. // but this allow to recover from a previous session.
Watchdog wdt(60); watchdog::WatchdogManager wdt(60000);
if (this->cmux_) { if (this->cmux_) {
this->dce->set_mode(modem_mode::CMUX_MANUAL_MODE); this->dce->set_mode(modem_mode::CMUX_MANUAL_MODE);
this->dce->set_mode(modem_mode::CMUX_MANUAL_COMMAND); 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); this->dce->set_mode(modem_mode::COMMAND_MODE);
} }
// App.feed_wdt();
if (this->modem_ready()) { if (this->modem_ready()) {
ESP_LOGD(TAG, "modem ready after exiting cmux/data mode"); ESP_LOGD(TAG, "modem ready after exiting cmux/data mode");
} else { } else {
@ -200,6 +204,7 @@ void ModemComponent::create_dte_dce_() {
// we can be sure of the cause. // we can be sure of the cause.
ESP_LOGD(TAG, "modem *not* ready after exiting cmux/data mode"); ESP_LOGD(TAG, "modem *not* ready after exiting cmux/data mode");
} }
ESP_LOGV(TAG, "DTE and CDE created");
} }
bool ModemComponent::prepare_sim_() { bool ModemComponent::prepare_sim_() {
@ -233,7 +238,7 @@ bool ModemComponent::prepare_sim_() {
void ModemComponent::send_init_at_() { void ModemComponent::send_init_at_() {
// send initial AT commands from yaml // send initial AT commands from yaml
Watchdog wdt(60); watchdog::WatchdogManager wdt(60000);
for (const auto &cmd : this->init_at_commands_) { for (const auto &cmd : this->init_at_commands_) {
std::string result = this->send_at(cmd); std::string result = this->send_at(cmd);
if (result == "ERROR") { if (result == "ERROR") {
@ -241,11 +246,12 @@ void ModemComponent::send_init_at_() {
} else { } else {
ESP_LOGI(TAG, "'init_at' '%s' result: %s", cmd.c_str(), result.c_str()); ESP_LOGI(TAG, "'init_at' '%s' result: %s", cmd.c_str(), result.c_str());
} }
yield();
} }
} }
void ModemComponent::start_connect_() { void ModemComponent::start_connect_() {
Watchdog wdt(60); watchdog::WatchdogManager wdt(60000);
this->connect_begin_ = millis(); this->connect_begin_ = millis();
this->status_set_warning("Starting connection"); this->status_set_warning("Starting connection");
@ -299,6 +305,7 @@ void ModemComponent::loop() {
if (this->power_transition_) { if (this->power_transition_) {
// No loop on power transition // No loop on power transition
yield();
return; return;
} }
@ -307,7 +314,7 @@ void ModemComponent::loop() {
switch (this->state_) { switch (this->state_) {
case ModemComponentState::NOT_RESPONDING: case ModemComponentState::NOT_RESPONDING:
if (this->start_) { if (this->start_) {
Watchdog wdt(60); watchdog::WatchdogManager wdt(60000);
if (this->modem_ready()) { if (this->modem_ready()) {
ESP_LOGI(TAG, "Modem recovered"); ESP_LOGI(TAG, "Modem recovered");
this->status_clear_warning(); this->status_clear_warning();
@ -332,7 +339,7 @@ void ModemComponent::loop() {
case ModemComponentState::DISCONNECTED: case ModemComponentState::DISCONNECTED:
if (this->enabled_) { if (this->enabled_) {
if (this->start_) { if (this->start_) {
Watchdog wdt(60); watchdog::WatchdogManager wdt(60000);
if (this->modem_ready()) { if (this->modem_ready()) {
this->send_init_at_(); this->send_init_at_();
if (this->prepare_sim_()) { if (this->prepare_sim_()) {
@ -384,7 +391,7 @@ void ModemComponent::loop() {
case ModemComponentState::DISCONNECTING: case ModemComponentState::DISCONNECTING:
if (this->start_) { if (this->start_) {
if (this->connected_) { if (this->connected_) {
Watchdog wdt(60); watchdog::WatchdogManager wdt(60000);
ESP_LOGD(TAG, "Going to hang up..."); ESP_LOGD(TAG, "Going to hang up...");
this->dump_connect_params_(); this->dump_connect_params_();
if (this->cmux_) { if (this->cmux_) {
@ -471,7 +478,7 @@ bool ModemComponent::get_power_status() {
void ModemComponent::poweron_() { void ModemComponent::poweron_() {
#ifdef USE_MODEM_POWER #ifdef USE_MODEM_POWER
if (this->power_pin_) { if (this->power_pin_) {
Watchdog wdt(60); App.feed_wdt();
ESP_LOGV(TAG, "Powering up modem with power_pin..."); ESP_LOGV(TAG, "Powering up modem with power_pin...");
this->power_transition_ = true; this->power_transition_ = true;
this->power_pin_->digital_write(false); this->power_pin_->digital_write(false);
@ -480,7 +487,7 @@ void ModemComponent::poweron_() {
// use a timout for long wait delay // 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); 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]() { this->set_timeout("wait_poweron", USE_MODEM_POWER_TONUART, [this]() {
Watchdog wdt(60); watchdog::WatchdogManager wdt(60000);
this->create_dte_dce_(); this->create_dte_dce_();
delay(500); // NOLINT delay(500); // NOLINT
if (!this->modem_ready()) { if (!this->modem_ready()) {
@ -491,6 +498,12 @@ void ModemComponent::poweron_() {
this->power_transition_ = false; 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 #endif // USE_MODEM_POWER
} }
@ -499,7 +512,7 @@ void ModemComponent::poweroff_() {
if (this->power_pin_) { if (this->power_pin_) {
ESP_LOGV(TAG, "Powering off modem with power pin..."); ESP_LOGV(TAG, "Powering off modem with power pin...");
this->power_transition_ = true; this->power_transition_ = true;
Watchdog wdt(60); watchdog::WatchdogManager wdt(60000);
this->power_pin_->digital_write(true); this->power_pin_->digital_write(true);
delay(10); delay(10);
this->power_pin_->digital_write(false); 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); 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]() { this->set_timeout("wait_poweroff", USE_MODEM_POWER_TOFFUART, [this]() {
Watchdog wdt(60); watchdog::WatchdogManager wdt(60000);
if (this->modem_ready()) { if (this->modem_ready()) {
ESP_LOGE(TAG, "Unable to power off the modem"); ESP_LOGE(TAG, "Unable to power off the modem");