Skip to content

Commit 487b7c6

Browse files
authored
Merge pull request #890 from fdlamotte/CommonCLI--gps-management
CommonCLI: gps management commands
2 parents da52d08 + bf1da43 commit 487b7c6

File tree

12 files changed

+260
-19
lines changed

12 files changed

+260
-19
lines changed

examples/simple_repeater/MyMesh.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,16 @@ mesh::Packet *MyMesh::createSelfAdvert() {
289289
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
290290
uint8_t app_data_len;
291291
{
292-
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
293-
app_data_len = builder.encodeTo(app_data);
292+
if (_prefs.advert_loc_policy == ADVERT_LOC_NONE) {
293+
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name);
294+
app_data_len = builder.encodeTo(app_data);
295+
} else if (_prefs.advert_loc_policy == ADVERT_LOC_SHARE) {
296+
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, sensors.node_lat, sensors.node_lon);
297+
app_data_len = builder.encodeTo(app_data);
298+
} else {
299+
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
300+
app_data_len = builder.encodeTo(app_data);
301+
}
294302
}
295303

296304
return createAdvert(self_id, app_data, app_data_len);
@@ -631,7 +639,12 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
631639
_prefs.bridge_pkt_src = 0; // logTx
632640
_prefs.bridge_baud = 115200; // baud rate
633641
_prefs.bridge_channel = 1; // channel 1
642+
634643
StrHelper::strncpy(_prefs.bridge_secret, "LVSITANOS", sizeof(_prefs.bridge_secret));
644+
645+
// GPS defaults
646+
_prefs.gps_enabled = 0;
647+
_prefs.gps_interval = 0;
635648
}
636649

637650
void MyMesh::begin(FILESYSTEM *fs) {
@@ -653,6 +666,10 @@ void MyMesh::begin(FILESYSTEM *fs) {
653666

654667
updateAdvertTimer();
655668
updateFloodAdvertTimer();
669+
670+
#if ENV_INCLUDE_GPS == 1
671+
applyGpsPrefs();
672+
#endif
656673
}
657674

658675
void MyMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) {

examples/simple_repeater/MyMesh.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
135135
return _prefs.multi_acks;
136136
}
137137

138+
#if ENV_INCLUDE_GPS == 1
139+
void applyGpsPrefs() {
140+
sensors.setSettingByKey("gps", _prefs.gps_enabled?"1":"0");
141+
}
142+
#endif
143+
138144
void onAnonDataRecv(mesh::Packet* packet, const uint8_t* secret, const mesh::Identity& sender, uint8_t* data, size_t len) override;
139145
int searchPeersByHash(const uint8_t* hash) override;
140146
void getPeerSharedSecret(uint8_t* dest_secret, int peer_idx) override;

examples/simple_room_server/MyMesh.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,16 @@ mesh::Packet *MyMesh::createSelfAdvert() {
116116
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
117117
uint8_t app_data_len;
118118
{
119-
AdvertDataBuilder builder(ADV_TYPE_ROOM, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
120-
app_data_len = builder.encodeTo(app_data);
119+
if (_prefs.advert_loc_policy == ADVERT_LOC_NONE) {
120+
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name);
121+
app_data_len = builder.encodeTo(app_data);
122+
} else if (_prefs.advert_loc_policy == ADVERT_LOC_SHARE) {
123+
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, sensors.node_lat, sensors.node_lon);
124+
app_data_len = builder.encodeTo(app_data);
125+
} else {
126+
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
127+
app_data_len = builder.encodeTo(app_data);
128+
}
121129
}
122130

123131
return createAdvert(self_id, app_data, app_data_len);
@@ -632,6 +640,10 @@ void MyMesh::begin(FILESYSTEM *fs) {
632640

633641
updateAdvertTimer();
634642
updateFloodAdvertTimer();
643+
644+
#if ENV_INCLUDE_GPS == 1
645+
applyGpsPrefs();
646+
#endif
635647
}
636648

