mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	filter state cb from previous state
This commit is contained in:
		| @@ -21,7 +21,7 @@ class ModemOnNotRespondingTrigger : public Trigger<> { | |||||||
| class ModemOnConnectTrigger : public Trigger<> { | class ModemOnConnectTrigger : public Trigger<> { | ||||||
|  public: |  public: | ||||||
|   explicit ModemOnConnectTrigger(ModemComponent *parent) { |   explicit ModemOnConnectTrigger(ModemComponent *parent) { | ||||||
|     parent->add_on_state_callback([this, parent](ModemComponentState state) { |     parent->add_on_state_callback([this, parent](ModemComponentState old_state, ModemComponentState state) { | ||||||
|       if (!parent->is_failed() && state == ModemComponentState::CONNECTED) { |       if (!parent->is_failed() && state == ModemComponentState::CONNECTED) { | ||||||
|         this->trigger(); |         this->trigger(); | ||||||
|       } |       } | ||||||
| @@ -32,9 +32,12 @@ class ModemOnConnectTrigger : public Trigger<> { | |||||||
| class ModemOnDisconnectTrigger : public Trigger<> { | class ModemOnDisconnectTrigger : public Trigger<> { | ||||||
|  public: |  public: | ||||||
|   explicit ModemOnDisconnectTrigger(ModemComponent *parent) { |   explicit ModemOnDisconnectTrigger(ModemComponent *parent) { | ||||||
|     parent->add_on_state_callback([this, parent](ModemComponentState state) { |     parent->add_on_state_callback([this, parent](ModemComponentState old_state, ModemComponentState state) { | ||||||
|       if (!parent->is_failed() && state == ModemComponentState::DISCONNECTED) { |       if (!parent->is_failed() && state == ModemComponentState::DISCONNECTED) { | ||||||
|         this->trigger(); |         // filter useless old_state | ||||||
|  |         if (old_state == ModemComponentState::CONNECTED) { | ||||||
|  |           this->trigger(); | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ | |||||||
|  |  | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  | #include <sstream> | ||||||
|  |  | ||||||
| #ifndef USE_MODEM_MODEL | #ifndef USE_MODEM_MODEL | ||||||
| #define USE_MODEM_MODEL "GENERIC" | #define USE_MODEM_MODEL "GENERIC" | ||||||
| @@ -248,9 +249,12 @@ bool ModemComponent::modem_sync_() { | |||||||
|     if (!this->prepare_sim_()) { |     if (!this->prepare_sim_()) { | ||||||
|       // fatal error |       // fatal error | ||||||
|       this->disable(); |       this->disable(); | ||||||
|  |       status = false; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   this->modem_synced_ = status; | ||||||
|  |  | ||||||
|   return status; |   return status; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -350,8 +354,12 @@ void ModemComponent::ip_event_handler(void *arg, esp_event_base_t event_base, in | |||||||
|       global_modem_component->got_ipv4_address_ = true; |       global_modem_component->got_ipv4_address_ = true; | ||||||
|       global_modem_component->connected_ = true; |       global_modem_component->connected_ = true; | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     case IP_EVENT_PPP_LOST_IP: |     case IP_EVENT_PPP_LOST_IP: | ||||||
|       ESP_LOGD(TAG, "[IP event] Lost IP"); |       if (global_modem_component->connected_) { | ||||||
|  |         // do not log message if we are not connected | ||||||
|  |         ESP_LOGD(TAG, "[IP event] Lost IP"); | ||||||
|  |       } | ||||||
|       global_modem_component->got_ipv4_address_ = false; |       global_modem_component->got_ipv4_address_ = false; | ||||||
|       global_modem_component->connected_ = false; |       global_modem_component->connected_ = false; | ||||||
|       break; |       break; | ||||||
| @@ -395,6 +403,7 @@ void ModemComponent::loop() { | |||||||
|         } else { |         } else { | ||||||
|           ESP_LOGI(TAG, "Modem powered ON"); |           ESP_LOGI(TAG, "Modem powered ON"); | ||||||
|           this->powered_on_ = true; |           this->powered_on_ = true; | ||||||
|  |           this->modem_synced_ = false; | ||||||
|           this->watchdog_.reset(); |           this->watchdog_.reset(); | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
| @@ -415,6 +424,7 @@ void ModemComponent::loop() { | |||||||
|         } else { |         } else { | ||||||
|           ESP_LOGI(TAG, "Modem powered OFF"); |           ESP_LOGI(TAG, "Modem powered OFF"); | ||||||
|           this->powered_on_ = false; |           this->powered_on_ = false; | ||||||
|  |           this->modem_synced_ = false; | ||||||
|           this->watchdog_.reset(); |           this->watchdog_.reset(); | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
| @@ -431,7 +441,6 @@ void ModemComponent::loop() { | |||||||
|           ESP_LOGI(TAG, "Modem recovered"); |           ESP_LOGI(TAG, "Modem recovered"); | ||||||
|           this->status_clear_warning(); |           this->status_clear_warning(); | ||||||
|           this->state_ = ModemComponentState::DISCONNECTED; |           this->state_ = ModemComponentState::DISCONNECTED; | ||||||
|           last_state = this->state_;  // disable on_disconnect cb |  | ||||||
|         } else { |         } else { | ||||||
|           if (!this->powered_on_) { |           if (!this->powered_on_) { | ||||||
|             this->poweron_(); |             this->poweron_(); | ||||||
| @@ -447,44 +456,25 @@ void ModemComponent::loop() { | |||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|     // disconnected, want to connect |  | ||||||
|     case ModemComponentState::DISCONNECTED: |     case ModemComponentState::DISCONNECTED: | ||||||
|       if (this->enabled_) { |       if (this->enabled_) { | ||||||
|         if (last_state == ModemComponentState::DISABLED) { |         // be sure the modem is on and synced | ||||||
|           last_state = this->state_;  // disable on_disconnect cb |  | ||||||
|         } |  | ||||||
|         if (!this->powered_on_) { |         if (!this->powered_on_) { | ||||||
|           this->poweron_(); |           this->poweron_(); | ||||||
|           break; |           break; | ||||||
|  |         } else if (!this->modem_synced_) { | ||||||
|  |           if (!this->modem_sync_()) { | ||||||
|  |             ESP_LOGE(TAG, "Modem not responding"); | ||||||
|  |             this->state_ = ModemComponentState::NOT_RESPONDING; | ||||||
|  |           } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (this->start_) { |         if (this->start_) { | ||||||
|           if (connecting) { |           // want to connect | ||||||
|             if (this->connected_) { |           if (!connecting) { | ||||||
|               connecting = false; |             // wait for the modem be attached to a network, start ppp, and set connecting=true | ||||||
|               ESP_LOGI(TAG, "Connected via Modem"); |  | ||||||
|               this->state_ = ModemComponentState::CONNECTED; |  | ||||||
|  |  | ||||||
|               this->dump_connect_params_(); |  | ||||||
|               this->status_clear_warning(); |  | ||||||
|               this->watchdog_.reset(); |  | ||||||
|             } else if (millis() - this->connect_begin_ > 15000) { |  | ||||||
|               ESP_LOGW(TAG, "Connecting via Modem failed! Re-connecting..."); |  | ||||||
|               // TODO: exit data/cmux without error check |  | ||||||
|               connecting = false; |  | ||||||
|             } else { |  | ||||||
|               // Wait for IP from PPP event |  | ||||||
|               next_loop_millis = millis() + 1000;  // delay for next loop |  | ||||||
|             } |  | ||||||
|           } else { |  | ||||||
|             if (!this->watchdog_) |             if (!this->watchdog_) | ||||||
|               this->watchdog_ = std::make_shared<watchdog::WatchdogManager>(60000); |               this->watchdog_ = std::make_shared<watchdog::WatchdogManager>(60000); | ||||||
|             // want to start connect, make sure the modem is ready |  | ||||||
|             if (!this->modem_sync_()) { |  | ||||||
|               ESP_LOGE(TAG, "Modem not responding"); |  | ||||||
|               this->state_ = ModemComponentState::NOT_RESPONDING; |  | ||||||
|               break; |  | ||||||
|             } |  | ||||||
|             if (is_network_attached_()) { |             if (is_network_attached_()) { | ||||||
|               network_attach_retry = 10; |               network_attach_retry = 10; | ||||||
|               if (this->start_ppp_()) { |               if (this->start_ppp_()) { | ||||||
| @@ -505,6 +495,27 @@ void ModemComponent::loop() { | |||||||
|               } |               } | ||||||
|               next_loop_millis = millis() + 1000;  // delay to retry |               next_loop_millis = millis() + 1000;  // delay to retry | ||||||
|             } |             } | ||||||
|  |           } else { | ||||||
|  |             // connecting | ||||||
|  |             if (!this->connected_) { | ||||||
|  |               // wait until this->connected_ set to true by IP_EVENT_PPP_GOT_IP | ||||||
|  |               next_loop_millis = millis() + 1000;  // delay for next loop | ||||||
|  |  | ||||||
|  |               // connecting timeout | ||||||
|  |               if (millis() - this->connect_begin_ > 15000) { | ||||||
|  |                 ESP_LOGW(TAG, "Connecting via Modem failed! Re-connecting..."); | ||||||
|  |                 // TODO: exit data/cmux without error check | ||||||
|  |                 connecting = false; | ||||||
|  |               } | ||||||
|  |             } else { | ||||||
|  |               connecting = false; | ||||||
|  |               ESP_LOGI(TAG, "Connected via Modem"); | ||||||
|  |               this->state_ = ModemComponentState::CONNECTED; | ||||||
|  |  | ||||||
|  |               this->dump_connect_params_(); | ||||||
|  |               this->status_clear_warning(); | ||||||
|  |               this->watchdog_.reset(); | ||||||
|  |             } | ||||||
|           } |           } | ||||||
|         } else { |         } else { | ||||||
|           this->start_ = true; |           this->start_ = true; | ||||||
| @@ -524,6 +535,7 @@ void ModemComponent::loop() { | |||||||
|         disconnecting = false; |         disconnecting = false; | ||||||
|       } else { |       } else { | ||||||
|         if (this->connected_) { |         if (this->connected_) { | ||||||
|  |           // connected but disbled, so disconnect | ||||||
|           if (!disconnecting) { |           if (!disconnecting) { | ||||||
|             disconnecting = true; |             disconnecting = true; | ||||||
|             ip_lost_retries = 10; |             ip_lost_retries = 10; | ||||||
| @@ -541,22 +553,20 @@ void ModemComponent::loop() { | |||||||
|             if (ip_info.ip.addr == 0) { |             if (ip_info.ip.addr == 0) { | ||||||
|               // lost IP |               // lost IP | ||||||
|               esp_event_post(IP_EVENT, IP_EVENT_PPP_LOST_IP, nullptr, 0, 0); |               esp_event_post(IP_EVENT, IP_EVENT_PPP_LOST_IP, nullptr, 0, 0); | ||||||
|  |             } else { | ||||||
|  |               ESP_LOGD(TAG, "Waiting for lost IP... (retries %" PRIu8 ")", ip_lost_retries); | ||||||
|  |               ip_lost_retries--; | ||||||
|  |               if (ip_lost_retries == 0) { | ||||||
|  |                 // Something goes wrong, we have still an IP | ||||||
|  |                 ESP_LOGE(TAG, "No IP lost event recieved. Sending one manually"); | ||||||
|  |                 esp_event_post(IP_EVENT, IP_EVENT_PPP_LOST_IP, nullptr, 0, 0); | ||||||
|  |               } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             ESP_LOGD(TAG, "Waiting for lost IP... (retries %" PRIu8 ")", ip_lost_retries); |  | ||||||
|             ip_lost_retries--; |  | ||||||
|             if (ip_lost_retries == 0) { |  | ||||||
|               // Something goes wrong, we have still an IP |  | ||||||
|               ESP_LOGE(TAG, "No IP lost event recieved. Sending one manually"); |  | ||||||
|               esp_event_post(IP_EVENT, IP_EVENT_PPP_LOST_IP, nullptr, 0, 0); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             next_loop_millis = millis() + 2000;  // delay for next loop |             next_loop_millis = millis() + 2000;  // delay for next loop | ||||||
|           } |           } | ||||||
|         } else {  // if (this->connected_) |         } else {  // if (this->connected_) | ||||||
|           // ip lost as expected |           // ip lost as expected | ||||||
|           ESP_LOGI(TAG, "PPPoS disconnected"); |           ESP_LOGI(TAG, "PPPoS disconnected"); | ||||||
|           this->dump_connect_params_(); |  | ||||||
|           this->state_ = ModemComponentState::DISCONNECTED; |           this->state_ = ModemComponentState::DISCONNECTED; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @@ -565,7 +575,6 @@ void ModemComponent::loop() { | |||||||
|     case ModemComponentState::DISABLED: |     case ModemComponentState::DISABLED: | ||||||
|       if (this->enabled_) { |       if (this->enabled_) { | ||||||
|         this->state_ = ModemComponentState::DISCONNECTED; |         this->state_ = ModemComponentState::DISCONNECTED; | ||||||
|         last_state = this->state_;  // disable on_disconnect cb |  | ||||||
|         ESP_LOGE(TAG, "here"); |         ESP_LOGE(TAG, "here"); | ||||||
|       } else if (this->powered_on_) { |       } else if (this->powered_on_) { | ||||||
|         this->poweroff_(); |         this->poweroff_(); | ||||||
| @@ -577,7 +586,7 @@ void ModemComponent::loop() { | |||||||
|   if (this->state_ != last_state) { |   if (this->state_ != last_state) { | ||||||
|     ESP_LOGV(TAG, "State changed: %s -> %s", state_to_string(last_state).c_str(), |     ESP_LOGV(TAG, "State changed: %s -> %s", state_to_string(last_state).c_str(), | ||||||
|              state_to_string(this->state_).c_str()); |              state_to_string(this->state_).c_str()); | ||||||
|     this->on_state_callback_.call(this->state_); |     this->on_state_callback_.call(last_state, this->state_); | ||||||
|  |  | ||||||
|     last_state = this->state_; |     last_state = this->state_; | ||||||
|   } |   } | ||||||
| @@ -668,21 +677,39 @@ bool ModemComponent::is_network_attached_() { | |||||||
|  |  | ||||||
| void ModemComponent::dump_dce_status_() { | void ModemComponent::dump_dce_status_() { | ||||||
|   ESP_LOGCONFIG(TAG, "Modem status:"); |   ESP_LOGCONFIG(TAG, "Modem status:"); | ||||||
|   int network_attachment_state; |   command_result err; | ||||||
|   std::string result; |   std::string result; | ||||||
|   command_result err = this->dce->get_network_attachment_state(network_attachment_state); |   err = this->dce->get_module_name(result); | ||||||
|  |   if (err != command_result::OK) { | ||||||
|  |     result = "command " + command_result_to_string(err); | ||||||
|  |   } | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Module name        : %s", result.c_str()); | ||||||
|  |  | ||||||
|  |   int rssi; | ||||||
|  |   int ber; | ||||||
|  |   err = this->dce->get_signal_quality(rssi, ber); | ||||||
|  |   if (err != command_result::OK) { | ||||||
|  |     result = "command " + command_result_to_string(err); | ||||||
|  |   } else { | ||||||
|  |     float ber_f; | ||||||
|  |     if (ber != 99) { | ||||||
|  |       ber_f = float(ber); | ||||||
|  |     } else | ||||||
|  |       ber_f = {}; | ||||||
|  |     std::ostringstream oss; | ||||||
|  |     oss << "rssi " << rssi << "(" << (rssi * 100) / 31 << "%), ber " << ber << "(" << (ber_f * 100) / 7 << "%)"; | ||||||
|  |     result = oss.str(); | ||||||
|  |   } | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Signal quality     : %s", result.c_str()); | ||||||
|  |  | ||||||
|  |   int network_attachment_state; | ||||||
|  |   err = this->dce->get_network_attachment_state(network_attachment_state); | ||||||
|   if (err == command_result::OK) { |   if (err == command_result::OK) { | ||||||
|     result = network_attachment_state ? "Yes" : "No"; |     result = network_attachment_state ? "Yes" : "No"; | ||||||
|   } else { |   } else { | ||||||
|     result = "command " + command_result_to_string(err); |     result = "command " + command_result_to_string(err); | ||||||
|   } |   } | ||||||
|   ESP_LOGCONFIG(TAG, "  Attached to network: %s", result.c_str()); |   ESP_LOGCONFIG(TAG, "  Attached to network: %s", result.c_str()); | ||||||
|  |  | ||||||
|   this->dce->get_module_name(result); |  | ||||||
|   if (err != command_result::OK) { |  | ||||||
|     result = "command " + command_result_to_string(err); |  | ||||||
|   } |  | ||||||
|   ESP_LOGCONFIG(TAG, "  Module name        : %s", result.c_str()); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| std::string ModemComponent::send_at(const std::string &cmd) { | std::string ModemComponent::send_at(const std::string &cmd) { | ||||||
| @@ -733,7 +760,7 @@ bool ModemComponent::modem_ready() { | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| void ModemComponent::add_on_state_callback(std::function<void(ModemComponentState)> &&callback) { | void ModemComponent::add_on_state_callback(std::function<void(ModemComponentState, ModemComponentState)> &&callback) { | ||||||
|   this->on_state_callback_.add(std::move(callback)); |   this->on_state_callback_.add(std::move(callback)); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -76,7 +76,7 @@ class ModemComponent : public Component { | |||||||
|   bool modem_ready(); |   bool modem_ready(); | ||||||
|   void enable(); |   void enable(); | ||||||
|   void disable(); |   void disable(); | ||||||
|   void add_on_state_callback(std::function<void(ModemComponentState)> &&callback); |   void add_on_state_callback(std::function<void(ModemComponentState, ModemComponentState)> &&callback); | ||||||
|   std::unique_ptr<DCE> dce{nullptr}; |   std::unique_ptr<DCE> dce{nullptr}; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
| @@ -115,6 +115,8 @@ class ModemComponent : public Component { | |||||||
|   bool enabled_{false}; |   bool enabled_{false}; | ||||||
|   bool connected_{false}; |   bool connected_{false}; | ||||||
|   bool got_ipv4_address_{false}; |   bool got_ipv4_address_{false}; | ||||||
|  |   // true if modem_sync_ was sucessfull | ||||||
|  |   bool modem_synced_{false}; | ||||||
|   // date start (millis()) |   // date start (millis()) | ||||||
|   uint32_t connect_begin_; |   uint32_t connect_begin_; | ||||||
|   std::string use_address_; |   std::string use_address_; | ||||||
| @@ -130,7 +132,7 @@ class ModemComponent : public Component { | |||||||
| #endif  // USE_MODEM_POWER | #endif  // USE_MODEM_POWER | ||||||
|   // 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, ModemComponentState)> on_state_callback_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user