mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	use define for to_code + more conf validation
This commit is contained in:
		| @@ -31,6 +31,14 @@ CONF_POWER_PIN = "power_pin" | |||||||
| CONF_INIT_AT = "init_at" | CONF_INIT_AT = "init_at" | ||||||
| CONF_ON_NOT_RESPONDING = "on_not_responding" | CONF_ON_NOT_RESPONDING = "on_not_responding" | ||||||
|  |  | ||||||
|  | MODEM_MODELS = ["BG96", "SIM800", "SIM7000", "SIM7600", "GENERIC"] | ||||||
|  | MODEM_MODELS_POWER = { | ||||||
|  |     "BG96": {"ton": 600, "tonuart": 4900, "toff": 650, "toffuart": 2000}, | ||||||
|  |     "SIM800": {"ton": 1300, "tonuart": 3000, "toff": 200, "toffuart": 3000}, | ||||||
|  |     "SIM7000": {"ton": 1100, "tonuart": 4500, "toff": 1300, "toffuart": 1800}, | ||||||
|  |     "SIM7600": {"ton": 500, "tonuart": 12000, "toff": 2800, "toffuart": 25000}, | ||||||
|  | } | ||||||
|  |  | ||||||
| modem_ns = cg.esphome_ns.namespace("modem") | modem_ns = cg.esphome_ns.namespace("modem") | ||||||
| ModemComponent = modem_ns.class_("ModemComponent", cg.Component) | ModemComponent = modem_ns.class_("ModemComponent", cg.Component) | ||||||
| ModemComponentState = modem_ns.enum("ModemComponentState") | ModemComponentState = modem_ns.enum("ModemComponentState") | ||||||
| @@ -51,7 +59,7 @@ CONFIG_SCHEMA = cv.All( | |||||||
|             cv.GenerateID(): cv.declare_id(ModemComponent), |             cv.GenerateID(): cv.declare_id(ModemComponent), | ||||||
|             cv.Required(CONF_TX_PIN): pins.internal_gpio_output_pin_schema, |             cv.Required(CONF_TX_PIN): pins.internal_gpio_output_pin_schema, | ||||||
|             cv.Required(CONF_RX_PIN): pins.internal_gpio_output_pin_schema, |             cv.Required(CONF_RX_PIN): pins.internal_gpio_output_pin_schema, | ||||||
|             cv.Required(CONF_MODEL): cv.string, |             cv.Required(CONF_MODEL): cv.one_of(*MODEM_MODELS, upper=True), | ||||||
|             cv.Required(CONF_APN): cv.string, |             cv.Required(CONF_APN): cv.string, | ||||||
|             cv.Optional(CONF_STATUS_PIN): pins.internal_gpio_input_pin_schema, |             cv.Optional(CONF_STATUS_PIN): pins.internal_gpio_input_pin_schema, | ||||||
|             cv.Optional(CONF_POWER_PIN): pins.internal_gpio_output_pin_schema, |             cv.Optional(CONF_POWER_PIN): pins.internal_gpio_output_pin_schema, | ||||||
| @@ -87,6 +95,21 @@ CONFIG_SCHEMA = cv.All( | |||||||
| ) | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _final_validate(config): | ||||||
|  |     if config.get(CONF_POWER_PIN, None) and not config.get(CONF_STATUS_PIN, None): | ||||||
|  |         raise cv.Invalid( | ||||||
|  |             f"'{CONF_STATUS_PIN}' must be declared if using '{CONF_POWER_PIN}'" | ||||||
|  |         ) | ||||||
|  |     if config.get(CONF_POWER_PIN, None): | ||||||
|  |         if config[CONF_MODEL] not in MODEM_MODELS_POWER: | ||||||
|  |             raise cv.Invalid( | ||||||
|  |                 f"Modem model '{config[CONF_MODEL]}' has no power power specs." | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | FINAL_VALIDATE_SCHEMA = _final_validate | ||||||
|  |  | ||||||
|  |  | ||||||
| @coroutine_with_priority(60.0) | @coroutine_with_priority(60.0) | ||||||
| async def to_code(config): | async def to_code(config): | ||||||
|     add_idf_component( |     add_idf_component( | ||||||
| @@ -135,7 +158,15 @@ async def to_code(config): | |||||||
|         for cmd in init_at: |         for cmd in init_at: | ||||||
|             cg.add(var.add_init_at_command(cmd)) |             cg.add(var.add_init_at_command(cmd)) | ||||||
|  |  | ||||||
|     cg.add(var.set_model(config[CONF_MODEL])) |     modem_model = config[CONF_MODEL] | ||||||
|  |     cg.add_define("USE_MODEM_MODEL", modem_model) | ||||||
|  |     cg.add_define(f"USE_MODEM_MODEL_{modem_model}") | ||||||
|  |  | ||||||
|  |     if power_spec := MODEM_MODELS_POWER.get(modem_model, None): | ||||||
|  |         cg.add_define("USE_MODEM_POWER") | ||||||
|  |         for spec, value in power_spec.items(): | ||||||
|  |             cg.add_define(f"USE_MODEM_POWER_{spec.upper()}", value) | ||||||
|  |  | ||||||
|     cg.add(var.set_apn(config[CONF_APN])) |     cg.add(var.set_apn(config[CONF_APN])) | ||||||
|  |  | ||||||
|     tx_pin = await cg.gpio_pin_expression(config[CONF_TX_PIN]) |     tx_pin = await cg.gpio_pin_expression(config[CONF_TX_PIN]) | ||||||
| @@ -147,6 +178,7 @@ async def to_code(config): | |||||||
|     if status_pin := config.get(CONF_STATUS_PIN, None): |     if status_pin := config.get(CONF_STATUS_PIN, None): | ||||||
|         pin = await cg.gpio_pin_expression(status_pin) |         pin = await cg.gpio_pin_expression(status_pin) | ||||||
|         cg.add(var.set_status_pin(pin)) |         cg.add(var.set_status_pin(pin)) | ||||||
|  |         cg.add_define("USE_MODEM_STATUS") | ||||||
|  |  | ||||||
|     if power_pin := config.get(CONF_POWER_PIN, None): |     if power_pin := config.get(CONF_POWER_PIN, None): | ||||||
|         pin = await cg.gpio_pin_expression(power_pin) |         pin = await cg.gpio_pin_expression(power_pin) | ||||||
|   | |||||||
| @@ -50,7 +50,22 @@ ModemComponent::ModemComponent() { | |||||||
|   global_modem_component = this; |   global_modem_component = this; | ||||||
| } | } | ||||||
|  |  | ||||||
| void ModemComponent::dump_config() { ESP_LOGCONFIG(TAG, "Config Modem:"); } | void ModemComponent::dump_config() { | ||||||
|  |   ESP_LOGCONFIG(TAG, "Config Modem:"); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Model     : %s", USE_MODEM_MODEL); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  APN       : %s", this->apn_.c_str()); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  PIN code  : %s", (this->pin_code_.empty()) ? "No" : "Yes (not shown)"); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Tx Pin    : GPIO%u", this->tx_pin_->get_pin()); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Rx Pin    : GPIO%u", this->rx_pin_->get_pin()); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Power pin : %s", | ||||||
|  |                 (this->power_pin_) ? ("GPIO" + std::to_string(this->power_pin_->get_pin())).c_str() : "Not defined"); | ||||||
|  |   if (this->status_pin_) { | ||||||
|  |     std::string current_status = this->get_power_status() ? "ON" : "OFF"; | ||||||
|  |     ESP_LOGCONFIG(TAG, "  Status pin: GPIO%u (current state %s)", this->status_pin_->get_pin(), current_status.c_str()); | ||||||
|  |   } else { | ||||||
|  |     ESP_LOGCONFIG(TAG, "  Status pin: Not defined"); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| float ModemComponent::get_setup_priority() const { return setup_priority::WIFI; } | float ModemComponent::get_setup_priority() const { return setup_priority::WIFI; } | ||||||
|  |  | ||||||
| @@ -153,33 +168,21 @@ void ModemComponent::reset_() { | |||||||
|  |  | ||||||
|   this->dte_ = create_uart_dte(&this->dte_config_); |   this->dte_ = create_uart_dte(&this->dte_config_); | ||||||
|  |  | ||||||
|   assert(this->dte_); |  | ||||||
|  |  | ||||||
|   ESP_LOGV(TAG, "DCE setup"); |   ESP_LOGV(TAG, "DCE setup"); | ||||||
|  |  | ||||||
|   // NOLINTBEGIN(bugprone-branch-clone) | #if defined(USE_MODEM_MODEL_GENERIC) | ||||||
|   // ( because create_modem_dce(dce_factory::ModemType, config, std::move(dte), netif) is private ) |   this->dce = create_generic_dce(&this->dce_config_, this->dte_, this->ppp_netif_); | ||||||
|   switch (this->model_) { | #elif defined(USE_MODEM_MODEL_BG96) | ||||||
|     case ModemModel::BG96: |  | ||||||
|   this->dce = create_BG96_dce(&this->dce_config_, this->dte_, this->ppp_netif_); |   this->dce = create_BG96_dce(&this->dce_config_, this->dte_, this->ppp_netif_); | ||||||
|       break; | #elif defined(USE_MODEM_MODEL_SIM800) | ||||||
|     case ModemModel::SIM800: |  | ||||||
|   this->dce = create_SIM800_dce(&this->dce_config_, this->dte_, this->ppp_netif_); |   this->dce = create_SIM800_dce(&this->dce_config_, this->dte_, this->ppp_netif_); | ||||||
|       break; | #elif defined(USE_MODEM_MODEL_SIM7000) | ||||||
|     case ModemModel::SIM7000: |  | ||||||
|   this->dce = create_SIM7000_dce(&this->dce_config_, this->dte_, this->ppp_netif_); |   this->dce = create_SIM7000_dce(&this->dce_config_, this->dte_, this->ppp_netif_); | ||||||
|       break; | #elif defined(USE_MODEM_MODEL_SIM7600) | ||||||
|     case ModemModel::SIM7600: |  | ||||||
|   this->dce = create_SIM7600_dce(&this->dce_config_, this->dte_, this->ppp_netif_); |   this->dce = create_SIM7600_dce(&this->dce_config_, this->dte_, this->ppp_netif_); | ||||||
|       break; | #else | ||||||
|     default: | #error Modem model not known | ||||||
|       ESP_LOGE(TAG, "Unknown modem model"); | #endif | ||||||
|       return; |  | ||||||
|       break; |  | ||||||
|   } |  | ||||||
|   // NOLINTEND(bugprone-branch-clone) |  | ||||||
|  |  | ||||||
|   assert(this->dce); |  | ||||||
|  |  | ||||||
|   // flow control not fully implemented, but kept here for future work |   // flow control not fully implemented, but kept here for future work | ||||||
|   if (this->dte_config_.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { |   if (this->dte_config_.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { | ||||||
| @@ -346,6 +349,7 @@ void ModemComponent::loop() { | |||||||
|         this->state_ = ModemComponentState::DISCONNECTED; |         this->state_ = ModemComponentState::DISCONNECTED; | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     case ModemComponentState::CONNECTED: |     case ModemComponentState::CONNECTED: | ||||||
|       if (!this->start_) { |       if (!this->start_) { | ||||||
|         this->state_ = ModemComponentState::DISCONNECTED; |         this->state_ = ModemComponentState::DISCONNECTED; | ||||||
| @@ -363,7 +367,7 @@ void ModemComponent::loop() { | |||||||
|           if (!this->modem_ready()) { |           if (!this->modem_ready()) { | ||||||
|             ESP_LOGE(TAG, "modem not ready after hang up"); |             ESP_LOGE(TAG, "modem not ready after hang up"); | ||||||
|           } |           } | ||||||
|           this->set_timeout("wait_lost_ip", 60000, [this]() { |           this->set_timeout("wait_lost_ip", 15000, [this]() { | ||||||
|             // often reached on 7600, but not reached on 7670 |             // often reached on 7600, but not reached on 7670 | ||||||
|             ESP_LOGW(TAG, "No lost ip event received. Forcing disconnect state"); |             ESP_LOGW(TAG, "No lost ip event received. Forcing disconnect state"); | ||||||
|  |  | ||||||
| @@ -442,10 +446,7 @@ void ModemComponent::exit_cmux_() { | |||||||
| } | } | ||||||
|  |  | ||||||
| bool ModemComponent::get_power_status() { | bool ModemComponent::get_power_status() { | ||||||
|   if (!this->status_pin_) { | #ifdef USE_MODEM_STATUS | ||||||
|     ESP_LOGV(TAG, "No status pin, assuming the modem is ON"); |  | ||||||
|     return true; |  | ||||||
|   } |  | ||||||
|   bool init_status = this->status_pin_->digital_read(); |   bool init_status = this->status_pin_->digital_read(); | ||||||
|   // The status pin might be floating when supposed to be low, at least on lilygo tsim7600 |   // The status pin might be floating when supposed to be low, at least on lilygo tsim7600 | ||||||
|   // as GPIO34 doesn't support pullup, we have to debounce it manually |   // as GPIO34 doesn't support pullup, we have to debounce it manually | ||||||
| @@ -458,21 +459,25 @@ bool ModemComponent::get_power_status() { | |||||||
|     // ESP_LOGV(TAG, "Floating status pin detected for state %d", final_status); |     // ESP_LOGV(TAG, "Floating status pin detected for state %d", final_status); | ||||||
|   } |   } | ||||||
|   return final_status; |   return final_status; | ||||||
|  | #else | ||||||
|  |   // No status pin, assuming the modem is ON | ||||||
|  |   return true; | ||||||
|  | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| void ModemComponent::poweron_() { | void ModemComponent::poweron_() { | ||||||
|  | #ifdef USE_MODEM_POWER | ||||||
|   if (this->power_pin_) { |   if (this->power_pin_) { | ||||||
|     Watchdog wdt(60); |     Watchdog wdt(60); | ||||||
|     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); | ||||||
|     // min 100 for SIM7600, but min 1200 for SIM800.  min BG96: 650 |     // min 100 for SIM7600, but min 1200 for SIM800.  min BG96: 650 | ||||||
|     delay(this->modem_model_ton_[this->model_]);  // NOLINT |     delay(USE_MODEM_POWER_TON); | ||||||
|     this->power_pin_->digital_write(true); |     this->power_pin_->digital_write(true); | ||||||
|     // use a timout for long wait delay |     // use a timout for long wait delay | ||||||
|     uint32_t tonuart = this->modem_model_tonuart_[this->model_]; |     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(tonuart) / 1000); |     this->set_timeout("wait_poweron", USE_MODEM_POWER_TONUART, [this]() { | ||||||
|     this->set_timeout("wait_poweron", tonuart, [this]() { |  | ||||||
|       Watchdog wdt(60); |       Watchdog wdt(60); | ||||||
|       while (!this->get_power_status()) { |       while (!this->get_power_status()) { | ||||||
|         delay(this->command_delay_); |         delay(this->command_delay_); | ||||||
| @@ -487,9 +492,11 @@ void ModemComponent::poweron_() { | |||||||
|       this->power_transition_ = false; |       this->power_transition_ = false; | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  | #endif  // USE_MODEM_POWER | ||||||
| } | } | ||||||
|  |  | ||||||
| void ModemComponent::poweroff_() { | void ModemComponent::poweroff_() { | ||||||
|  | #ifdef USE_MODEM_POWER | ||||||
|   if (this->get_power_status()) { |   if (this->get_power_status()) { | ||||||
|     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..."); | ||||||
| @@ -498,12 +505,11 @@ void ModemComponent::poweroff_() { | |||||||
|       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); | ||||||
|       delay(this->modem_model_toff_[this->model_]); |       delay(USE_MODEM_POWER_TOFF); | ||||||
|       this->power_pin_->digital_write(true); |       this->power_pin_->digital_write(true); | ||||||
|  |  | ||||||
|       uint32_t toffuart = this->modem_model_toffuart_[this->model_]; |       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(toffuart) / 1000); |       this->set_timeout("wait_poweron", USE_MODEM_POWER_TOFFUART, [this]() { | ||||||
|       this->set_timeout("wait_poweron", toffuart, [this]() { |  | ||||||
|         Watchdog wdt(60); |         Watchdog wdt(60); | ||||||
|  |  | ||||||
|         while (this->get_power_status()) { |         while (this->get_power_status()) { | ||||||
| @@ -513,10 +519,8 @@ void ModemComponent::poweroff_() { | |||||||
|         this->power_transition_ = false; |         this->power_transition_ = false; | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|   } else { |  | ||||||
|     ESP_LOGD(TAG, "Modem poweroff with AT command"); |  | ||||||
|     this->dce->power_down(); |  | ||||||
|   } |   } | ||||||
|  | #endif  // USE_MODEM_POWER | ||||||
| } | } | ||||||
|  |  | ||||||
| void ModemComponent::dump_connect_params_() { | void ModemComponent::dump_connect_params_() { | ||||||
|   | |||||||
| @@ -40,8 +40,6 @@ enum class ModemComponentState { | |||||||
|   DISABLED, |   DISABLED, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum class ModemModel { BG96, SIM800, SIM7000, SIM7070, SIM7600, UNKNOWN }; |  | ||||||
|  |  | ||||||
| class ModemComponent : public Component { | class ModemComponent : public Component { | ||||||
|  public: |  public: | ||||||
|   ModemComponent(); |   ModemComponent(); | ||||||
| @@ -62,9 +60,6 @@ class ModemComponent : public Component { | |||||||
|   void set_password(const std::string &password) { this->password_ = password; } |   void set_password(const std::string &password) { this->password_ = password; } | ||||||
|   void set_pin_code(const std::string &pin_code) { this->pin_code_ = pin_code; } |   void set_pin_code(const std::string &pin_code) { this->pin_code_ = pin_code; } | ||||||
|   void set_apn(const std::string &apn) { this->apn_ = apn; } |   void set_apn(const std::string &apn) { this->apn_ = apn; } | ||||||
|   void set_model(const std::string &model) { |  | ||||||
|     this->model_ = this->modem_model_map_.count(model) ? modem_model_map_[model] : ModemModel::UNKNOWN; |  | ||||||
|   } |  | ||||||
|   void set_not_responding_cb(Trigger<> *not_responding_cb) { this->not_responding_cb_ = not_responding_cb; } |   void set_not_responding_cb(Trigger<> *not_responding_cb) { this->not_responding_cb_ = not_responding_cb; } | ||||||
|   void add_init_at_command(const std::string &cmd) { this->init_at_commands_.push_back(cmd); } |   void add_init_at_command(const std::string &cmd) { this->init_at_commands_.push_back(cmd); } | ||||||
|   std::string send_at(const std::string &cmd); |   std::string send_at(const std::string &cmd); | ||||||
| @@ -95,12 +90,6 @@ class ModemComponent : public Component { | |||||||
|   std::string password_; |   std::string password_; | ||||||
|   std::string apn_; |   std::string apn_; | ||||||
|   std::vector<std::string> init_at_commands_; |   std::vector<std::string> init_at_commands_; | ||||||
|   ModemModel model_; |  | ||||||
|   std::unordered_map<std::string, ModemModel> modem_model_map_ = {{"BG96", ModemModel::BG96}, |  | ||||||
|                                                                   {"SIM800", ModemModel::SIM800}, |  | ||||||
|                                                                   {"SIM7000", ModemModel::SIM7000}, |  | ||||||
|                                                                   {"SIM7070", ModemModel::SIM7070}, |  | ||||||
|                                                                   {"SIM7600", ModemModel::SIM7600}}; |  | ||||||
|   std::shared_ptr<DTE> dte_{nullptr}; |   std::shared_ptr<DTE> dte_{nullptr}; | ||||||
|   esp_netif_t *ppp_netif_{nullptr}; |   esp_netif_t *ppp_netif_{nullptr}; | ||||||
|   esp_modem_dte_config_t dte_config_; |   esp_modem_dte_config_t dte_config_; | ||||||
| @@ -117,31 +106,6 @@ class ModemComponent : public Component { | |||||||
|   uint32_t command_delay_ = 500; |   uint32_t command_delay_ = 500; | ||||||
|   // Will be true when power transitionning |   // Will be true when power transitionning | ||||||
|   bool power_transition_ = false; |   bool power_transition_ = false; | ||||||
|   // time needed for power_pin to be low for poweron |  | ||||||
|   std::unordered_map<ModemModel, uint32_t> modem_model_ton_ = {{ModemModel::BG96, 600}, |  | ||||||
|                                                                {ModemModel::SIM800, 1300}, |  | ||||||
|                                                                {ModemModel::SIM7000, 1100}, |  | ||||||
|                                                                {ModemModel::SIM7070, 1100}, |  | ||||||
|                                                                {ModemModel::SIM7600, 500}}; |  | ||||||
|   // time to wait after poweron for uart to be ready |  | ||||||
|   std::unordered_map<ModemModel, uint32_t> modem_model_tonuart_ = {{ModemModel::BG96, 4900}, |  | ||||||
|                                                                    {ModemModel::SIM800, 3000}, |  | ||||||
|                                                                    {ModemModel::SIM7000, 4500}, |  | ||||||
|                                                                    {ModemModel::SIM7070, 2500}, |  | ||||||
|                                                                    {ModemModel::SIM7600, 12000}}; |  | ||||||
|   // time needed for power_pin to be high for poweroff |  | ||||||
|   std::unordered_map<ModemModel, uint32_t> modem_model_toff_ = {{ModemModel::BG96, 650}, |  | ||||||
|                                                                 {ModemModel::SIM800, 200}, |  | ||||||
|                                                                 {ModemModel::SIM7000, 1300}, |  | ||||||
|                                                                 {ModemModel::SIM7070, 1300}, |  | ||||||
|                                                                 {ModemModel::SIM7600, 2800}}; |  | ||||||
|   // time to wait after for poweroff for uart to be really closed |  | ||||||
|   std::unordered_map<ModemModel, uint32_t> modem_model_toffuart_ = {{ModemModel::BG96, 2000}, |  | ||||||
|                                                                     {ModemModel::SIM800, 3000}, |  | ||||||
|                                                                     {ModemModel::SIM7000, 1800}, |  | ||||||
|                                                                     {ModemModel::SIM7070, 1800}, |  | ||||||
|                                                                     {ModemModel::SIM7600, 25000}}; |  | ||||||
|  |  | ||||||
|   // separate handler for `on_not_responding` (we want to know when it's ended) |   // separate handler for `on_not_responding` (we want to know when it's ended) | ||||||
|   Trigger<> *not_responding_cb_{nullptr}; |   Trigger<> *not_responding_cb_{nullptr}; | ||||||
|   CallbackManager<void(ModemComponentState)> on_state_callback_; |   CallbackManager<void(ModemComponentState)> on_state_callback_; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user