diff --git a/esphome/components/modem/__init__.py b/esphome/components/modem/__init__.py index 1ff505acbb..ca61d8ba5c 100644 --- a/esphome/components/modem/__init__.py +++ b/esphome/components/modem/__init__.py @@ -24,14 +24,13 @@ CONF_PIN_CODE = "pin_code" CONF_APN = "apn" CONF_DTR_PIN = "dtr_pin" CONF_INIT_AT = "init_at" -# CONF_ON_SCRIPT = "on_script" -# CONF_OFF_SCRIPT = "off_script" CONF_ON_NOT_RESPONDING = "on_not_responding" modem_ns = cg.esphome_ns.namespace("modem") ModemComponent = modem_ns.class_("ModemComponent", cg.Component) -ModemNotRespondingTrigger = modem_ns.class_( - "ModemNotRespondingTrigger", automation.Trigger.template() +ModemState = modem_ns.enum("ModemState") +ModemOnNotRespondingTrigger = modem_ns.class_( + "ModemOnNotRespondingTrigger", automation.Trigger.template() ) @@ -52,7 +51,7 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_ON_NOT_RESPONDING): automation.validate_automation( { cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id( - ModemNotRespondingTrigger + ModemOnNotRespondingTrigger ) } ), @@ -85,6 +84,8 @@ async def to_code(config): add_idf_sdkconfig_option("CONFIG_PPP_CHAP_SUPPORT", True) add_idf_sdkconfig_option("CONFIG_LWIP_PPP_VJ_HEADER_COMPRESSION", True) add_idf_sdkconfig_option("CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT", True) + # commented because cause crash if another UART is defined in the yaml + # If enabled, it should increase the reliability and the speed of the connection (TODO: test) # add_idf_sdkconfig_option("CONFIG_UART_ISR_IN_IRAM", True) cg.add_define("USE_MODEM") diff --git a/esphome/components/modem/automation.h b/esphome/components/modem/automation.h index 12bfe6fe2a..52bd82e10d 100644 --- a/esphome/components/modem/automation.h +++ b/esphome/components/modem/automation.h @@ -9,10 +9,14 @@ namespace esphome { namespace modem { -class ModemNotRespondingTrigger : public Trigger<> { +class ModemOnNotRespondingTrigger : public Trigger<> { public: - explicit ModemNotRespondingTrigger(ModemComponent *parent) { - parent->add_on_not_responding_callback([this, parent]() { this->trigger(); }); + explicit ModemOnNotRespondingTrigger(ModemComponent *parent) { + parent->add_on_state_callback([this, parent](ModemState state) { + if (!parent->is_failed() && state == ModemState::NOT_RESPONDING) { + this->trigger(); + } + }); } }; diff --git a/esphome/components/modem/modem_component.cpp b/esphome/components/modem/modem_component.cpp index 5d7d3dc211..9bfb1a9ce1 100644 --- a/esphome/components/modem/modem_component.cpp +++ b/esphome/components/modem/modem_component.cpp @@ -269,7 +269,7 @@ void ModemComponent::loop() { ESP_LOGW(TAG, "Forcing cmux manual exit mode"); this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_EXIT); if (!this->modem_ready()) { - this->on_not_responding_callback_.call(); + this->on_state_callback_.call(ModemState::NOT_RESPONDING); } if (this->modem_ready()) { ESP_LOGI(TAG, "Modem is ready"); @@ -380,8 +380,8 @@ bool ModemComponent::modem_ready() { return this->get_imei(imei); } -void ModemComponent::add_on_not_responding_callback(std::function &&callback) { - this->on_not_responding_callback_.add(std::move(callback)); +void ModemComponent::add_on_state_callback(std::function &&callback) { + this->on_state_callback_.add(std::move(callback)); } } // namespace modem diff --git a/esphome/components/modem/modem_component.h b/esphome/components/modem/modem_component.h index d5a44fa646..b6a7433cab 100644 --- a/esphome/components/modem/modem_component.h +++ b/esphome/components/modem/modem_component.h @@ -27,12 +27,20 @@ using namespace esp_modem; static const char *const TAG = "modem"; +// used internally for loop management enum class ModemComponentState { STOPPED, CONNECTING, CONNECTED, }; +// Automation states +enum class ModemState { + NOT_RESPONDING, + CONNECTED, + DISCONNECTED, +}; + enum class ModemModel { BG96, SIM800, SIM7000, SIM7070, SIM7600, UNKNOWN }; class ModemComponent : public Component { @@ -60,7 +68,7 @@ class ModemComponent : public Component { std::string send_at(const std::string &cmd); bool get_imei(std::string &result); bool modem_ready(); - void add_on_not_responding_callback(std::function &&callback); + void add_on_state_callback(std::function &&callback); std::unique_ptr dce; protected: @@ -90,7 +98,7 @@ class ModemComponent : public Component { void dump_connect_params_(); std::string use_address_; uint32_t command_delay_ = 500; - CallbackManager on_not_responding_callback_; + CallbackManager on_state_callback_; }; // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)