637649
void MyMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) {

examples/simple_room_server/MyMesh.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
149149
bool onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override;
150150
void onAckRecv(mesh::Packet* packet, uint32_t ack_crc) override;
151151

152+
#if ENV_INCLUDE_GPS == 1
153+
void applyGpsPrefs() {
154+
sensors.setSettingByKey("gps", _prefs.gps_enabled?"1":"0");
155+
}
156+
#endif
157+
152158
public:
153159
MyMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::MeshTables& tables);
154160

examples/simple_sensor/SensorMesh.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,16 @@ mesh::Packet* SensorMesh::createSelfAdvert() {
241241
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
242242
uint8_t app_data_len;
243243
{
244-
AdvertDataBuilder builder(ADV_TYPE_SENSOR, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
245-
app_data_len = builder.encodeTo(app_data);
244+
if (_prefs.advert_loc_policy == ADVERT_LOC_NONE) {
245+
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name);
246+
app_data_len = builder.encodeTo(app_data);
247+
} else if (_prefs.advert_loc_policy == ADVERT_LOC_SHARE) {
248+
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, sensors.node_lat, sensors.node_lon);
249+
app_data_len = builder.encodeTo(app_data);
250+
} else {
251+
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
252+
app_data_len = builder.encodeTo(app_data);
253+
}
246254
}
247255

248256
return createAdvert(self_id, app_data, app_data_len);
@@ -697,6 +705,10 @@ void SensorMesh::begin(FILESYSTEM* fs) {
697705

698706
updateAdvertTimer();
699707
updateFloodAdvertTimer();
708+
709+
#if ENV_INCLUDE_GPS == 1
710+
applyGpsPrefs();
711+
#endif
700712
}
701713

