Просмотр исходного кода

* CommonCLI: "set radio " now with optional 5th param timeout_mins, for applying temporary radio params for that many mins
* "advert" command now with longer delay, so that CLI reply is sent first

Scott Powell 1 год назад
Родитель
Сommit
ea4aa93594

+ 30 - 1
examples/simple_repeater/main.cpp

@@ -120,7 +120,7 @@ struct NeighbourInfo {
   int8_t snr; // multiplied by 4, user should divide to get float value
 };
 
-#define CLI_REPLY_DELAY_MILLIS  1000
+#define CLI_REPLY_DELAY_MILLIS  600
 
 class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
   FILESYSTEM* _fs;
@@ -134,6 +134,11 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
   NeighbourInfo neighbours[MAX_NEIGHBOURS];
 #endif
   CayenneLPP telemetry;
+  unsigned long set_radio_at, revert_radio_at;
+  float pending_freq;
+  float pending_bw;
+  uint8_t pending_sf;
+  uint8_t pending_cr;
 
   ClientInfo* putClient(const mesh::Identity& id) {
     uint32_t min_time = 0xFFFFFFFF;
@@ -558,6 +563,7 @@ public:
   {
     memset(known_clients, 0, sizeof(known_clients));
     next_local_advert = next_flood_advert = 0;
+    set_radio_at = revert_radio_at = 0;
     _logging = false;
 
   #if MAX_NEIGHBOURS
@@ -609,6 +615,16 @@ public:
     _cli.savePrefs(_fs);
   }
 
+  void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override {
+    set_radio_at = futureMillis(2000);   // give CLI reply some time to be sent back, before applying temp radio params
+    pending_freq = freq;
+    pending_bw = bw;
+    pending_sf = sf;
+    pending_cr = cr;
+
+    revert_radio_at = futureMillis(2000 + timeout_mins*60*1000);   // schedule when to revert radio params
+  }
+
   bool formatFileSystem() override {
 #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
     return InternalFS.format();
@@ -734,6 +750,19 @@ public:
 
       updateAdvertTimer();   // schedule next local advert
     }
+
+    if (set_radio_at && millisHasNowPassed(set_radio_at)) {   // apply pending (temporary) radio params
+      set_radio_at = 0;  // clear timer
+      radio_set_params(pending_freq, pending_bw, pending_sf, pending_cr);
+      MESH_DEBUG_PRINTLN("Temp radio params");
+    }
+
+    if (revert_radio_at && millisHasNowPassed(revert_radio_at)) {   // revert radio params to orig
+      revert_radio_at = 0;  // clear timer
+      radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
+      MESH_DEBUG_PRINTLN("Radio params restored");
+    }
+
   #ifdef DISPLAY_CLASS
     ui_task.loop();
   #endif

+ 28 - 0
examples/simple_room_server/main.cpp

@@ -165,6 +165,11 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
   int next_post_idx;
   PostInfo posts[MAX_UNSYNCED_POSTS];   // cyclic queue
   CayenneLPP telemetry;
+  unsigned long set_radio_at, revert_radio_at;
+  float pending_freq;
+  float pending_bw;
+  uint8_t pending_sf;
+  uint8_t pending_cr;
 
   ClientInfo* putClient(const mesh::Identity& id) {
     for (int i = 0; i < num_clients; i++) {
@@ -721,6 +726,7 @@ public:
   {
     next_local_advert = next_flood_advert = 0;
     _logging = false;
+    set_radio_at = revert_radio_at = 0;
 
     // defaults
     memset(&_prefs, 0, sizeof(_prefs));
@@ -778,6 +784,16 @@ public:
     _cli.savePrefs(_fs);
   }
 
+  void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override {
+    set_radio_at = futureMillis(2000);   // give CLI reply some time to be sent back, before applying temp radio params
+    pending_freq = freq;
+    pending_bw = bw;
+    pending_sf = sf;
+    pending_cr = cr;
+
+    revert_radio_at = futureMillis(2000 + timeout_mins*60*1000);   // schedule when to revert radio params
+  }
+
   bool formatFileSystem() override {
     #if defined(NRF52_PLATFORM)
       return InternalFS.format();
@@ -922,6 +938,18 @@ public:
       updateAdvertTimer();   // schedule next local advert
     }
 
+    if (set_radio_at && millisHasNowPassed(set_radio_at)) {   // apply pending (temporary) radio params
+      set_radio_at = 0;  // clear timer
+      radio_set_params(pending_freq, pending_bw, pending_sf, pending_cr);
+      MESH_DEBUG_PRINTLN("Temp radio params");
+    }
+
+    if (revert_radio_at && millisHasNowPassed(revert_radio_at)) {   // revert radio params to orig
+      revert_radio_at = 0;  // clear timer
+      radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
+      MESH_DEBUG_PRINTLN("Radio params restored");
+    }
+
   #ifdef DISPLAY_CLASS
     ui_task.loop();
   #endif

+ 23 - 0
examples/simple_sensor/SensorMesh.cpp

@@ -722,6 +722,7 @@ SensorMesh::SensorMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::Millise
   dirty_contacts_expiry = 0;
   last_read_time = 0;
   num_alert_tasks = 0;
+  set_radio_at = revert_radio_at = 0;
 
   // defaults
   memset(&_prefs, 0, sizeof(_prefs));
@@ -772,6 +773,16 @@ bool SensorMesh::formatFileSystem() {
 #endif
 }
 
+void SensorMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) {
+  set_radio_at = futureMillis(2000);   // give CLI reply some time to be sent back, before applying temp radio params
+  pending_freq = freq;
+  pending_bw = bw;
+  pending_sf = sf;
+  pending_cr = cr;
+
+  revert_radio_at = futureMillis(2000 + timeout_mins*60*1000);   // schedule when to revert radio params
+}
+
 void SensorMesh::sendSelfAdvertisement(int delay_millis) {
   mesh::Packet* pkt = createSelfAdvert();
   if (pkt) {
@@ -847,6 +858,18 @@ void SensorMesh::loop() {
     updateAdvertTimer();   // schedule next local advert
   }
 
+  if (set_radio_at && millisHasNowPassed(set_radio_at)) {   // apply pending (temporary) radio params
+    set_radio_at = 0;  // clear timer
+    radio_set_params(pending_freq, pending_bw, pending_sf, pending_cr);
+    MESH_DEBUG_PRINTLN("Temp radio params");
+  }
+
+  if (revert_radio_at && millisHasNowPassed(revert_radio_at)) {   // revert radio params to orig
+    revert_radio_at = 0;  // clear timer
+    radio_set_params(_prefs.freq, _prefs.bw, _prefs.sf, _prefs.cr);
+    MESH_DEBUG_PRINTLN("Radio params restored");
+  }
+
   uint32_t curr = getRTCClock()->getCurrentTime();
   if (curr >= last_read_time + SENSOR_READ_INTERVAL_SECS) {
     telemetry.reset();

+ 6 - 0
examples/simple_sensor/SensorMesh.h

@@ -90,6 +90,7 @@ public:
   }
   const uint8_t* getSelfIdPubKey() override { return self_id.pub_key; }
   void clearStats() override { }
+  void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) override;
 
   float getTelemValue(uint8_t channel, uint8_t type);
 
@@ -154,6 +155,11 @@ private:
   int matching_peer_indexes[MAX_SEARCH_RESULTS];
   int num_alert_tasks;
   Trigger* alert_tasks[MAX_CONCURRENT_ALERTS];
+  unsigned long set_radio_at, revert_radio_at;
+  float pending_freq;
+  float pending_bw;
+  uint8_t pending_sf;
+  uint8_t pending_cr;
 
   void loadContacts();
   void saveContacts();

+ 15 - 9
src/helpers/CommonCLI.cpp

@@ -132,7 +132,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
     if (memcmp(command, "reboot", 6) == 0) {
       _board->reboot();  // doesn't return
     } else if (memcmp(command, "advert", 6) == 0) {
-      _callbacks->sendSelfAdvertisement(400);
+      _callbacks->sendSelfAdvertisement(1500);  // longer delay, give CLI response time to be sent first
       strcpy(reply, "OK - Advert sent");
     } else if (memcmp(command, "clock sync", 10) == 0) {
       uint32_t curr = getRTCClock()->getCurrentTime();
@@ -280,19 +280,25 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
         strcpy(reply, _prefs->disable_fwd ? "OK - repeat is now OFF" : "OK - repeat is now ON");
       } else if (memcmp(config, "radio ", 6) == 0) {
         strcpy(tmp, &config[6]);
-        const char *parts[4];
-        int num = mesh::Utils::parseTextParts(tmp, parts, 4);
+        const char *parts[5];
+        int num = mesh::Utils::parseTextParts(tmp, parts, 5);
         float freq  = num > 0 ? atof(parts[0]) : 0.0f;
         float bw    = num > 1 ? atof(parts[1]) : 0.0f;
         uint8_t sf  = num > 2 ? atoi(parts[2]) : 0;
         uint8_t cr  = num > 3 ? atoi(parts[3]) : 0;
+        int temp_timeout_mins  = num > 4 ? atoi(parts[4]) : 0;
         if (freq >= 300.0f && freq <= 2500.0f && sf >= 7 && sf <= 12 && cr >= 5 && cr <= 8 && bw >= 7.0f && bw <= 500.0f) {
-          _prefs->sf = sf;
-          _prefs->cr = cr;
-          _prefs->freq = freq;
-          _prefs->bw = bw;
-          _callbacks->savePrefs();
-          strcpy(reply, "OK - reboot to apply");
+          if (temp_timeout_mins > 0) {
+            _callbacks->applyTempRadioParams(freq, bw, sf, cr, temp_timeout_mins);
+            sprintf(reply, "OK - temp params for %d mins", temp_timeout_mins);
+          } else {
+            _prefs->sf = sf;
+            _prefs->cr = cr;
+            _prefs->freq = freq;
+            _prefs->bw = bw;
+            _callbacks->savePrefs();
+            strcpy(reply, "OK - reboot to apply");
+          }
         } else {
           strcpy(reply, "Error, invalid radio params");
         }

+ 1 - 0
src/helpers/CommonCLI.h

@@ -45,6 +45,7 @@ public:
   virtual void formatNeighborsReply(char *reply) = 0;
   virtual const uint8_t* getSelfIdPubKey() = 0;
   virtual void clearStats() = 0;
+  virtual void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) = 0;
 };
 
 class CommonCLI {