/* * 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 #include #include #include #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: (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)); }