155 lines
5.2 KiB
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));
|
|
}
|