mirror of
https://github.com/esphome/esphome.git
synced 2024-11-30 18:54:14 +01:00
optionnal cmux WIP
This commit is contained in:
parent
34d5445e27
commit
90ec353d85
2 changed files with 162 additions and 128 deletions
|
@ -6,6 +6,7 @@
|
||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/defines.h"
|
#include "esphome/core/defines.h"
|
||||||
#include "esphome/components/network/util.h"
|
#include "esphome/components/network/util.h"
|
||||||
|
// #include "esphome/components/gpio/binary_sensor/gpio_binary_sensor.h"
|
||||||
|
|
||||||
#include <esp_netif.h>
|
#include <esp_netif.h>
|
||||||
#include <esp_netif_ppp.h>
|
#include <esp_netif_ppp.h>
|
||||||
|
@ -20,6 +21,10 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifndef USE_MODEM_MODEL
|
||||||
|
#define USE_MODEM_MODEL UNKNOWN
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ESPHL_ERROR_CHECK(err, message) \
|
#define ESPHL_ERROR_CHECK(err, message) \
|
||||||
if ((err) != ESP_OK) { \
|
if ((err) != ESP_OK) { \
|
||||||
ESP_LOGE(TAG, message ": (%d) %s", err, esp_err_to_name(err)); \
|
ESP_LOGE(TAG, message ": (%d) %s", err, esp_err_to_name(err)); \
|
||||||
|
@ -50,24 +55,9 @@ ModemComponent::ModemComponent() {
|
||||||
global_modem_component = this;
|
global_modem_component = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModemComponent::dump_config() {
|
void ModemComponent::dump_config() { this->dump_connect_params_(); }
|
||||||
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; } // FIXME AFTER_WIFI
|
||||||
|
|
||||||
bool ModemComponent::can_proceed() { return this->is_connected(); }
|
bool ModemComponent::can_proceed() { return this->is_connected(); }
|
||||||
|
|
||||||
|
@ -99,6 +89,30 @@ bool ModemComponent::is_connected() { return this->state_ == ModemComponentState
|
||||||
void ModemComponent::setup() {
|
void ModemComponent::setup() {
|
||||||
ESP_LOGI(TAG, "Setting up Modem...");
|
ESP_LOGI(TAG, "Setting up Modem...");
|
||||||
|
|
||||||
|
if (this->power_pin_) {
|
||||||
|
this->power_pin_->setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->status_pin_) {
|
||||||
|
this->status_pin_->setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
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_) ? this->power_pin_->dump_summary().c_str() : "Not defined");
|
||||||
|
if (this->status_pin_) {
|
||||||
|
std::string current_status = this->get_power_status() ? "ON" : "OFF";
|
||||||
|
ESP_LOGCONFIG(TAG, " Status pin: %s (current state %s)", this->status_pin_->dump_summary().c_str(),
|
||||||
|
current_status.c_str());
|
||||||
|
} else {
|
||||||
|
ESP_LOGCONFIG(TAG, " Status pin: Not defined");
|
||||||
|
}
|
||||||
|
ESP_LOGCONFIG(TAG, " Enabled : %s", this->enabled_ ? "Yes" : "No");
|
||||||
|
|
||||||
ESP_LOGV(TAG, "PPP netif setup");
|
ESP_LOGV(TAG, "PPP netif setup");
|
||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
err = esp_netif_init();
|
err = esp_netif_init();
|
||||||
|
@ -126,32 +140,24 @@ void ModemComponent::setup() {
|
||||||
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &ModemComponent::ip_event_handler, nullptr);
|
err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &ModemComponent::ip_event_handler, nullptr);
|
||||||
ESPHL_ERROR_CHECK(err, "IP event handler register error");
|
ESPHL_ERROR_CHECK(err, "IP event handler register error");
|
||||||
|
|
||||||
if (this->power_pin_) {
|
this->create_dte_dce_();
|
||||||
this->power_pin_->setup();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->status_pin_) {
|
if (this->enabled_ && !this->get_power_status()) {
|
||||||
this->status_pin_->setup();
|
ESP_LOGI(TAG, "Powering up modem");
|
||||||
}
|
|
||||||
|
|
||||||
this->reset_();
|
this->poweron_();
|
||||||
// At boot time, if the modem power is up, but the modem is not ready, it is probably still in cmux mode
|
|
||||||
if (this->enabled_ && this->get_power_status() && !this->modem_ready()) {
|
|
||||||
this->exit_cmux_();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGV(TAG, "Setup finished");
|
ESP_LOGV(TAG, "Setup finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModemComponent::reset_() {
|
void ModemComponent::create_dte_dce_() {
|
||||||
// destroy previous dte/dce, and recreate them.
|
// destroy previous dte/dce, and recreate them.
|
||||||
// destroying them seems to be the only way to have a clear state after hang up, and be able to reconnect.
|
// destroying them seems to be the only way to have a clear state after hang up, and be able to reconnect.
|
||||||
// if the modem was previously in cmux mode, this->exit_cmux_(), will be needed after.
|
|
||||||
|
|
||||||
this->dte_.reset();
|
this->dte_.reset();
|
||||||
this->dce.reset();
|
this->dce.reset();
|
||||||
|
|
||||||
ESP_LOGV(TAG, "DTE setup");
|
|
||||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||||
this->dte_config_ = dte_config;
|
this->dte_config_ = dte_config;
|
||||||
|
|
||||||
|
@ -168,7 +174,7 @@ void ModemComponent::reset_() {
|
||||||
|
|
||||||
this->dte_ = create_uart_dte(&this->dte_config_);
|
this->dte_ = create_uart_dte(&this->dte_config_);
|
||||||
|
|
||||||
ESP_LOGV(TAG, "DCE setup");
|
// this->dte_->set_mode(modem_mode::COMMAND_MODE);
|
||||||
|
|
||||||
#if defined(USE_MODEM_MODEL_GENERIC)
|
#if defined(USE_MODEM_MODEL_GENERIC)
|
||||||
this->dce = create_generic_dce(&this->dce_config_, this->dte_, this->ppp_netif_);
|
this->dce = create_generic_dce(&this->dce_config_, this->dte_, this->ppp_netif_);
|
||||||
|
@ -190,9 +196,22 @@ void ModemComponent::reset_() {
|
||||||
ESP_LOGE(TAG, "Failed to set the set_flow_control mode");
|
ESP_LOGE(TAG, "Failed to set the set_flow_control mode");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "set_flow_control OK");
|
ESP_LOGD(TAG, "set_flow_control OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to exit CMUX_MANUAL_DATA or DATA_MODE, if any
|
||||||
|
Watchdog wdt(60);
|
||||||
|
if (this->cmux_) {
|
||||||
|
this->dce->set_mode(modem_mode::CMUX_MANUAL_MODE);
|
||||||
|
this->dce->set_mode(modem_mode::CMUX_MANUAL_COMMAND);
|
||||||
|
} else if (!this->modem_ready()) {
|
||||||
|
this->dce->set_mode(modem_mode::COMMAND_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->modem_ready()) {
|
||||||
|
ESP_LOGD(TAG, "modem ready after exiting cmux/data mode");
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "not set_flow_control, because 2-wire mode active.");
|
ESP_LOGD(TAG, "modem *not* ready after exiting cmux/data mode");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +246,7 @@ bool ModemComponent::prepare_sim_() {
|
||||||
|
|
||||||
void ModemComponent::send_init_at_() {
|
void ModemComponent::send_init_at_() {
|
||||||
// send initial AT commands from yaml
|
// send initial AT commands from yaml
|
||||||
|
Watchdog wdt(60);
|
||||||
for (const auto &cmd : this->init_at_commands_) {
|
for (const auto &cmd : this->init_at_commands_) {
|
||||||
std::string result = this->send_at(cmd);
|
std::string result = this->send_at(cmd);
|
||||||
if (result == "ERROR") {
|
if (result == "ERROR") {
|
||||||
|
@ -243,13 +263,28 @@ void ModemComponent::start_connect_() {
|
||||||
this->status_set_warning("Starting connection");
|
this->status_set_warning("Starting connection");
|
||||||
|
|
||||||
// will be set to true on event IP_EVENT_PPP_GOT_IP
|
// will be set to true on event IP_EVENT_PPP_GOT_IP
|
||||||
global_modem_component->got_ipv4_address_ = false;
|
global_modem_component->got_ipv4_address_ = false; // FIXME this
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Entering CMUX mode");
|
if (this->cmux_) {
|
||||||
if (this->dce->set_mode(modem_mode::CMUX_MODE)) {
|
ESP_LOGD(TAG, "Entering CMUX mode");
|
||||||
ESP_LOGD(TAG, "Modem has correctly entered multiplexed command/data mode");
|
this->dce->set_mode(modem_mode::CMUX_MANUAL_MODE);
|
||||||
|
if (this->dce->set_mode(modem_mode::CMUX_MANUAL_DATA)) {
|
||||||
|
ESP_LOGD(TAG, "Modem has correctly entered multiplexed command/data mode");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "Unable to enter CMUX mode");
|
||||||
|
this->status_set_error("Unable to enter CMUX mode");
|
||||||
|
}
|
||||||
|
assert(this->modem_ready());
|
||||||
} else {
|
} else {
|
||||||
this->status_set_error("Unable to enter CMUX mode");
|
ESP_LOGD(TAG, "Entering DATA mode");
|
||||||
|
if (this->dce->set_mode(modem_mode::DATA_MODE)) {
|
||||||
|
ESP_LOGD(TAG, "Modem has correctly entered data mode");
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "Unable to enter DATA mode");
|
||||||
|
this->status_set_error("Unable to enter DATA mode");
|
||||||
|
}
|
||||||
|
assert(!this->modem_ready());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +300,7 @@ void ModemComponent::ip_event_handler(void *arg, esp_event_base_t event_base, in
|
||||||
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_LOGV(TAG, "[IP event] Lost IP");
|
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;
|
||||||
|
@ -285,6 +320,7 @@ void ModemComponent::loop() {
|
||||||
switch (this->state_) {
|
switch (this->state_) {
|
||||||
case ModemComponentState::NOT_RESPONDING:
|
case ModemComponentState::NOT_RESPONDING:
|
||||||
if (this->start_) {
|
if (this->start_) {
|
||||||
|
Watchdog wdt(60);
|
||||||
if (this->modem_ready()) {
|
if (this->modem_ready()) {
|
||||||
ESP_LOGI(TAG, "Modem recovered");
|
ESP_LOGI(TAG, "Modem recovered");
|
||||||
this->status_clear_warning();
|
this->status_clear_warning();
|
||||||
|
@ -309,6 +345,7 @@ void ModemComponent::loop() {
|
||||||
case ModemComponentState::DISCONNECTED:
|
case ModemComponentState::DISCONNECTED:
|
||||||
if (this->enabled_) {
|
if (this->enabled_) {
|
||||||
if (this->start_) {
|
if (this->start_) {
|
||||||
|
Watchdog wdt(60);
|
||||||
if (this->modem_ready()) {
|
if (this->modem_ready()) {
|
||||||
this->send_init_at_();
|
this->send_init_at_();
|
||||||
if (this->prepare_sim_()) {
|
if (this->prepare_sim_()) {
|
||||||
|
@ -319,13 +356,13 @@ void ModemComponent::loop() {
|
||||||
this->disable();
|
this->disable();
|
||||||
}
|
}
|
||||||
} else if (!this->get_power_status()) {
|
} else if (!this->get_power_status()) {
|
||||||
|
ESP_LOGI(TAG,
|
||||||
|
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
|
||||||
this->poweron_();
|
this->poweron_();
|
||||||
} else {
|
} else {
|
||||||
this->state_ = ModemComponentState::NOT_RESPONDING;
|
this->state_ = ModemComponentState::NOT_RESPONDING;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// when disconnected, we have to reset the dte and the dce
|
|
||||||
this->reset_();
|
|
||||||
this->start_ = true;
|
this->start_ = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -362,29 +399,50 @@ void ModemComponent::loop() {
|
||||||
case ModemComponentState::DISCONNECTING:
|
case ModemComponentState::DISCONNECTING:
|
||||||
if (this->start_) {
|
if (this->start_) {
|
||||||
if (this->connected_) {
|
if (this->connected_) {
|
||||||
ESP_LOGD(TAG, "Hanging up...");
|
Watchdog wdt(60);
|
||||||
ESPMODEM_ERROR_CHECK(this->dce->hang_up(), "Unable to hang up");
|
ESP_LOGD(TAG, "Going to hang up...");
|
||||||
if (!this->modem_ready()) {
|
this->dump_connect_params_();
|
||||||
ESP_LOGE(TAG, "modem not ready after hang up");
|
if (this->cmux_) {
|
||||||
|
assert(this->dce->set_mode(modem_mode::CMUX_MANUAL_COMMAND));
|
||||||
|
} else {
|
||||||
|
// assert(this->dce->set_mode(modem_mode::COMMAND_MODE)); // OK on 7600, nok on 7670...
|
||||||
|
this->dce->set_mode(modem_mode::COMMAND_MODE);
|
||||||
}
|
}
|
||||||
this->set_timeout("wait_lost_ip", 15000, [this]() {
|
delay(500);
|
||||||
// often reached on 7600, but not reached on 7670
|
ESP_LOGD(TAG, "Hanging up connection after %.1fmin", float(this->connect_begin_) / (1000 * 60));
|
||||||
ESP_LOGW(TAG, "No lost ip event received. Forcing disconnect state");
|
if (this->dce->hang_up() != command_result::OK) {
|
||||||
|
ESP_LOGW(TAG, "Unable to hang up modem. Trying to continue anyway.");
|
||||||
this->state_ = ModemComponentState::DISCONNECTED;
|
}
|
||||||
|
this->dump_connect_params_();
|
||||||
this->reset_(); // reset dce/dte
|
// this->set_timeout("wait_lost_ip", 15000, [this]() {
|
||||||
this->exit_cmux_();
|
// // often reached on 7600, but not reached on 7670
|
||||||
});
|
// // FIXME: don't wait for lost IP (ip is lost for 7600 several minutes after)
|
||||||
|
// ESP_LOGW(TAG, "No lost ip event received. Forcing disconnect state");
|
||||||
|
// // esp_netif_action_stop(this->ppp_netif_, nullptr, 0, nullptr);
|
||||||
|
// this->dump_connect_params_();
|
||||||
|
// // esp_netif_action_disconnected(this->ppp_netif_, nullptr, 0, nullptr);
|
||||||
|
// // esp_netif_action_stop(this->ppp_netif_, nullptr, 0, nullptr);
|
||||||
|
// esp_event_post(IP_EVENT, IP_EVENT_PPP_LOST_IP, nullptr, 0, 0);
|
||||||
|
// // esp_netif_destroy(this->ppp_netif_);
|
||||||
|
// this->dump_connect_params_();
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
this->start_ = false;
|
this->start_ = false;
|
||||||
} else if (!this->connected_) {
|
} else if (!this->connected_) {
|
||||||
// ip lost as expected
|
// ip lost as expected
|
||||||
this->cancel_timeout("wait_lost_ip");
|
this->cancel_timeout("wait_lost_ip");
|
||||||
|
ESP_LOGI(TAG, "Modem disconnected");
|
||||||
|
this->dump_connect_params_();
|
||||||
this->state_ = ModemComponentState::DISCONNECTED;
|
this->state_ = ModemComponentState::DISCONNECTED;
|
||||||
|
} else {
|
||||||
|
esp_netif_ip_info_t ip_info;
|
||||||
|
esp_netif_get_ip_info(this->ppp_netif_, &ip_info);
|
||||||
|
if (ip_info.ip.addr == 0) {
|
||||||
|
// lost IP
|
||||||
|
esp_event_post(IP_EVENT, IP_EVENT_PPP_LOST_IP, nullptr, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
this->reset_(); // reset dce/dte
|
// waiting for lost IP
|
||||||
this->exit_cmux_();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -392,7 +450,7 @@ void ModemComponent::loop() {
|
||||||
case ModemComponentState::DISABLED:
|
case ModemComponentState::DISABLED:
|
||||||
if (this->enabled_) {
|
if (this->enabled_) {
|
||||||
this->state_ = ModemComponentState::DISCONNECTED;
|
this->state_ = ModemComponentState::DISCONNECTED;
|
||||||
} else if (this->status_pin_ && this->get_power_status()) {
|
} else if (this->get_power_status()) { // FIXME long time in loop because of get_power_status
|
||||||
this->poweroff_();
|
this->poweroff_();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -426,42 +484,15 @@ void ModemComponent::disable() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModemComponent::exit_cmux_() {
|
|
||||||
// This must be called to gain command mode if:
|
|
||||||
// - if the esp has rebooted, but the modem not, it is still in cmux mode
|
|
||||||
// - after a dte/dce reset.
|
|
||||||
// If the modem was previously ready, this will *HANG* de dte, and the modem will be unreachable, with no chances to
|
|
||||||
// recover it.
|
|
||||||
// We need this because we are not able to do a simple esp_modem::modem_mode::COMMAND_MODE (this is probably a bug in
|
|
||||||
// esp_modem)
|
|
||||||
Watchdog wdt(60);
|
|
||||||
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_MODE);
|
|
||||||
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_COMMAND);
|
|
||||||
this->dce->set_mode(esp_modem::modem_mode::CMUX_MANUAL_EXIT);
|
|
||||||
if (!this->modem_ready()) {
|
|
||||||
ESP_LOGE(TAG, "Modem still not ready after reset");
|
|
||||||
} else {
|
|
||||||
ESP_LOGD(TAG, "Modem exited previous CMUX session");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ModemComponent::get_power_status() {
|
bool ModemComponent::get_power_status() {
|
||||||
#ifdef USE_MODEM_STATUS
|
#ifdef USE_MODEM_STATUS
|
||||||
bool init_status = this->status_pin_->digital_read();
|
// This code is not fully checked. The status pin seems to be flickering on Lilygo T-SIM7600
|
||||||
// The status pin might be floating when supposed to be low, at least on lilygo tsim7600
|
return this->status_pin_->digital_read();
|
||||||
// as GPIO34 doesn't support pullup, we have to debounce it manually
|
|
||||||
bool final_status = init_status;
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
delay(10);
|
|
||||||
final_status = final_status && this->status_pin_->digital_read();
|
|
||||||
}
|
|
||||||
if (final_status != init_status) {
|
|
||||||
// ESP_LOGV(TAG, "Floating status pin detected for state %d", final_status);
|
|
||||||
}
|
|
||||||
return final_status;
|
|
||||||
#else
|
#else
|
||||||
// No status pin, assuming the modem is ON
|
// No status pin, assuming the modem is ON
|
||||||
return true;
|
// return true;
|
||||||
|
// Watchdog wdt(60);
|
||||||
|
return this->modem_ready();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,11 +510,11 @@ void ModemComponent::poweron_() {
|
||||||
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(USE_MODEM_POWER_TONUART) / 1000);
|
||||||
this->set_timeout("wait_poweron", USE_MODEM_POWER_TONUART, [this]() {
|
this->set_timeout("wait_poweron", USE_MODEM_POWER_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_);
|
||||||
ESP_LOGV(TAG, "Waiting for modem to poweron...");
|
// ESP_LOGV(TAG, "Waiting for modem to poweron...");
|
||||||
}
|
// }
|
||||||
ESP_LOGV(TAG, "Modem ON");
|
this->create_dte_dce_();
|
||||||
while (!this->modem_ready()) {
|
while (!this->modem_ready()) {
|
||||||
delay(500); // NOLINT
|
delay(500); // NOLINT
|
||||||
ESP_LOGV(TAG, "Waiting for modem to be ready after poweron...");
|
ESP_LOGV(TAG, "Waiting for modem to be ready after poweron...");
|
||||||
|
@ -497,35 +528,37 @@ void ModemComponent::poweron_() {
|
||||||
|
|
||||||
void ModemComponent::poweroff_() {
|
void ModemComponent::poweroff_() {
|
||||||
#ifdef USE_MODEM_POWER
|
#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...");
|
||||||
this->power_transition_ = true;
|
this->power_transition_ = true;
|
||||||
|
Watchdog wdt(60);
|
||||||
|
this->power_pin_->digital_write(true);
|
||||||
|
delay(10);
|
||||||
|
this->power_pin_->digital_write(false);
|
||||||
|
delay(USE_MODEM_POWER_TOFF);
|
||||||
|
this->power_pin_->digital_write(true);
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Will check that the modem is off in %.1fs...", float(USE_MODEM_POWER_TOFFUART) / 1000);
|
||||||
|
this->set_timeout("wait_poweroff", USE_MODEM_POWER_TOFFUART, [this]() {
|
||||||
Watchdog wdt(60);
|
Watchdog wdt(60);
|
||||||
this->power_pin_->digital_write(true);
|
|
||||||
delay(10);
|
|
||||||
this->power_pin_->digital_write(false);
|
|
||||||
delay(USE_MODEM_POWER_TOFF);
|
|
||||||
this->power_pin_->digital_write(true);
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Will check that the modem is off in %.1fs...", float(USE_MODEM_POWER_TOFFUART) / 1000);
|
// while (this->get_power_status()) {
|
||||||
this->set_timeout("wait_poweron", USE_MODEM_POWER_TOFFUART, [this]() {
|
// delay(this->command_delay_);
|
||||||
Watchdog wdt(60);
|
// }
|
||||||
|
assert(!this->modem_ready());
|
||||||
while (this->get_power_status()) {
|
ESP_LOGV(TAG, "Modem OFF");
|
||||||
delay(this->command_delay_);
|
this->power_transition_ = false;
|
||||||
}
|
});
|
||||||
ESP_LOGV(TAG, "Modem OFF");
|
|
||||||
this->power_transition_ = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
#endif // USE_MODEM_POWER
|
#endif // USE_MODEM_POWER
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModemComponent::dump_connect_params_() {
|
void ModemComponent::dump_connect_params_() {
|
||||||
esp_netif_ip_info_t ip;
|
esp_netif_ip_info_t ip;
|
||||||
esp_netif_get_ip_info(this->ppp_netif_, &ip);
|
esp_netif_get_ip_info(this->ppp_netif_, &ip);
|
||||||
|
ESP_LOGCONFIG(TAG, "Modem connection:");
|
||||||
ESP_LOGCONFIG(TAG, " IP Address: %s", network::IPAddress(&ip.ip).str().c_str());
|
ESP_LOGCONFIG(TAG, " IP Address: %s", network::IPAddress(&ip.ip).str().c_str());
|
||||||
ESP_LOGCONFIG(TAG, " Hostname: '%s'", App.get_name().c_str());
|
ESP_LOGCONFIG(TAG, " Hostname: '%s'", App.get_name().c_str());
|
||||||
ESP_LOGCONFIG(TAG, " Subnet: %s", network::IPAddress(&ip.netmask).str().c_str());
|
ESP_LOGCONFIG(TAG, " Subnet: %s", network::IPAddress(&ip.netmask).str().c_str());
|
||||||
|
@ -580,13 +613,13 @@ bool ModemComponent::get_imei(std::string &result) {
|
||||||
bool ModemComponent::modem_ready() {
|
bool ModemComponent::modem_ready() {
|
||||||
// check if the modem is ready to answer AT commands
|
// check if the modem is ready to answer AT commands
|
||||||
std::string imei;
|
std::string imei;
|
||||||
bool status;
|
// bool status;
|
||||||
{
|
// {
|
||||||
// Temp increase watchdog timout
|
// // Temp increase watchdog timout. // FIXME infinite loop if while(!this->modem_ready())
|
||||||
Watchdog wdt(60);
|
// Watchdog wdt(60);
|
||||||
status = this->get_imei(imei);
|
// status = this->get_imei(imei);
|
||||||
}
|
// }
|
||||||
return status;
|
return this->get_imei(imei);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModemComponent::add_on_state_callback(std::function<void(ModemComponentState)> &&callback) {
|
void ModemComponent::add_on_state_callback(std::function<void(ModemComponentState)> &&callback) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#ifdef USE_ESP_IDF
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
|
@ -7,8 +8,6 @@
|
||||||
#include "esphome/core/automation.h"
|
#include "esphome/core/automation.h"
|
||||||
#include "esphome/components/network/util.h"
|
#include "esphome/components/network/util.h"
|
||||||
|
|
||||||
#ifdef USE_ESP_IDF
|
|
||||||
|
|
||||||
// esp_modem will use esphome logger (needed if other components include esphome/core/log.h)
|
// esp_modem will use esphome logger (needed if other components include esphome/core/log.h)
|
||||||
// We need to do this because "cxx_include/esp_modem_api.hpp" is not a pure C++ header, and use logging.
|
// We need to do this because "cxx_include/esp_modem_api.hpp" is not a pure C++ header, and use logging.
|
||||||
// FIXME: Find another workaround ?.
|
// FIXME: Find another workaround ?.
|
||||||
|
@ -54,8 +53,8 @@ class ModemComponent : public Component {
|
||||||
void set_use_address(const std::string &use_address);
|
void set_use_address(const std::string &use_address);
|
||||||
void set_rx_pin(InternalGPIOPin *rx_pin) { this->rx_pin_ = rx_pin; }
|
void set_rx_pin(InternalGPIOPin *rx_pin) { this->rx_pin_ = rx_pin; }
|
||||||
void set_tx_pin(InternalGPIOPin *tx_pin) { this->tx_pin_ = tx_pin; }
|
void set_tx_pin(InternalGPIOPin *tx_pin) { this->tx_pin_ = tx_pin; }
|
||||||
void set_power_pin(InternalGPIOPin *power_pin) { this->power_pin_ = power_pin; }
|
void set_power_pin(GPIOPin *power_pin) { this->power_pin_ = power_pin; }
|
||||||
void set_status_pin(InternalGPIOPin *status_pin) { this->status_pin_ = status_pin; }
|
void set_status_pin(GPIOPin *status_pin) { this->status_pin_ = status_pin; }
|
||||||
void set_username(const std::string &username) { this->username_ = username; }
|
void set_username(const std::string &username) { this->username_ = username; }
|
||||||
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; }
|
||||||
|
@ -70,9 +69,10 @@ class ModemComponent : public Component {
|
||||||
void disable();
|
void disable();
|
||||||
void add_on_state_callback(std::function<void(ModemComponentState)> &&callback);
|
void add_on_state_callback(std::function<void(ModemComponentState)> &&callback);
|
||||||
std::unique_ptr<DCE> dce{nullptr};
|
std::unique_ptr<DCE> dce{nullptr};
|
||||||
|
uint8_t get_cmux_vt_states();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void reset_(); // (re)create dte and dce
|
void create_dte_dce_(); // (re)create dte and dce
|
||||||
bool prepare_sim_();
|
bool prepare_sim_();
|
||||||
void send_init_at_();
|
void send_init_at_();
|
||||||
void start_connect_();
|
void start_connect_();
|
||||||
|
@ -83,8 +83,8 @@ class ModemComponent : public Component {
|
||||||
void exit_cmux_();
|
void exit_cmux_();
|
||||||
InternalGPIOPin *tx_pin_;
|
InternalGPIOPin *tx_pin_;
|
||||||
InternalGPIOPin *rx_pin_;
|
InternalGPIOPin *rx_pin_;
|
||||||
InternalGPIOPin *status_pin_{nullptr};
|
GPIOPin *status_pin_{nullptr};
|
||||||
InternalGPIOPin *power_pin_{nullptr};
|
GPIOPin *power_pin_{nullptr};
|
||||||
std::string pin_code_;
|
std::string pin_code_;
|
||||||
std::string username_;
|
std::string username_;
|
||||||
std::string password_;
|
std::string password_;
|
||||||
|
@ -95,6 +95,7 @@ class ModemComponent : public Component {
|
||||||
esp_modem_dte_config_t dte_config_;
|
esp_modem_dte_config_t dte_config_;
|
||||||
esp_modem_dce_config_t dce_config_;
|
esp_modem_dce_config_t dce_config_;
|
||||||
ModemComponentState state_{ModemComponentState::DISABLED};
|
ModemComponentState state_{ModemComponentState::DISABLED};
|
||||||
|
bool cmux_{false};
|
||||||
bool start_{false};
|
bool start_{false};
|
||||||
bool enabled_{false};
|
bool enabled_{false};
|
||||||
bool connected_{false};
|
bool connected_{false};
|
||||||
|
|
Loading…
Reference in a new issue