Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/cli_commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,20 @@ region save

---

#### View or change the GPS read interval
**Usage:**
- `gps interval`
- `gps interval <seconds>`

**Parameters:**
- `seconds`: seconds between location reads, `0` to `86400`. `0` restores the firmware default (1 s)

**Default:** `0`

**Note:** The bare form reports the stored value. The setting is persisted and re-applied at boot.

---

#### Sync this node's clock with GPS time
**Usage:**
- `gps sync`
Expand Down
5 changes: 5 additions & 0 deletions examples/simple_repeater/MyMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
#if ENV_INCLUDE_GPS == 1
void applyGpsPrefs() {
sensors.setSettingValue("gps", _prefs.gps_enabled?"1":"0");
if (_prefs.gps_interval > 0) { // 0 = leave the firmware default (1 s)
char interval_str[12]; // max: 86400 seconds, 5 digits + null
sprintf(interval_str, "%u", (unsigned) _prefs.gps_interval);
sensors.setSettingValue("gps_interval", interval_str);
}
}
#endif

Expand Down
41 changes: 41 additions & 0 deletions src/helpers/CommonCLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ static uint32_t _atoi(const char* sp) {
return n;
}

// _atoi() returns 0 for garbage input, same as for a real "0" -- callers that
// need to tell "you typed 0" from "you typed a typo" check the string first.
static bool isAllDigits(const char* s) {
if (*s == 0) return false;
while (*s) {
if (*s < '0' || *s > '9') return false;
s++;
}
return true;
}

static bool isValidName(const char *n) {
while (*n) {
if (*n == '[' || *n == ']' || *n == '\\' || *n == ':' || *n == ',' || *n == '?' || *n == '*') return false;
Expand Down Expand Up @@ -390,6 +401,36 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
} else {
strcpy(reply, "error");
}
} else if (memcmp(command, "gps interval", 12) == 0
&& (command[12] == 0 || command[12] == ' ')) {
// Seconds between location reads. 0 means "use the firmware default"
// (1 s), matching how applyGpsPrefs() interprets a zero pref.
//
// The prefix match needs the delimiter check: without it "gps intervalX"
// matches here and then parses command[13] -- past the 'X' -- as the
// argument, so a mistyped command silently sets the interval to 0 instead
// of falling through to the generic "gps" handler and being rejected.
const char* arg = &command[12];
while (*arg == ' ') arg++;
if (*arg == 0) { // bare `gps interval` (or only trailing spaces): report
sprintf(reply, "> %u", (unsigned) _prefs->gps_interval);
} else if (!isAllDigits(arg)) {
// _atoi() would silently read a typo like "abc" as 0, resetting the
// pref to the firmware default instead of reporting the mistake.
strcpy(reply, "Error: interval must be a number of seconds");
} else {
char secs_str[12];
uint32_t secs = _atoi(arg);
if (secs > 86400) secs = 86400; // cap at 24 hours
sprintf(secs_str, "%u", (unsigned) secs);
if (_sensors->setSettingValue("gps_interval", secs_str)) {
_prefs->gps_interval = secs;
savePrefs();
strcpy(reply, "ok");
} else {
strcpy(reply, "gps interval not found");
}
}
} else if (memcmp(command, "gps", 3) == 0) {
LocationProvider * l = _sensors->getLocationProvider();
if (l != NULL) {
Expand Down
13 changes: 13 additions & 0 deletions src/helpers/sensors/EnvironmentSensorManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,19 @@ bool EnvironmentSensorManager::setSettingValue(const char* name, const char* val
}
return true;
}
// Deliberately NOT enumerated by getNumSettings()/getSettingName()/
// getSettingValue() above, unlike "gps": those three also drive
// CMD_GET_CUSTOM_VARS's wire payload in every companion_radio build
// (examples/companion_radio/MyMesh.cpp, ui-tiny/ui-new UITask.cpp), so
// adding an entry there changes an embedded companion-app payload on every
// target that compiles ENV_INCLUDE_GPS. "gps_interval" stays
// settable-but-not-listed, same as before.
//
// Also deliberately NOT gated on gps_detected, unlike "gps": every
// example's applyGpsPrefs() calls this at boot regardless of whether GPS
// hardware was found (and CMD_SET_CUSTOM_VAR / CommonCLI's `gps interval`
// rely on that), so gating it would break persisting the interval pref on
// boards where no GPS was detected at boot.
if (strcmp(name, "gps_interval") == 0) {
uint32_t interval_seconds = atoi(value);
gps_update_interval_sec = interval_seconds > 0 ? interval_seconds : 1;
Expand Down
Loading