ESP32/components/app_console/cmd_gps.c

155 lines
5.2 KiB
C

/*
* cmd_gps.c
*
* Copyright (c) 2025 Umber Networks & Robert McMahon
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
#include "esp_log.h"
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "gps_sync.h"
#include "app_console.h"
// ============================================================================
// COMMAND: gps (Configure & Status)
// ============================================================================
static struct {
struct arg_lit *enable;
struct arg_lit *disable;
struct arg_lit *status;
struct arg_lit *help;
struct arg_end *end;
} gps_args;
static int cmd_gps(int argc, char **argv) {
int nerrors = arg_parse(argc, argv, (void **)&gps_args);
if (nerrors > 0) {
arg_print_errors(stderr, gps_args.end, argv[0]);
return 1;
}
if (gps_args.help->count > 0) {
printf("Usage: gps [--enable|--disable|--status]\n");
return 0;
}
nvs_handle_t h;
esp_err_t err = nvs_open("storage", NVS_READWRITE, &h);
if (err != ESP_OK) {
printf("Error opening NVS: %s\n", esp_err_to_name(err));
return 1;
}
// --- HANDLE SETTERS ---
bool changed = false;
if (gps_args.enable->count > 0) {
nvs_set_u8(h, "gps_enabled", 1);
printf("GPS set to ENABLED. (Reboot required)\n");
changed = true;
} else if (gps_args.disable->count > 0) {
nvs_set_u8(h, "gps_enabled", 0);
printf("GPS set to DISABLED. (Reboot required)\n");
changed = true;
}
if (changed) nvs_commit(h);
// --- DISPLAY STATUS ---
// 1. NVS State
uint8_t val = 1;
if (nvs_get_u8(h, "gps_enabled", &val) != ESP_OK) val = 1; // Default true
printf("GPS NVS State: %s\n", val ? "ENABLED" : "DISABLED");
nvs_close(h);
// 2. Runtime Status
if (val) {
gps_timestamp_t ts = gps_get_timestamp();
int64_t pps_age = gps_get_pps_age_ms();
printf("Status: %s\n", ts.synced ? "SYNCED" : "SEARCHING");
// Print Raw NMEA
char nmea_buf[128];
gps_get_last_nmea(nmea_buf, sizeof(nmea_buf));
// Cleanup CR/LF for printing
size_t len = strlen(nmea_buf);
if (len > 0 && (nmea_buf[len-1] == '\r' || nmea_buf[len-1] == '\n')) nmea_buf[len-1] = 0;
if (len > 1 && (nmea_buf[len-2] == '\r' || nmea_buf[len-2] == '\n')) nmea_buf[len-2] = 0;
printf("Last NMEA: [%s]\n", nmea_buf);
if (pps_age < 0) {
printf("PPS Signal: NEVER DETECTED\n");
} else if (pps_age > 1100) {
printf("PPS Signal: LOST (Last seen %" PRId64 " ms ago)\n", pps_age);
} else {
printf("PPS Signal: ACTIVE (Age: %" PRId64 " ms)\n", pps_age);
}
if (ts.gps_us > 0) {
time_t now_sec = ts.gps_us / 1000000;
struct tm tm_info;
gmtime_r(&now_sec, &tm_info);
char time_buf[64];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S UTC", &tm_info);
printf("Current Time: %s\n", time_buf);
} else {
printf("Current Time: <Unknown> (System Epoch)\n");
}
}
app_console_update_prompt();
return 0;
}
void register_gps_cmd(void) {
gps_args.enable = arg_lit0(NULL, "enable", "Enable GPS");
gps_args.disable = arg_lit0(NULL, "disable", "Disable GPS");
gps_args.status = arg_lit0(NULL, "status", "Show Status");
gps_args.help = arg_lit0("h", "help", "Help");
gps_args.end = arg_end(2);
const esp_console_cmd_t cmd = {
.command = "gps",
.help = "Configure GPS",
.func = &cmd_gps,
.argtable = &gps_args
};
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
}