new state machine

This commit is contained in:
Alexandr Pyslar 2024-10-10 17:27:03 +00:00
parent deb18247ed
commit c5580bbbdb
2 changed files with 75 additions and 38 deletions

View file

@ -4,7 +4,6 @@
#include "esphome/core/util.h" #include "esphome/core/util.h"
#include "esphome/core/application.h" #include "esphome/core/application.h"
#ifdef USE_ESP32 #ifdef USE_ESP32
#include "esp_modem_c_api_types.h" #include "esp_modem_c_api_types.h"
@ -16,14 +15,16 @@
#include <lwip/dns.h> #include <lwip/dns.h>
#include "esp_event.h" #include "esp_event.h"
uint32_t time_info_print = 0; int time_info_print = 0;
uint32_t time_hard_reset_modem = 0; int time_hard_reset_modem = 0;
uint32_t time_check_rssi = 0; int time_check_rssi = 0;
uint32_t time_check_pwrkey = 0; int time_check_pwrkey = 0;
uint32_t time_check_reset = 0; int time_check_reset = 0;
uint32_t time_turn_on_reset = 0; int time_turn_on_reset = 0;
uint32_t time_turn_on_modem = 0; int time_turn_on_modem = 0;
uint32_t time_turn_off_modem = 0; int time_turn_off_modem = 0;
int last_pull_time = 0;
int time_change_state = 0;
#define TIME_TO_NEXT_HARD_RESET 30000 #define TIME_TO_NEXT_HARD_RESET 30000
#define TIME_TO_START_MODEM 9000 #define TIME_TO_START_MODEM 9000
@ -98,19 +99,22 @@ void ModemComponent::setup() {
} }
void ModemComponent::loop() { void ModemComponent::loop() {
const uint32_t now = millis(); const int now = millis();
if (!ModemComponent::check_modem_component_state_timings()) {
return;
}
switch (this->state_) { switch (this->state_) {
case ModemComponentState::STOPPED: case ModemComponentState::STOPPED:
this->turn_on_modem(); this->turn_on_modem();
break; break;
case ModemComponentState::TURNING_ON_POWER: //time_check_pwrkey case ModemComponentState::TURNING_ON_POWER: // time_check_pwrkey
this->turn_on_pwrkey(); this->turn_on_pwrkey();
this->dce_init(); this->dce_init();
break; break;
case ModemComponentState::TURNING_ON_PWRKEY: case ModemComponentState::TURNING_ON_PWRKEY:
if (time_check_pwrkey + SYNCHRONIZATION_CHECK_PERIOD < now){ if (time_check_pwrkey + SYNCHRONIZATION_CHECK_PERIOD < now) {
time_check_pwrkey = now; time_check_pwrkey = now;
if (this->dce->sync() == esp_modem::command_result::OK){ if (this->dce->sync() == esp_modem::command_result::OK) {
ESP_LOGD(TAG, "sync OK TURNING_ON_PWRKEY"); ESP_LOGD(TAG, "sync OK TURNING_ON_PWRKEY");
this->turn_off_pwrkey(); this->turn_off_pwrkey();
this->state_ = ModemComponentState::REGISTRATION_IN_NETWORK; this->state_ = ModemComponentState::REGISTRATION_IN_NETWORK;
@ -120,7 +124,7 @@ void ModemComponent::loop() {
} }
break; break;
case ModemComponentState::REGISTRATION_IN_NETWORK: case ModemComponentState::REGISTRATION_IN_NETWORK:
if (time_check_rssi + TIME_CHECK_REGISTRATION_IN_NETWORK < now){ if (time_check_rssi + TIME_CHECK_REGISTRATION_IN_NETWORK < now) {
time_check_rssi = now; time_check_rssi = now;
if (get_rssi()) { if (get_rssi()) {
ESP_LOGD(TAG, "Starting modem connection"); ESP_LOGD(TAG, "Starting modem connection");
@ -139,7 +143,6 @@ void ModemComponent::loop() {
if (time_info_print < now) { if (time_info_print < now) {
// ESP_LOGI(TAG, "voltage %dV.", get_modem_voltage() / 1000); // ESP_LOGI(TAG, "voltage %dV.", get_modem_voltage() / 1000);
if (esp_netif_is_netif_up(this->modem_netif_)) { if (esp_netif_is_netif_up(this->modem_netif_)) {
ESP_LOGD(TAG, "esp_netif_is_netif_UP"); ESP_LOGD(TAG, "esp_netif_is_netif_UP");
} else { } else {
ESP_LOGD(TAG, "esp_netif_is_netif_DOWN"); ESP_LOGD(TAG, "esp_netif_is_netif_DOWN");
@ -148,12 +151,12 @@ void ModemComponent::loop() {
} }
break; break;
case ModemComponentState::TURNING_ON_RESET: case ModemComponentState::TURNING_ON_RESET:
if (time_turn_on_reset + DELAY_HOLD_RESET_PIN > now){ if (time_turn_on_reset + DELAY_HOLD_RESET_PIN > now) {
break; break;
} }
if (time_check_reset + SYNCHRONIZATION_CHECK_PERIOD < now){ if (time_check_reset + SYNCHRONIZATION_CHECK_PERIOD < now) {
time_check_reset = now; time_check_reset = now;
if (this->dce->sync() == esp_modem::command_result::OK){ if (this->dce->sync() == esp_modem::command_result::OK) {
ESP_LOGD(TAG, "sync OK TURNING_ON_RESET"); ESP_LOGD(TAG, "sync OK TURNING_ON_RESET");
this->turn_off_reset(); this->turn_off_reset();
this->state_ = ModemComponentState::REGISTRATION_IN_NETWORK; this->state_ = ModemComponentState::REGISTRATION_IN_NETWORK;
@ -163,21 +166,21 @@ void ModemComponent::loop() {
} }
break; break;
case ModemComponentState::TURNING_OFF_POWER: case ModemComponentState::TURNING_OFF_POWER:
if (time_turn_off_modem + TURN_OFF_MODEM_TIME < now) { if (time_turn_off_modem + TURN_OFF_MODEM_TIME < now) {
this->turn_on_modem(); this->turn_on_modem();
} }
break; break;
} }
} }
void ModemComponent::modem_netif_init(){ void ModemComponent::modem_netif_init() {
esp_netif_config_t netif_ppp_config = ESP_NETIF_DEFAULT_PPP(); esp_netif_config_t netif_ppp_config = ESP_NETIF_DEFAULT_PPP();
this->modem_netif_ = esp_netif_new(&netif_ppp_config); this->modem_netif_ = esp_netif_new(&netif_ppp_config);
assert(this->modem_netif_); assert(this->modem_netif_);
ESP_LOGD(TAG, "netif create succes"); ESP_LOGD(TAG, "netif create succes");
} }
void ModemComponent::dte_init(){ void ModemComponent::dte_init() {
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG(); esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
/* setup UART specific configuration based on kconfig options */ /* setup UART specific configuration based on kconfig options */
dte_config.uart_config.tx_io_num = this->tx_pin_; dte_config.uart_config.tx_io_num = this->tx_pin_;
@ -191,13 +194,25 @@ void ModemComponent::dte_init(){
this->dte = esp_modem::create_uart_dte(&dte_config); this->dte = esp_modem::create_uart_dte(&dte_config);
} }
void ModemComponent::dce_init(){ void ModemComponent::dce_init() {
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(this->apn_.c_str()); esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(this->apn_.c_str());
this->dce = esp_modem::create_SIM800_dce(&dce_config, dte, this->modem_netif_); this->dce = esp_modem::create_SIM800_dce(&dce_config, dte, this->modem_netif_);
} }
bool ModemComponent::check_modem_component_state_timings() {
const int now = millis();
ModemComponentStateTiming timing = this->modemComponentStateTimingMap[this->state_];
if (last_pull_time + timing.poll_period > now) {
last_pull_time = now;
return true;
} else if (time_change_state + timing.time_limit < now) {
return true;
}
return false;
}
void ModemComponent::turn_on_modem() { void ModemComponent::turn_on_modem() {
if (power_pin_){ if (power_pin_) {
this->power_pin_->digital_write(true); this->power_pin_->digital_write(true);
time_turn_on_modem = millis(); time_turn_on_modem = millis();
ESP_LOGD(TAG, "Modem turn on"); ESP_LOGD(TAG, "Modem turn on");
@ -218,7 +233,7 @@ void ModemComponent::turn_off_modem() {
} }
void ModemComponent::turn_on_pwrkey() { void ModemComponent::turn_on_pwrkey() {
if (pwrkey_pin_){ if (pwrkey_pin_) {
this->pwrkey_pin_->digital_write(false); this->pwrkey_pin_->digital_write(false);
ESP_LOGD(TAG, "pwrkey turn on"); ESP_LOGD(TAG, "pwrkey turn on");
this->state_ = ModemComponentState::TURNING_ON_PWRKEY; this->state_ = ModemComponentState::TURNING_ON_PWRKEY;
@ -226,7 +241,7 @@ void ModemComponent::turn_on_pwrkey() {
ESP_LOGD(TAG, "Can't turn on pwrkey pin because it is not configured, go to reset modem"); ESP_LOGD(TAG, "Can't turn on pwrkey pin because it is not configured, go to reset modem");
this->turn_on_reset(); this->turn_on_reset();
} }
//vTaskDelay(pdMS_TO_TICKS(500)); // NOLINT // vTaskDelay(pdMS_TO_TICKS(500)); // NOLINT
} }
void ModemComponent::turn_off_pwrkey() { void ModemComponent::turn_off_pwrkey() {
@ -303,7 +318,7 @@ network::IPAddress ModemComponent::get_ip_address() {
return network::IPAddress(&ip.ip); return network::IPAddress(&ip.ip);
} }
void ModemComponent::got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { void ModemComponent::got_ip_event_handler(void *arg, esp_event_base_t event_base, int event_id, void *event_data) {
ESP_LOGD(TAG, "IP event! %" PRIu32, event_id); ESP_LOGD(TAG, "IP event! %" PRIu32, event_id);
if (event_id == IP_EVENT_PPP_GOT_IP) { if (event_id == IP_EVENT_PPP_GOT_IP) {
global_modem_component->connected_ = true; global_modem_component->connected_ = true;
@ -364,8 +379,8 @@ void ModemComponent::set_pwrkey_pin(InternalGPIOPin *pwrkey_pin) { this->pwrkey_
void ModemComponent::set_type(ModemType type) { this->type_ = type; } void ModemComponent::set_type(ModemType type) { this->type_ = type; }
void ModemComponent::set_reset_pin(InternalGPIOPin *reset_pin) { this->reset_pin_ = reset_pin; } void ModemComponent::set_reset_pin(InternalGPIOPin *reset_pin) { this->reset_pin_ = reset_pin; }
void ModemComponent::set_apn(const std::string &apn) { this->apn_ = apn; } void ModemComponent::set_apn(const std::string &apn) { this->apn_ = apn; }
void ModemComponent::set_tx_pin(int tx_pin) { this->tx_pin_ = tx_pin; } void ModemComponent::set_tx_pin(uint8_t tx_pin) { this->tx_pin_ = tx_pin; }
void ModemComponent::set_rx_pin(int rx_pin) { this->rx_pin_ = rx_pin; } void ModemComponent::set_rx_pin(uint8_t rx_pin) { this->rx_pin_ = rx_pin; }
void ModemComponent::set_uart_event_task_stack_size(int uart_event_task_stack_size) { void ModemComponent::set_uart_event_task_stack_size(int uart_event_task_stack_size) {
this->uart_event_task_stack_size_ = uart_event_task_stack_size; this->uart_event_task_stack_size_ = uart_event_task_stack_size;
} }

View file

@ -6,9 +6,9 @@
#include "esphome/core/hal.h" #include "esphome/core/hal.h"
#include "esphome/components/network/ip_address.h" #include "esphome/components/network/ip_address.h"
#ifdef USE_ESP32 #ifdef USE_ESP32
#include <map>
using esphome::esp_log_printf_; using esphome::esp_log_printf_;
#include "esp_netif.h" #include "esp_netif.h"
@ -36,6 +36,13 @@ enum class ModemComponentState {
TURNING_OFF_POWER, TURNING_OFF_POWER,
}; };
struct ModemComponentStateTiming {
int time_limit;
int poll_period;
ModemComponentStateTiming() : time_limit(0), poll_period(0) {}
ModemComponentStateTiming(int time_limit, int poll_period) : time_limit(time_limit), poll_period(poll_period) {}
};
class ModemComponent : public Component { class ModemComponent : public Component {
public: public:
ModemComponent(); ModemComponent();
@ -51,8 +58,8 @@ class ModemComponent : public Component {
void set_type(ModemType type); void set_type(ModemType type);
void set_reset_pin(InternalGPIOPin *reset_pin); void set_reset_pin(InternalGPIOPin *reset_pin);
void set_apn(const std::string &apn); void set_apn(const std::string &apn);
void set_tx_pin(int tx_pin); void set_tx_pin(uint8_t tx_pin);
void set_rx_pin(int rx_pin); void set_rx_pin(uint8_t rx_pin);
void set_uart_event_task_stack_size(int uart_event_task_stack_size); void set_uart_event_task_stack_size(int uart_event_task_stack_size);
void set_uart_event_task_priority(int uart_event_task_priority); void set_uart_event_task_priority(int uart_event_task_priority);
void set_uart_event_queue_size(int uart_event_queue_size); void set_uart_event_queue_size(int uart_event_queue_size);
@ -65,11 +72,23 @@ class ModemComponent : public Component {
bool powerdown(); bool powerdown();
protected: protected:
static void got_ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); std::map<ModemComponentState, ModemComponentStateTiming> modemComponentStateTimingMap = {
{ModemComponentState::STOPPED, ModemComponentStateTiming(0, 0)},
{ModemComponentState::TURNING_ON_POWER, ModemComponentStateTiming(1000, 10000)},
{ModemComponentState::TURNING_ON_PWRKEY, ModemComponentStateTiming(1000, 5000)},
{ModemComponentState::REGISTRATION_IN_NETWORK, ModemComponentStateTiming(1000, 4000)},
{ModemComponentState::CONNECTING, ModemComponentStateTiming(1000, 4000)},
{ModemComponentState::CONNECTED, ModemComponentStateTiming(0, 0)},
{ModemComponentState::TURNING_ON_RESET, ModemComponentStateTiming(1000, 6000)},
{ModemComponentState::TURNING_OFF_POWER, ModemComponentStateTiming(0, 0)},
};
static void got_ip_event_handler(void *arg, esp_event_base_t event_base, int event_id, void *event_data);
void modem_netif_init(); void modem_netif_init();
void dte_init(); void dte_init();
void dce_init(); void dce_init();
bool check_modem_component_state_timings();
void turn_on_modem(); void turn_on_modem();
void turn_off_modem(); void turn_off_modem();
void turn_on_pwrkey(); void turn_on_pwrkey();
@ -86,8 +105,8 @@ class ModemComponent : public Component {
InternalGPIOPin *reset_pin_{nullptr}; InternalGPIOPin *reset_pin_{nullptr};
InternalGPIOPin *power_pin_{nullptr}; InternalGPIOPin *power_pin_{nullptr};
InternalGPIOPin *pwrkey_pin_{nullptr}; InternalGPIOPin *pwrkey_pin_{nullptr};
int tx_pin_{-1}; uint8_t tx_pin_{0};
int rx_pin_{-1}; uint8_t rx_pin_{0};
std::string apn_{""}; std::string apn_{""};
std::string use_address_; std::string use_address_;
int uart_event_task_stack_size_{0}; int uart_event_task_stack_size_{0};
@ -96,11 +115,14 @@ class ModemComponent : public Component {
int uart_tx_buffer_size_{0}; int uart_tx_buffer_size_{0};
int uart_rx_buffer_size_{0}; int uart_rx_buffer_size_{0};
int pull_time_{0};
int change_state_{0};
bool started_{false}; bool started_{false};
bool connected_{false}; bool connected_{false};
ModemComponentState state_{ModemComponentState::STOPPED}; ModemComponentState state_{ModemComponentState::STOPPED};
uint32_t connect_begin_; int connect_begin_;
esp_netif_t *modem_netif_{nullptr}; esp_netif_t *modem_netif_{nullptr};
// esp_eth_phy_t *phy_{nullptr}; // esp_eth_phy_t *phy_{nullptr};
}; };