send_at return AtCommandResult

This commit is contained in:
oarcher 2024-08-12 16:18:22 +02:00
parent 60a7ef7408
commit 307880bc05
4 changed files with 53 additions and 52 deletions

View file

@ -50,47 +50,43 @@ ModemComponent::ModemComponent() {
void ModemComponent::enable_debug() { esp_log_level_set("command_lib", ESP_LOG_VERBOSE); } void ModemComponent::enable_debug() { esp_log_level_set("command_lib", ESP_LOG_VERBOSE); }
std::string ModemComponent::send_at(const std::string &cmd) { AtCommandResult ModemComponent::send_at(const std::string &cmd, uint32_t timeout) {
std::string result = ""; AtCommandResult at_command_result;
at_command_result.success = false;
command_result status = command_result::FAIL; command_result status = command_result::FAIL;
ESP_LOGV(TAG, "Sending command: %s", cmd.c_str());
if (this->modem_ready()) { if (this->modem_ready()) {
status = this->dce->at(cmd, result, this->command_delay_); ESP_LOGV(TAG, "Sending command: %s", cmd.c_str());
ESP_LOGV(TAG, "Result for command %s: %s (status %s)", cmd.c_str(), result.c_str(), status = this->dce->at(cmd, at_command_result.result, timeout);
ESP_LOGV(TAG, "Result for command %s: %s (status %s)", cmd.c_str(), at_command_result.result.c_str(),
command_result_to_string(status).c_str()); command_result_to_string(status).c_str());
} }
if (status != command_result::OK) { if (status == command_result::OK) {
result = "ERROR"; at_command_result.success = true;
} }
return result; return at_command_result;
} }
bool ModemComponent::get_imei(std::string &result) { AtCommandResult ModemComponent::send_at(const std::string &cmd) { return this->send_at(cmd, this->command_delay_); }
// wrapper around this->dce->get_imei() that check that the result is valid
// (so it can be used to check if the modem is responding correctly (a simple 'AT' cmd is sometime not enough))
bool success = false; AtCommandResult ModemComponent::get_imei() {
if (this->dce) { // get the imei, and check the result is a valid imei string
command_result status; // (so it can be used to check if the modem is responding correctly (a simple 'AT' cmd is sometime not enough))
// status = this->dce->get_imei(result); AtCommandResult at_command_result;
status = this->dce->at("AT+CGSN", result, 1000); at_command_result.success = false;
success = true; command_result status = command_result::FAIL;
if (status == command_result::OK && result.length() == 15) { status = this->dce->at("AT+CGSN", at_command_result.result, 1000);
for (char c : result) { if ((status == command_result::OK) && at_command_result.result.length() == 15) {
at_command_result.success = true;
for (char c : at_command_result.result) {
if (!isdigit(static_cast<unsigned char>(c))) { if (!isdigit(static_cast<unsigned char>(c))) {
success = false; at_command_result.success = false;
break; break;
} }
} }
} else { } else {
success = false; at_command_result.success = false;
} }
} return at_command_result;
if (!success) {
result = "UNAVAILABLE";
}
return success;
} }
bool ModemComponent::get_power_status() { bool ModemComponent::get_power_status() {
@ -121,9 +117,7 @@ bool ModemComponent::modem_ready(bool force_check) {
return false; return false;
#endif #endif
} }
std::string imei; if (this->get_imei()) {
// watchdog::WatchdogManager wdt(10000);
if (this->get_imei(imei)) {
// we are sure that the modem is on // we are sure that the modem is on
this->internal_state_.powered_on = true; this->internal_state_.powered_on = true;
return true; return true;
@ -603,14 +597,13 @@ 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::WatchdogManager wdt(20000);
for (const auto &cmd : this->init_at_commands_) { for (const auto &cmd : this->init_at_commands_) {
App.feed_wdt(); App.feed_wdt();
std::string result = this->send_at(cmd); auto at_command_result = this->send_at(cmd);
if (result == "ERROR") { if (!at_command_result) {
ESP_LOGE(TAG, "Error while executing 'init_at' '%s' command", cmd.c_str()); ESP_LOGE(TAG, "Error while executing 'init_at' '%s' command", cmd.c_str());
} else { } else {
ESP_LOGI(TAG, "'init_at' '%s' result: %s", cmd.c_str(), result.c_str()); ESP_LOGI(TAG, "'init_at' '%s' result: %s", cmd.c_str(), at_command_result.result.c_str());
} }
delay(200); // NOLINT delay(200); // NOLINT
} }

View file

@ -42,6 +42,14 @@ enum class ModemPowerState {
TOFFUART, TOFFUART,
}; };
struct AtCommandResult {
std::string result;
bool success;
// Conversion to bool, allowing you to do things like `if (commandResult) {...}`
operator bool() const { return success; }
};
class ModemComponent : public Component { class ModemComponent : public Component {
public: public:
void set_use_address(const std::string &use_address) { this->use_address_ = use_address; } void set_use_address(const std::string &use_address) { this->use_address_ = use_address; }
@ -58,16 +66,15 @@ class ModemComponent : public Component {
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; }
void set_apn(const std::string &apn) { this->apn_ = apn; } 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; }
// std::string get_gnss_power_command() { return this->gnss_power_command_; }
void set_not_responding_cb(Trigger<> *not_responding_cb) { this->not_responding_cb_ = not_responding_cb; } void set_not_responding_cb(Trigger<> *not_responding_cb) { this->not_responding_cb_ = not_responding_cb; }
void enable_cmux() { this->cmux_ = true; } void enable_cmux() { this->cmux_ = true; }
void enable_debug(); void enable_debug();
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); }
bool is_connected() { return this->component_state_ == ModemComponentState::CONNECTED; } bool is_connected() { return this->component_state_ == ModemComponentState::CONNECTED; }
bool is_disabled() { return this->component_state_ == ModemComponentState::DISABLED; } bool is_disabled() { return this->component_state_ == ModemComponentState::DISABLED; }
std::string send_at(const std::string &cmd); AtCommandResult send_at(const std::string &cmd, uint32_t timeout);
bool get_imei(std::string &result); AtCommandResult send_at(const std::string &cmd);
AtCommandResult get_imei();
bool get_power_status(); bool get_power_status();
bool modem_ready(); bool modem_ready();
bool modem_ready(bool force_check); bool modem_ready(bool force_check);

View file

@ -153,9 +153,9 @@ std::map<std::string, std::string> get_gnssinfo_tokens(const std::string &gnss_i
void ModemSensor::update_gnss_sensors_() { void ModemSensor::update_gnss_sensors_() {
if (this->gnss_latitude_sensor_ || this->gnss_longitude_sensor_ || this->gnss_altitude_sensor_) { if (this->gnss_latitude_sensor_ || this->gnss_longitude_sensor_ || this->gnss_altitude_sensor_) {
std::string gnss_info = modem::global_modem_component->send_at("AT+CGNSSINFO"); auto at_command_result = modem::global_modem_component->send_at("AT+CGNSSINFO");
if (at_command_result) {
if (gnss_info != "ERROR") { std::string gnss_info = at_command_result.result;
std::map<std::string, std::string> parts = get_gnssinfo_tokens(gnss_info, "SIM7600"); std::map<std::string, std::string> parts = get_gnssinfo_tokens(gnss_info, "SIM7600");
float lat = NAN; float lat = NAN;
@ -220,6 +220,7 @@ void ModemSensor::update_gnss_sensors_() {
ESP_LOGV(TAG, "Time: %02d:%02d:%02d", hour, minute, second); ESP_LOGV(TAG, "Time: %02d:%02d:%02d", hour, minute, second);
// Sensors update // Sensors update
App.feed_wdt();
if (this->gnss_latitude_sensor_) if (this->gnss_latitude_sensor_)
this->gnss_latitude_sensor_->publish_state(lat); this->gnss_latitude_sensor_->publish_state(lat);
if (this->gnss_longitude_sensor_) if (this->gnss_longitude_sensor_)

View file

@ -33,8 +33,9 @@ static const char *const TAG = "modem.switch";
optional<bool> GnssSwitch::get_modem_gnss_state() { optional<bool> GnssSwitch::get_modem_gnss_state() {
optional<bool> gnss_state; optional<bool> gnss_state;
if (global_modem_component->modem_ready()) { auto at_command_result = global_modem_component->send_at(this->command_ + "?");
std::string modem_state = global_modem_component->send_at(this->command_ + "?"); if (at_command_result) {
std::string modem_state = at_command_result.result;
std::string delimiter = ": "; std::string delimiter = ": ";
std::size_t pos = modem_state.find(delimiter); std::size_t pos = modem_state.find(delimiter);
if (pos != std::string::npos) { if (pos != std::string::npos) {
@ -54,12 +55,11 @@ void GnssSwitch::dump_config() { LOG_SWITCH("", "Modem GNSS Switch", this); }
void GnssSwitch::setup() { this->state = this->get_initial_state_with_restore_mode().value_or(false); } void GnssSwitch::setup() { this->state = this->get_initial_state_with_restore_mode().value_or(false); }
void GnssSwitch::loop() { void GnssSwitch::loop() {
if (global_modem_component->modem_ready()) {
if (!this->modem_state_.has_value()) { if (!this->modem_state_.has_value()) {
this->modem_state_ = this->get_modem_gnss_state(); this->modem_state_ = this->get_modem_gnss_state();
} else { } else {
if ((this->state != this->modem_state_)) { if ((this->state != this->modem_state_)) {
global_modem_component->send_at(this->command_ + (this->state ? "=1" : "=0")); if (global_modem_component->send_at(this->command_ + (this->state ? "=1" : "=0"))) {
this->modem_state_ = this->state; this->modem_state_ = this->state;
this->publish_state(this->state); this->publish_state(this->state);
} }