sim7670 gnss

This commit is contained in:
oarcher 2024-08-06 23:59:44 +02:00
parent 9bfde3b3ab
commit 4ec62a2be6
4 changed files with 31 additions and 31 deletions

View file

@ -42,7 +42,7 @@ CONF_ON_NOT_RESPONDING = "on_not_responding"
CONF_ENABLE_CMUX = "enable_cmux"
CONF_ENABLE_GNSS = "enable_gnss"
MODEM_MODELS = ["BG96", "SIM800", "SIM7000", "SIM7600", "GENERIC"]
MODEM_MODELS = ["BG96", "SIM800", "SIM7000", "SIM7600", "SIM7670", "GENERIC"]
MODEM_MODELS_POWER = {
"BG96": {"ton": 600, "tonuart": 4900, "toff": 650, "toffuart": 2000},
"SIM800": {"ton": 1300, "tonuart": 3000, "toff": 200, "toffuart": 3000},
@ -50,6 +50,12 @@ MODEM_MODELS_POWER = {
"SIM7600": {"ton": 500, "tonuart": 12000, "toff": 2800, "toffuart": 25000},
}
MODEM_MODELS_POWER["SIM7670"] = MODEM_MODELS_POWER["SIM7600"]
# SIM70xx doesn't support AT+CGNSSINFO, so gnss is not available
MODEM_MODELS_GNSS_POWER = {"SIM7600": "AT+CGPS=1", "SIM7670": "AT+CGNSSPWR=1"}
modem_ns = cg.esphome_ns.namespace("modem")
ModemComponent = modem_ns.class_("ModemComponent", cg.Component)
ModemComponentState = modem_ns.enum("ModemComponentState")
@ -119,19 +125,12 @@ def final_validate_platform(config):
def _final_validate(config):
# if config.get(CONF_POWER_PIN, None) and not config.get(CONF_STATUS_PIN, None):
# raise cv.Invalid(
# f"'{CONF_STATUS_PIN}' must be declared if using '{CONF_POWER_PIN}'"
# )
# uncomment after PR#4091 merged
# if wifi_config := fv.full_config.get().get(CONF_WIFI, None):
# if wifi_has_sta(wifi_config):
# raise cv.Invalid("Wifi must be AP only when using ethernet")
if config.get(CONF_STATUS_PIN, None):
_LOGGER.warning("Using '%s' is experimental", CONF_STATUS_PIN)
if config[CONF_ENABLE_CMUX]:
_LOGGER.warning("Using '%s: True' is experimental", CONF_ENABLE_CMUX)
if not config[CONF_ENABLE_ON_BOOT]:
_LOGGER.warning("Using '%s: False' is experimental", CONF_ENABLE_ON_BOOT)
if config.get(CONF_POWER_PIN, None):
@ -139,6 +138,11 @@ def _final_validate(config):
raise cv.Invalid(
f"Modem model '{config[CONF_MODEL]}' has no power power specs."
)
if config.get(CONF_ENABLE_GNSS, None):
if config[CONF_MODEL] not in MODEM_MODELS_GNSS_POWER:
raise cv.Invalid(
f"Modem model '{config[CONF_MODEL]}' has no GNSS support with AT+CGNSSINFO."
)
FINAL_VALIDATE_SCHEMA = _final_validate
@ -185,10 +189,6 @@ async def to_code(config):
if config[CONF_ENABLE_CMUX]:
cg.add(var.enable_cmux())
if config[CONF_ENABLE_GNSS]:
cg.add_define("USE_MODEM_GNSS")
cg.add(var.enable_gnss())
if config[CONF_DEBUG]:
cg.add(var.enable_debug())
@ -200,6 +200,10 @@ async def to_code(config):
cg.add_define("USE_MODEM_MODEL", modem_model)
cg.add_define(f"USE_MODEM_MODEL_{modem_model}")
if config[CONF_ENABLE_GNSS]:
cg.add_define("USE_MODEM_GNSS")
cg.add(var.set_gnss_power_command(MODEM_MODELS_GNSS_POWER[modem_model]))
if power_spec := MODEM_MODELS_POWER.get(modem_model, None):
cg.add_define("USE_MODEM_POWER")
for spec, value in power_spec.items():

View file

@ -473,7 +473,6 @@ void ModemComponent::modem_lazy_init_() {
if (this->dte_->set_mode(modem_mode::COMMAND_MODE)) {
ESP_LOGD(TAG, "dte in command mode");
}
esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(this->apn_.c_str());
#if defined(USE_MODEM_MODEL_GENERIC)
@ -484,12 +483,11 @@ void ModemComponent::modem_lazy_init_() {
this->dce = create_SIM800_dce(&dce_config, this->dte_, this->ppp_netif_);
#elif defined(USE_MODEM_MODEL_SIM7000)
this->dce = create_SIM7000_dce(&dce_config, this->dte_, this->ppp_netif_);
#elif defined(USE_MODEM_MODEL_SIM7600)
#elif defined(USE_MODEM_MODEL_SIM7600) || defined(USE_MODEM_MODEL_SIM7670)
this->dce = create_SIM7600_dce(&dce_config, this->dte_, this->ppp_netif_);
#else
#error Modem model not known
#endif
// flow control not fully implemented, but kept here for future work
// if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) {
// if (command_result::OK != this->dce->set_flow_control(2, 2)) {
@ -508,6 +506,7 @@ bool ModemComponent::modem_sync_() {
uint32_t start_ms = millis();
uint32_t elapsed_ms;
std::string result;
ESP_LOGV(TAG, "Checking if the modem is synced...");
bool status = this->modem_ready(true);
@ -516,8 +515,6 @@ bool ModemComponent::modem_sync_() {
// Try to exit CMUX_MANUAL_DATA or DATA_MODE, if any
ESP_LOGD(TAG, "Connecting to the the modem...");
std::string result;
auto command_mode = [this]() -> bool {
ESP_LOGVV(TAG, "trying command mode");
this->dce->set_mode(modem_mode::UNDEF);
@ -553,16 +550,15 @@ bool ModemComponent::modem_sync_() {
// First time the modem is synced, or modem recovered
this->internal_state_.modem_synced = true;
// Fail on 7600, because esp_modem use internally AT+CGNSPWR? that is unsupported (should be AT+CGPS?)
// int gnss_power;
// ESPMODEM_ERROR_CHECK(this->dce->get_gnss_power_mode(gnss_power), "Getting GNSS power state");
// ESP_LOGD(TAG, "GNSS power mode: %d", gnss_power);
// enabling GNSS seems to return an error, if already enabled
// Fail on 7670, because esp_modem use internally AT+CGPS=1 that is unsupported (should be AT+CGNSSPWR=1 not
// (AT+CGNSPWR?))
// So SIM7670 should add AT+CGNSSPWR=1 to init_at
ESPMODEM_ERROR_CHECK(this->dce->set_gnss_power_mode(this->gnss_), "Enabling/disabling GNSS");
if (!this->gnss_power_command_.empty()) {
command_result err;
ESP_LOGD(TAG, "Enabling GNSS with command: %s", this->gnss_power_command_.c_str());
err = this->dce->at(this->gnss_power_command_, result, this->command_delay_);
if (err == command_result::FAIL) {
// AT+CGPS=1 for SIM7600 or AT+CGNSSPWR=1 for SIM7670 often fail, but seems to be working anyway
ESP_LOGD(TAG, "GNSS power command failed. Ignoring, as the status is often FAIL, while it works later.");
}
}
// ESPMODEM_ERROR_CHECK(this->dce->set_gnss_power_mode(0), "Enabling/disabling GNSS");
// delay(200); // NOLINT
@ -678,7 +674,6 @@ bool ModemComponent::stop_ppp_() {
if (this->cmux_) {
status = 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...
status = this->dce->set_mode(modem_mode::COMMAND_MODE);
}
if (!status) {

View file

@ -58,9 +58,9 @@ class ModemComponent : public Component {
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_apn(const std::string &apn) { this->apn_ = apn; }
void set_gnss_power_command(const std::string &at_command) { this->gnss_power_command_ = at_command; }
void set_not_responding_cb(Trigger<> *not_responding_cb) { this->not_responding_cb_ = not_responding_cb; }
void enable_cmux() { this->cmux_ = true; }
void enable_gnss() { this->gnss_ = true; }
void enable_debug() { esp_log_level_set("command_lib", ESP_LOG_VERBOSE); }
void add_init_at_command(const std::string &cmd) { this->init_at_commands_.push_back(cmd); }
bool is_connected() { return this->component_state_ == ModemComponentState::CONNECTED; }
@ -122,7 +122,7 @@ class ModemComponent : public Component {
std::vector<std::string> init_at_commands_;
std::string use_address_;
bool cmux_{false};
bool gnss_{false};
std::string gnss_power_command_;
// separate handler for `on_not_responding` (we want to know when it's ended)
Trigger<> *not_responding_cb_{nullptr};
CallbackManager<void(ModemComponentState, ModemComponentState)> on_state_callback_;

View file

@ -39,6 +39,7 @@ void ModemSensor::update() {
ESP_LOGD(TAG, "Modem sensor update");
if (modem::global_modem_component->dce && modem::global_modem_component->modem_ready()) {
this->update_signal_sensors_();
App.feed_wdt();
this->update_gnss_sensors_();
}
}
@ -182,7 +183,7 @@ void ModemSensor::update_gnss_sensors_() {
float alt = std::stof(parts["altitude"]);
float speed_knots = std::stof(parts["speed"]);
float speed_kmh = speed_knots * 1.852; // Convert speed from knots to km/h
float cog = std::stof(parts["cog"]);
float cog = parts["cog"].empty() ? NAN : std::stof(parts["cog"]);
float pdop = std::stof(parts["pdop"]);
float hdop = std::stof(parts["hdop"]);
float vdop = std::stof(parts["vdop"]);