Selaa lähdekoodia

* SensorManager: now can influence advert lat/lon, new custom name:value pairs for custom settings (eg, gps on/off)
* companion: new CMD_GET_CUSTOM_VARS, CMD_SET_CUSTOM_VAR
* T1000e: now supports "gps" custom setting (value "0" or "1")

Scott Powell 1 vuosi sitten
vanhempi
sitoutus
e442e94e3d

+ 0 - 1
examples/companion_radio/NodePrefs.h

@@ -6,7 +6,6 @@
 struct NodePrefs {  // persisted to file
   float airtime_factor;
   char node_name[32];
-  double node_lat, node_lon;
   float freq;
   uint8_t sf;
   uint8_t cr;

+ 37 - 10
examples/companion_radio/main.cpp

@@ -140,6 +140,8 @@ static uint32_t _atoi(const char* sp) {
 #define CMD_SET_DEVICE_PIN        37
 #define CMD_SET_OTHER_PARAMS      38
 #define CMD_SEND_TELEMETRY_REQ    39
+#define CMD_GET_CUSTOM_VARS       40
+#define CMD_SET_CUSTOM_VAR        41
 
 #define RESP_CODE_OK                0
 #define RESP_CODE_ERR               1
@@ -162,6 +164,7 @@ static uint32_t _atoi(const char* sp) {
 #define RESP_CODE_CHANNEL_INFO     18   // a reply to CMD_GET_CHANNEL
 #define RESP_CODE_SIGN_START       19
 #define RESP_CODE_SIGNATURE        20
+#define RESP_CODE_CUSTOM_VARS      21
 
 // these are _pushed_ to client app at any time
 #define PUSH_CODE_ADVERT            0x80
@@ -801,8 +804,8 @@ public:
       file.read((uint8_t *) &_prefs.airtime_factor, sizeof(float));  // 0
       file.read((uint8_t *) _prefs.node_name, sizeof(_prefs.node_name));  // 4
       file.read(pad, 4);   // 36
-      file.read((uint8_t *) &_prefs.node_lat, sizeof(_prefs.node_lat));  // 40
-      file.read((uint8_t *) &_prefs.node_lon, sizeof(_prefs.node_lon));  // 48
+      file.read((uint8_t *) &sensors.node_lat, sizeof(sensors.node_lat));  // 40
+      file.read((uint8_t *) &sensors.node_lon, sizeof(sensors.node_lon));  // 48
       file.read((uint8_t *) &_prefs.freq, sizeof(_prefs.freq));   // 56
       file.read((uint8_t *) &_prefs.sf, sizeof(_prefs.sf));  // 60
       file.read((uint8_t *) &_prefs.cr, sizeof(_prefs.cr));  // 61
@@ -910,8 +913,8 @@ public:
       file.write((uint8_t *) &_prefs.airtime_factor, sizeof(float));  // 0
       file.write((uint8_t *) _prefs.node_name, sizeof(_prefs.node_name));  // 4
       file.write(pad, 4);   // 36
-      file.write((uint8_t *) &_prefs.node_lat, sizeof(_prefs.node_lat));  // 40
-      file.write((uint8_t *) &_prefs.node_lon, sizeof(_prefs.node_lon));  // 48
+      file.write((uint8_t *) &sensors.node_lat, sizeof(sensors.node_lat));  // 40
+      file.write((uint8_t *) &sensors.node_lon, sizeof(sensors.node_lon));  // 48
       file.write((uint8_t *) &_prefs.freq, sizeof(_prefs.freq));   // 56
       file.write((uint8_t *) &_prefs.sf, sizeof(_prefs.sf));  // 60
       file.write((uint8_t *) &_prefs.cr, sizeof(_prefs.cr));  // 61
@@ -958,8 +961,8 @@ public:
       memcpy(&out_frame[i], self_id.pub_key, PUB_KEY_SIZE); i += PUB_KEY_SIZE;
 
       int32_t lat, lon;
-      lat = (_prefs.node_lat * 1000000.0);
-      lon = (_prefs.node_lon * 1000000.0);
+      lat = (sensors.node_lat * 1000000.0);
+      lon = (sensors.node_lon * 1000000.0);
       memcpy(&out_frame[i], &lat, 4); i += 4;
       memcpy(&out_frame[i], &lon, 4); i += 4;
       out_frame[i++] = 0;  // reserved
@@ -1072,8 +1075,8 @@ public:
         memcpy(&alt, &cmd_frame[9], 4);  // for FUTURE support
       }
       if (lat <= 90*1E6 && lat >= -90*1E6 && lon <= 180*1E6 && lon >= -180*1E6) {
-        _prefs.node_lat = ((double)lat) / 1000000.0;
-        _prefs.node_lon = ((double)lon) / 1000000.0;
+        sensors.node_lat = ((double)lat) / 1000000.0;
+        sensors.node_lon = ((double)lon) / 1000000.0;
         savePrefs();
         writeOKFrame();
       } else {
@@ -1096,7 +1099,7 @@ public:
         writeErrFrame(ERR_CODE_ILLEGAL_ARG);
       }
     } else if (cmd_frame[0] == CMD_SEND_SELF_ADVERT) {
-      auto pkt = createSelfAdvert(_prefs.node_name, _prefs.node_lat, _prefs.node_lon);
+      auto pkt = createSelfAdvert(_prefs.node_name, sensors.node_lat, sensors.node_lon);
       if (pkt) {
         if (len >= 2 && cmd_frame[1] == 1) {   // optional param (1 = flood, 0 = zero hop)
           sendFlood(pkt);
@@ -1170,7 +1173,7 @@ public:
     } else if (cmd_frame[0] == CMD_EXPORT_CONTACT) {
       if (len < 1 + PUB_KEY_SIZE) {
         // export SELF
-        auto pkt = createSelfAdvert(_prefs.node_name, _prefs.node_lat, _prefs.node_lon);
+        auto pkt = createSelfAdvert(_prefs.node_name, sensors.node_lat, sensors.node_lon);
         if (pkt) {
           pkt->header |= ROUTE_TYPE_FLOOD;  // would normally be sent in this mode
 
@@ -1456,6 +1459,30 @@ public:
       memcpy(&_prefs.ble_pin, &cmd_frame[1], 4);
       savePrefs();
       writeOKFrame();
+    } else if (cmd_frame[0] == CMD_GET_CUSTOM_VARS) {
+      out_frame[0] = RESP_CODE_CUSTOM_VARS;
+      char* dp = (char *) &out_frame[1];
+      for (int i = 0; i < sensors.getNumSettings() && dp - (char *) &out_frame[1] < 140; i++) {
+        if (i > 0) { *dp++ = ','; }
+        strcpy(dp, sensors.getSettingName(i)); dp = strchr(dp, 0);
+        *dp++ = ':';
+        strcpy(dp, sensors.getSettingValue(i)); dp = strchr(dp, 0);
+      }
+      _serial->writeFrame(out_frame, dp - (char *)out_frame);
+    } else if (cmd_frame[0] == CMD_SET_CUSTOM_VAR && len >= 4) {
+      char* sp = (char *) &cmd_frame[1];
+      char* np = strchr(sp, ':');  // look for separator char
+      if (np) {
+        *np++ = 0;   // modify 'cmd_frame', replace ':' with null
+        bool success = sensors.setSettingValue(sp, np);
+        if (success) {
+          writeOKFrame();
+        } else {
+          writeErrFrame(ERR_CODE_ILLEGAL_ARG);
+        }
+      } else {
+        writeErrFrame(ERR_CODE_ILLEGAL_ARG);
+      }
     } else {
       writeErrFrame(ERR_CODE_UNSUPPORTED_CMD);
       MESH_DEBUG_PRINTLN("ERROR: unknown command: %02X", cmd_frame[0]);

+ 7 - 0
src/helpers/SensorManager.h

@@ -8,7 +8,14 @@
 
 class SensorManager {
 public:
+  double node_lat, node_lon;  // modify these, if you want to affect Advert location
+
+  SensorManager() { node_lat = 0; node_lon = 0; }
   virtual bool begin() { return false; }
   virtual bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) { return false; }
   virtual void loop() { }
+  virtual int getNumSettings() const { return 0; }
+  virtual const char* getSettingName(int i) const { return NULL; }
+  virtual const char* getSettingValue(int i) const { return NULL; }
+  virtual bool setSettingValue(const char* name, const char* value) { return false; }
 };

+ 28 - 9
variants/t1000-e/target.cpp

@@ -137,7 +137,7 @@ void T1000SensorManager::stop_gps() {
 
 
 bool T1000SensorManager::begin() {
-  // TODO: init GPS
+  // init GPS
   Serial1.begin(115200);
 
   // make sure gps pin are off
@@ -148,31 +148,50 @@ bool T1000SensorManager::begin() {
   pinMode(GPS_RESETB, OUTPUT);
   digitalWrite(GPS_RESETB, LOW);
 
-  start_gps();
-
-
   return true;
 }
 
 bool T1000SensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) {
   if (requester_permissions & TELEM_PERM_LOCATION) {   // does requester have permission?
-    telemetry.addGPS(TELEM_CHANNEL_SELF, _lat, _lon, _alt);
+    telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, 0.0f);
   }
   return true;
 }
 
 void T1000SensorManager::loop() {
-  // TODO: poll GPS serial,  set _lat, _lon, _alt
   static long next_gps_update = 0;
 
   _nmea->loop();
 
   if (millis() > next_gps_update) {
     if (_nmea->isValid()) {
-      _lat = ((double)_nmea->getLatitude())/1000000.;
-      _lon = ((double)_nmea->getLongitude())/1000000.;
+      node_lat = ((double)_nmea->getLatitude())/1000000.;
+      node_lon = ((double)_nmea->getLongitude())/1000000.;
       //Serial.printf("lat %f lon %f\r\n", _lat, _lon);
     }
-    next_gps_update = millis() + 5000;
+    next_gps_update = millis() + 1000;
+  }
+}
+
+int T1000SensorManager::getNumSettings() const { return 1; }  // just one supported: "gps" (power switch)
+
+const char* T1000SensorManager::getSettingName(int i) const {
+  return i == 0 ? "gps" : NULL;
+}
+const char* T1000SensorManager::getSettingValue(int i) const {
+  if (i == 0) {
+    return gps_active ? "1" : "0";
+  }
+  return NULL;
+}
+bool T1000SensorManager::setSettingValue(const char* name, const char* value) {
+  if (strcmp(name, "gps") == 0) {
+    if (strcmp(value, "0") == 0) {
+      stop_gps();   // or should this be sleep_gps() ??
+    } else {
+      start_gps();
+    }
+    return true;
   }
+  return false;  // not supported
 }

+ 9 - 5
variants/t1000-e/target.h

@@ -11,17 +11,21 @@
 #include <helpers/SensorManager.h>
 
 class T1000SensorManager: public SensorManager {
-  float _lat, _lon, _alt;
   bool gps_active = false;
   LocationProvider * _nmea;
+
+  void start_gps();
+  void sleep_gps();
+  void stop_gps();
 public:
-  T1000SensorManager(LocationProvider &nmea): _nmea(&nmea), _lat(0), _lon(0), _alt(0) { }
+  T1000SensorManager(LocationProvider &nmea): _nmea(&nmea) { }
   bool begin() override;
   bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
   void loop() override;
-  void start_gps();
-  void sleep_gps();
-  void stop_gps();
+  int getNumSettings() const override;
+  const char* getSettingName(int i) const override;
+  const char* getSettingValue(int i) const override;
+  bool setSettingValue(const char* name, const char* value) override;
 };
 
 extern T1000eBoard board;