mirror of
https://github.com/esphome/esphome.git
synced 2024-11-23 23:48:11 +01:00
filter state cb from previous state
This commit is contained in:
parent
1b9c9e9ccb
commit
00b9e83d0e
3 changed files with 88 additions and 56 deletions
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue