@@ -221,10 +221,10 @@ void SensorMesh::applyContactPermissions(const uint8_t* pubkey, uint16_t perms)
221221void SensorMesh::sendAlert (const char * text) {
222222 int text_len = strlen (text);
223223
224- // send text message to all admins
224+ // send text message to all contacts with RECV_ALERT permission
225225 for (int i = 0 ; i < num_contacts; i++) {
226226 auto c = &contacts[i];
227- if (! c->isAdmin () ) continue ;
227+ if (( c->permissions & PERM_RECV_ALERTS) == 0 ) continue ; // contact does NOT want alerts
228228
229229 uint8_t data[MAX_PACKET_PAYLOAD];
230230 uint32_t now = getRTCClock ()->getCurrentTimeUnique (); // need different timestamp per packet
@@ -308,7 +308,7 @@ uint8_t SensorMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t*
308308 MESH_DEBUG_PRINTLN (" Login success!" );
309309 client->last_timestamp = sender_timestamp;
310310 client->last_activity = getRTCClock ()->getCurrentTime ();
311- client->permissions = PERM_IS_ADMIN;
311+ client->permissions = PERM_IS_ADMIN | PERM_RECV_ALERTS ;
312312 memcpy (client->shared_secret , secret, PUB_KEY_SIZE);
313313
314314 dirty_contacts_expiry = futureMillis (LAZY_CONTACTS_WRITE_DELAY);
@@ -542,7 +542,7 @@ SensorMesh::SensorMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::Millise
542542 _prefs.cr = LORA_CR;
543543 _prefs.tx_power_dbm = LORA_TX_POWER;
544544 _prefs.advert_interval = 1 ; // default to 2 minutes for NEW installs
545- _prefs.flood_advert_interval = 3 ; // 3 hours
545+ _prefs.flood_advert_interval = 0 ; // disabled
546546 _prefs.disable_fwd = true ;
547547 _prefs.flood_max = 64 ;
548548 _prefs.interference_threshold = 0 ; // disabled
@@ -604,6 +604,102 @@ void SensorMesh::setTxPower(uint8_t power_dbm) {
604604 radio_set_tx_power (power_dbm);
605605}
606606
607+ static uint8_t getDataSize (uint8_t type) {
608+ switch (type) {
609+ case LPP_GPS:
610+ return 9 ;
611+ case LPP_POLYLINE:
612+ return 8 ; // TODO: this is MINIMIUM
613+ case LPP_GYROMETER:
614+ case LPP_ACCELEROMETER:
615+ return 6 ;
616+ case LPP_GENERIC_SENSOR:
617+ case LPP_FREQUENCY:
618+ case LPP_DISTANCE:
619+ case LPP_ENERGY:
620+ case LPP_UNIXTIME:
621+ return 4 ;
622+ case LPP_COLOUR:
623+ return 3 ;
624+ case LPP_ANALOG_INPUT:
625+ case LPP_ANALOG_OUTPUT:
626+ case LPP_LUMINOSITY:
627+ case LPP_TEMPERATURE:
628+ case LPP_CONCENTRATION:
629+ case LPP_BAROMETRIC_PRESSURE:
630+ case LPP_ALTITUDE:
631+ case LPP_VOLTAGE:
632+ case LPP_CURRENT:
633+ case LPP_DIRECTION:
634+ case LPP_POWER:
635+ return 2 ;
636+ }
637+ return 1 ;
638+ }
639+
640+ static uint32_t getMultiplier (uint8_t type) {
641+ switch (type) {
642+ case LPP_CURRENT:
643+ case LPP_DISTANCE:
644+ case LPP_ENERGY:
645+ return 1000 ;
646+ case LPP_VOLTAGE:
647+ case LPP_ANALOG_INPUT:
648+ case LPP_ANALOG_OUTPUT:
649+ return 100 ;
650+ case LPP_TEMPERATURE:
651+ case LPP_BAROMETRIC_PRESSURE:
652+ return 10 ;
653+ }
654+ return 1 ;
655+ }
656+
657+ static bool isSigned (uint8_t type) {
658+ return type == LPP_ALTITUDE || type == LPP_TEMPERATURE || type == LPP_GYROMETER ||
659+ type == LPP_ANALOG_INPUT || type == LPP_ANALOG_OUTPUT || type == LPP_GPS || type == LPP_ACCELEROMETER;
660+ }
661+
662+ static float getFloat (const uint8_t * buffer, uint8_t size, uint32_t multiplier, bool is_signed) {
663+ uint32_t value = 0 ;
664+ for (uint8_t i = 0 ; i < size; i++) {
665+ value = (value << 8 ) + buffer[i];
666+ }
667+
668+ int sign = 1 ;
669+ if (is_signed) {
670+ uint32_t bit = 1ul << ((size * 8 ) - 1 );
671+ if ((value & bit) == bit) {
672+ value = (bit << 1 ) - value;
673+ sign = -1 ;
674+ }
675+ }
676+ return sign * ((float ) value / multiplier);
677+ }
678+
679+ float SensorMesh::getTelemValue (uint8_t channel, uint8_t type) {
680+ auto buf = telemetry.getBuffer ();
681+ uint8_t size = telemetry.getSize ();
682+ uint8_t i = 0 ;
683+
684+ while (i + 2 < size) {
685+ // Get channel #
686+ uint8_t ch = buf[i++];
687+ // Get data type
688+ uint8_t t = buf[i++];
689+ uint8_t sz = getDataSize (t);
690+
691+ if (ch == channel && t == type) {
692+ return getFloat (&buf[i], sz, getMultiplier (t), isSigned (t));
693+ }
694+ i += sz; // skip
695+ }
696+ return 0 .0f ; // not found
697+ }
698+
699+ bool SensorMesh::getGPS (uint8_t channel, float & lat, float & lon, float & alt) {
700+ return false ; // TODO
701+ }
702+
607703void SensorMesh::loop () {
608704 mesh::Mesh::loop ();
609705
@@ -629,21 +725,6 @@ void SensorMesh::loop() {
629725
630726 onSensorDataRead ();
631727
632- // save telemetry to time-series datastore
633- File file = openAppend (_fs, " /s_data" );
634- if (file) {
635- file.write ((uint8_t *)&curr, 4 ); // start record with RTC timestamp
636- uint8_t tlen = telemetry.getSize ();
637- file.write (&tlen, 1 );
638- file.write (telemetry.getBuffer (), tlen);
639- uint8_t zero = 0 ;
640- while (tlen < MAX_PACKET_PAYLOAD - 4 ) { // pad with zeroes, for fixed record length
641- file.write (&zero, 1 );
642- tlen++;
643- }
644- file.close ();
645- }
646-
647728 last_read_time = curr;
648729 }
649730
0 commit comments