702714
bool SensorMesh::formatFileSystem() {

examples/simple_sensor/SensorMesh.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,9 @@ class SensorMesh : public mesh::Mesh, public CommonCLICallbacks {
149149

150150
void sendAlert(const ClientInfo* c, Trigger* t);
151151

152+
#if ENV_INCLUDE_GPS == 1
153+
void applyGpsPrefs() {
154+
sensors.setSettingByKey("gps", _prefs.gps_enabled?"1":"0");
155+
}
156+
#endif
152157
};

src/helpers/CommonCLI.cpp

Lines changed: 139 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,15 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
6262
file.read((uint8_t *)&_prefs->bridge_delay, sizeof(_prefs->bridge_delay)); // 128
6363
file.read((uint8_t *)&_prefs->bridge_pkt_src, sizeof(_prefs->bridge_pkt_src)); // 130
6464
file.read((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
65-
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 132
66-
file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 133
65+
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
66+
file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
67+
file.read(pad, 4); // 152
68+
file.read((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
69+
file.read((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
70+
if (file.read((uint8_t *)&_prefs->advert_loc_policy, sizeof (_prefs->advert_loc_policy)) == -1) {
71+
_prefs->advert_loc_policy = ADVERT_LOC_PREFS; // default value
72+
} // 161
73+
// 162
6774

6875
// sanitise bad pref values
6976
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
@@ -84,6 +91,9 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
8491
_prefs->bridge_baud = constrain(_prefs->bridge_baud, 9600, 115200);
8592
_prefs->bridge_channel = constrain(_prefs->bridge_channel, 0, 14);
8693

94+
_prefs->gps_enabled = constrain(_prefs->gps_enabled, 0, 1);
95+
_prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, 0, 2);
96+
8797
file.close();
8898
}
8999
}
@@ -131,8 +141,13 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
131141
file.write((uint8_t *)&_prefs->bridge_delay, sizeof(_prefs->bridge_delay)); // 128
132142
file.write((uint8_t *)&_prefs->bridge_pkt_src, sizeof(_prefs->bridge_pkt_src)); // 130
133143
file.write((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
134-
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 132
135-
file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 133
144+
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
145+
file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
146+
file.write(pad, 4); // 152
147+
file.write((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
148+
file.write((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
149+
file.write((uint8_t *)&_prefs->advert_loc_policy, sizeof(_prefs->advert_loc_policy)); // 161
150+
// 162
136151

137152
file.close();
138153
}
@@ -504,6 +519,126 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
504519
sprintf(reply, "%s (Build: %s)", _callbacks->getFirmwareVer(), _callbacks->getBuildDate());
505520
} else if (memcmp(command, "board", 5) == 0) {
506521
sprintf(reply, "%s", _board->getManufacturerName());
522+
} else if (memcmp(command, "sensor get ", 11) == 0) {
523+
const char* key = command + 11;
524+
const char* val = sensors.getSettingByKey(key);
525+
if (val != NULL) {
526+
sprintf(reply, "> %s", val);
527+
} else {
528+
strcpy(reply, "null");
529+
}
530+
} else if (memcmp(command, "sensor set ", 11) == 0) {
531+
strcpy(tmp, &command[11]);
532+
const char *parts[2];
533+
int num = mesh::Utils::parseTextParts(tmp, parts, 2, ' ');
534+
const char *key = (num > 0) ? parts[0] : "";
535+
const char *value = (num > 1) ? parts[1] : "null";
536+
if (sensors.setSettingByKey(key, value)) {
537+
strcpy(reply, "ok");
538+
} else {
539+
strcpy(reply, "can't find custom var");
540+
}
541+
} else if (memcmp(command, "sensor list", 11) == 0) {
542+
char* dp = reply;
543+
int start = 0;
544+
int end = sensors.getNumSettings();
545+
if (strlen(command) > 11) {
546+
start = _atoi(command+12);
547+
}
548+
if (start >= end) {
549+
strcpy(reply, "no custom var");
550+
} else {
551+
sprintf(dp, "%d vars\n", end);
552+
dp = strchr(dp, 0);
553+
int i;
554+
for (i = start; i < end && (dp-reply < 134); i++) {
555+
sprintf(dp, "%s=%s\n",
556+
sensors.getSettingName(i),
557+
sensors.getSettingValue(i));
558+
dp = strchr(dp, 0);
559+
}
560+
if (i < end) {
561+
sprintf(dp, "... next:%d", i);
562+
} else {
563+
*(dp-1) = 0; // remove last CR
564+
}
565+
}
566+
#if ENV_INCLUDE_GPS == 1
567+
} else if (memcmp(command, "gps on", 6) == 0) {
568+
if (sensors.setSettingByKey("gps", "1")) {
569+
_prefs->gps_enabled = 1;
570+
savePrefs();
571+
strcpy(reply, "ok");
572+
} else {
573+
strcpy(reply, "gps toggle not found");
574+
}
575+
} else if (memcmp(command, "gps off", 7) == 0) {
576+
if (sensors.setSettingByKey("gps", "0")) {
577+
_prefs->gps_enabled = 0;
578+
savePrefs();
579+
strcpy(reply, "ok");
580+
} else {
581+
strcpy(reply, "gps toggle not found");
582+
}
583+
} else if (memcmp(command, "gps sync", 8) == 0) {
584+
LocationProvider * l = sensors.getLocationProvider();
585+
if (l != NULL) {
586+
l->syncTime();
587+
}
588+
} else if (memcmp(command, "gps setloc", 10) == 0) {
589+
_prefs->node_lat = sensors.node_lat;
590+
_prefs->node_lon = sensors.node_lon;
591+
savePrefs();
592+
strcpy(reply, "ok");
593+
} else if (memcmp(command, "gps advert", 10) == 0) {
594+
if (strlen(command) == 10) {
595+
switch (_prefs->advert_loc_policy) {
596+
case ADVERT_LOC_NONE:
597+
strcpy(reply, "> none");
598+
break;
599+
case ADVERT_LOC_PREFS:
600+
strcpy(reply, "> prefs");
601+
break;
602+
case ADVERT_LOC_SHARE:
603+
strcpy(reply, "> share");
604+
break;
605+
default:
606+
strcpy(reply, "error");
607+
}
608+
} else if (memcmp(command+11, "none", 4) == 0) {
609+
_prefs->advert_loc_policy = ADVERT_LOC_NONE;
610+
savePrefs();
611+
strcpy(reply, "ok");
612+
} else if (memcmp(command+11, "share", 5) == 0) {
613+
_prefs->advert_loc_policy = ADVERT_LOC_SHARE;
614+
savePrefs();
615+
strcpy(reply, "ok");
616+
} else if (memcmp(command+11, "prefs", 4) == 0) {
617+
_prefs->advert_loc_policy = ADVERT_LOC_PREFS;
618+
savePrefs();
619+
strcpy(reply, "ok");
620+
} else {
621+
strcpy(reply, "error");
622+
}
623+
} else if (memcmp(command, "gps", 3) == 0) {
624+
LocationProvider * l = sensors.getLocationProvider();
625+
if (l != NULL) {
626+
bool enabled = l->isEnabled(); // is EN pin on ?
627+
bool fix = l->isValid(); // has fix ?
628+
int sats = l->satellitesCount();
629+
bool active = !strcmp(sensors.getSettingByKey("gps"), "1");
630+
if (enabled) {
631+
sprintf(reply, "on, %s, %s, %d sats",
632+
active?"active":"deactivated",
633+
fix?"fix":"no fix",
634+
sats);
635+
} else {
636+
strcpy(reply, "off");
637+
}
638+
} else {
639+
strcpy(reply, "Can't find GPS");
640+
}
641+
#endif
507642
} else if (memcmp(command, "log start", 9) == 0) {
508643
_callbacks->setLoggingOn(true);
509644
strcpy(reply, " logging on");

src/helpers/CommonCLI.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22

33
#include "Mesh.h"
44
#include <helpers/IdentityStore.h>
5+
#include <target.h>
56

67
#if defined(WITH_RS232_BRIDGE) || defined(WITH_ESPNOW_BRIDGE)
78
#define WITH_BRIDGE
89
#endif
910

11+
#define ADVERT_LOC_NONE 0
12+
#define ADVERT_LOC_SHARE 1
13+
#define ADVERT_LOC_PREFS 2
14+
1015
struct NodePrefs { // persisted to file
1116
float airtime_factor;
1217
char node_name[32];
@@ -37,6 +42,10 @@ struct NodePrefs { // persisted to file
3742
uint32_t bridge_baud; // 9600, 19200, 38400, 57600, 115200 (default 115200)
3843
uint8_t bridge_channel; // 1-14 (ESP-NOW only)
3944
char bridge_secret[16]; // for XOR encryption of bridge packets (ESP-NOW only)
45+
// Gps settings
46+
uint8_t gps_enabled;
47+
uint32_t gps_interval; // in seconds
48+
uint8_t advert_loc_policy;
4049
};
4150

4251
class CommonCLICallbacks {

src/helpers/SensorManager.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,25 @@ class SensorManager {
2323
virtual const char* getSettingValue(int i) const { return NULL; }
2424
virtual bool setSettingValue(const char* name, const char* value) { return false; }
2525
virtual LocationProvider* getLocationProvider() { return NULL; }
26+
27+
// Helper functions to manage setting by keys (useful in many places ...)
28+
const char* getSettingByKey(const char* key) {
29+
int num = getNumSettings();
30+
for (int i = 0; i < num; i++) {
31+
if (strcmp(getSettingName(i), key) == 0) {
32+
return getSettingValue(i);
33+
}
34+
}
35+
return NULL;
36+
}
37+
38+
bool setSettingByKey(const char* key, const char* value) {
39+
int num = getNumSettings();
40+
for (int i = 0; i < num; i++) {
41+
if (strcmp(getSettingName(i), key) == 0) {
42+
return setSettingValue(key, value);
43+
}
44+
}
45+
return false;
46+
}
2647
};

0 commit comments

Comments
 (0)