mirror of
https://github.com/esphome/esphome.git
synced 2024-12-25 15:04:54 +01:00
power & status WIP
This commit is contained in:
parent
ca55ed7b4b
commit
7b5fe70cf6
3 changed files with 104 additions and 0 deletions
|
@ -26,6 +26,9 @@ CONFLICTS_WITH = ["wifi", "captive_portal", "ethernet"]
|
||||||
CONF_PIN_CODE = "pin_code"
|
CONF_PIN_CODE = "pin_code"
|
||||||
CONF_APN = "apn"
|
CONF_APN = "apn"
|
||||||
CONF_DTR_PIN = "dtr_pin"
|
CONF_DTR_PIN = "dtr_pin"
|
||||||
|
CONF_STATUS_PIN = "status_pin"
|
||||||
|
CONF_POWER_PIN = "power_pin"
|
||||||
|
CONF_FLIGTH_PIN = "flight_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"
|
||||||
|
|
||||||
|
@ -51,6 +54,8 @@ CONFIG_SCHEMA = cv.All(
|
||||||
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.string,
|
||||||
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_POWER_PIN): pins.internal_gpio_output_pin_schema,
|
||||||
cv.Optional(CONF_DTR_PIN): pins.internal_gpio_output_pin_schema,
|
cv.Optional(CONF_DTR_PIN): pins.internal_gpio_output_pin_schema,
|
||||||
cv.Optional(CONF_PIN_CODE): cv.string_strict,
|
cv.Optional(CONF_PIN_CODE): cv.string_strict,
|
||||||
cv.Optional(CONF_USERNAME): cv.string,
|
cv.Optional(CONF_USERNAME): cv.string,
|
||||||
|
@ -140,6 +145,14 @@ async def to_code(config):
|
||||||
rx_pin = await cg.gpio_pin_expression(config[CONF_RX_PIN])
|
rx_pin = await cg.gpio_pin_expression(config[CONF_RX_PIN])
|
||||||
cg.add(var.set_rx_pin(rx_pin))
|
cg.add(var.set_rx_pin(rx_pin))
|
||||||
|
|
||||||
|
if status_pin := config.get(CONF_STATUS_PIN, None):
|
||||||
|
pin = await cg.gpio_pin_expression(status_pin)
|
||||||
|
cg.add(var.set_status_pin(pin))
|
||||||
|
|
||||||
|
if power_pin := config.get(CONF_POWER_PIN, None):
|
||||||
|
pin = await cg.gpio_pin_expression(power_pin)
|
||||||
|
cg.add(var.set_power_pin(pin))
|
||||||
|
|
||||||
for conf in config.get(CONF_ON_NOT_RESPONDING, []):
|
for conf in config.get(CONF_ON_NOT_RESPONDING, []):
|
||||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
await automation.build_automation(trigger, [], conf)
|
await automation.build_automation(trigger, [], conf)
|
||||||
|
|
|
@ -113,6 +113,31 @@ void ModemComponent::setup() {
|
||||||
|
|
||||||
this->reset_();
|
this->reset_();
|
||||||
|
|
||||||
|
if (this->power_pin_) {
|
||||||
|
this->power_pin_->setup();
|
||||||
|
|
||||||
|
delay(100); // NOLINT
|
||||||
|
// this->power_pin_->digital_write(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->status_pin_) {
|
||||||
|
this->status_pin_->setup();
|
||||||
|
delay(100); // NOLINT
|
||||||
|
if (this->get_power_status()) {
|
||||||
|
ESP_LOGI(TAG, "Modem is ON");
|
||||||
|
this->poweroff();
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "Modem is OFF");
|
||||||
|
this->poweron();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->modem_ready()) {
|
||||||
|
ESP_LOGD(TAG, "modem ready at setup");
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "modem not ready at setup");
|
||||||
|
}
|
||||||
|
|
||||||
ESP_LOGV(TAG, "Setup finished");
|
ESP_LOGV(TAG, "Setup finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +193,7 @@ void ModemComponent::reset_() {
|
||||||
|
|
||||||
assert(this->dce);
|
assert(this->dce);
|
||||||
|
|
||||||
|
// 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) {
|
||||||
if (command_result::OK != this->dce->set_flow_control(2, 2)) {
|
if (command_result::OK != this->dce->set_flow_control(2, 2)) {
|
||||||
ESP_LOGE(TAG, "Failed to set the set_flow_control mode");
|
ESP_LOGE(TAG, "Failed to set the set_flow_control mode");
|
||||||
|
@ -180,6 +206,7 @@ void ModemComponent::reset_() {
|
||||||
|
|
||||||
if (this->enabled_ && !this->modem_ready()) {
|
if (this->enabled_ && !this->modem_ready()) {
|
||||||
ESP_LOGW(TAG, "Here...");
|
ESP_LOGW(TAG, "Here...");
|
||||||
|
|
||||||
// if the esp has rebooted, but the modem not, it is still in cmux mode
|
// if the esp has rebooted, but the modem not, it is still in cmux mode
|
||||||
// So we close cmux.
|
// So we close cmux.
|
||||||
// The drawback is that if the modem is poweroff, those commands will take some time to execute.
|
// The drawback is that if the modem is poweroff, those commands will take some time to execute.
|
||||||
|
@ -424,6 +451,63 @@ void ModemComponent::disable() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ModemComponent::get_power_status() {
|
||||||
|
if (!this->status_pin_) {
|
||||||
|
ESP_LOGV(TAG, "No status pin, assuming the modem is ON");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool init_status = this->status_pin_->digital_read();
|
||||||
|
// 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
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
ESP_LOGV(TAG, "power status: %d", final_status);
|
||||||
|
return final_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModemComponent::poweron() {
|
||||||
|
if (this->power_pin_) {
|
||||||
|
Watchdog wdt(60);
|
||||||
|
this->power_pin_->digital_write(0);
|
||||||
|
delay(10);
|
||||||
|
this->power_pin_->digital_write(1);
|
||||||
|
delay(1010);
|
||||||
|
this->power_pin_->digital_write(0);
|
||||||
|
while (!this->get_power_status()) {
|
||||||
|
delay(this->command_delay_);
|
||||||
|
ESP_LOGV(TAG, "Waiting for modem to poweron");
|
||||||
|
}
|
||||||
|
while (!this->modem_ready()) {
|
||||||
|
delay(500); // NOLINT
|
||||||
|
ESP_LOGV(TAG, "Waiting for modem to be ready after poweron");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModemComponent::poweroff() {
|
||||||
|
if (this->get_power_status()) {
|
||||||
|
if (this->power_pin_) {
|
||||||
|
ESP_LOGV(TAG, "Modem poweroff with power pin");
|
||||||
|
Watchdog wdt(60);
|
||||||
|
this->power_pin_->digital_write(false);
|
||||||
|
delay(2600); // NOLINT
|
||||||
|
this->power_pin_->digital_write(true);
|
||||||
|
while (this->get_power_status()) {
|
||||||
|
delay(this->command_delay_);
|
||||||
|
ESP_LOGV(TAG, "Waiting for modem to poweroff");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "Modem poweroff with AT command (TODO)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -56,6 +56,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_status_pin(InternalGPIOPin *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; }
|
||||||
|
@ -67,6 +69,9 @@ class ModemComponent : public Component {
|
||||||
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);
|
||||||
bool get_imei(std::string &result);
|
bool get_imei(std::string &result);
|
||||||
|
bool get_power_status();
|
||||||
|
void poweron();
|
||||||
|
void poweroff();
|
||||||
bool modem_ready();
|
bool modem_ready();
|
||||||
void enable();
|
void enable();
|
||||||
void disable();
|
void disable();
|
||||||
|
@ -77,6 +82,8 @@ class ModemComponent : public Component {
|
||||||
void reset_(); // (re)create dte and dce
|
void reset_(); // (re)create dte and dce
|
||||||
InternalGPIOPin *tx_pin_;
|
InternalGPIOPin *tx_pin_;
|
||||||
InternalGPIOPin *rx_pin_;
|
InternalGPIOPin *rx_pin_;
|
||||||
|
InternalGPIOPin *status_pin_{nullptr};
|
||||||
|
InternalGPIOPin *power_pin_{nullptr};
|
||||||
std::string pin_code_;
|
std::string pin_code_;
|
||||||
std::string username_;
|
std::string username_;
|
||||||
std::string password_;
|
std::string password_;
|
||||||
|
|
Loading…
Reference in a new issue