@@ -140,6 +140,101 @@ void SensorMesh::saveContacts() {
140140 }
141141}
142142
143+ static uint8_t getDataSize (uint8_t type) {
144+ switch (type) {
145+ case LPP_GPS:
146+ return 9 ;
147+ case LPP_POLYLINE:
148+ return 8 ; // TODO: this is MINIMIUM
149+ case LPP_GYROMETER:
150+ case LPP_ACCELEROMETER:
151+ return 6 ;
152+ case LPP_GENERIC_SENSOR:
153+ case LPP_FREQUENCY:
154+ case LPP_DISTANCE:
155+ case LPP_ENERGY:
156+ case LPP_UNIXTIME:
157+ return 4 ;
158+ case LPP_COLOUR:
159+ return 3 ;
160+ case LPP_ANALOG_INPUT:
161+ case LPP_ANALOG_OUTPUT:
162+ case LPP_LUMINOSITY:
163+ case LPP_TEMPERATURE:
164+ case LPP_CONCENTRATION:
165+ case LPP_BAROMETRIC_PRESSURE:
166+ case LPP_ALTITUDE:
167+ case LPP_VOLTAGE:
168+ case LPP_CURRENT:
169+ case LPP_DIRECTION:
170+ case LPP_POWER:
171+ return 2 ;
172+ }
173+ return 1 ;
174+ }
175+
176+ static uint32_t getMultiplier (uint8_t type) {
177+ switch (type) {
178+ case LPP_CURRENT:
179+ case LPP_DISTANCE:
180+ case LPP_ENERGY:
181+ return 1000 ;
182+ case LPP_VOLTAGE:
183+ case LPP_ANALOG_INPUT:
184+ case LPP_ANALOG_OUTPUT:
185+ return 100 ;
186+ case LPP_TEMPERATURE:
187+ case LPP_BAROMETRIC_PRESSURE:
188+ return 10 ;
189+ }
190+ return 1 ;
191+ }
192+
193+ static bool isSigned (uint8_t type) {
194+ return type == LPP_ALTITUDE || type == LPP_TEMPERATURE || type == LPP_GYROMETER ||
195+ type == LPP_ANALOG_INPUT || type == LPP_ANALOG_OUTPUT || type == LPP_GPS || type == LPP_ACCELEROMETER;
196+ }
197+
198+ static float getFloat (const uint8_t * buffer, uint8_t size, uint32_t multiplier, bool is_signed) {
199+ uint32_t value = 0 ;
200+ for (uint8_t i = 0 ; i < size; i++) {
201+ value = (value << 8 ) + buffer[i];
202+ }
203+
204+ int sign = 1 ;
205+ if (is_signed) {
206+ uint32_t bit = 1ul << ((size * 8 ) - 1 );
207+ if ((value & bit) == bit) {
208+ value = (bit << 1 ) - value;
209+ sign = -1 ;
210+ }
211+ }
212+ return sign * ((float ) value / multiplier);
213+ }
214+
215+ static uint8_t putFloat (uint8_t * dest, float value, uint8_t size, uint32_t multiplier, bool is_signed) {
216+ // check sign
217+ bool sign = value < 0 ;
218+ if (sign) value = -value;
219+
220+ // get value to store
221+ uint32_t v = value * multiplier;
222+
223+ // format an uint32_t as if it was an int32_t
224+ if (is_signed & sign) {
225+ uint32_t mask = (1 << (size * 8 )) - 1 ;
226+ v = v & mask;
227+ if (sign) v = mask - v + 1 ;
228+ }
229+
230+ // add bytes (MSB first)
231+ for (uint8_t i=1 ; i<=size; i++) {
232+ dest[size - i] = (v & 0xFF );
233+ v >>= 8 ;
234+ }
235+ return size;
236+ }
237+
143238uint8_t SensorMesh::handleRequest (uint16_t perms, uint32_t sender_timestamp, uint8_t req_type, uint8_t * payload, size_t payload_len) {
144239 memcpy (reply_data, &sender_timestamp, 4 ); // reflect sender_timestamp back in response packet (kind of like a 'tag')
145240
@@ -167,7 +262,25 @@ uint8_t SensorMesh::handleRequest(uint16_t perms, uint32_t sender_timestamp, uin
167262 } else {
168263 n = 0 ;
169264 }
170- return 0 ; // TODO: encode data[0..n)
265+
266+ uint8_t ofs = 4 ;
267+ {
268+ uint32_t now = getRTCClock ()->getCurrentTime ();
269+ memcpy (&reply_data[ofs], &now, 4 ); ofs += 4 ;
270+ }
271+
272+ for (int i = 0 ; i < n; i++) {
273+ auto d = &data[i];
274+ reply_data[ofs++] = d->_channel ;
275+ reply_data[ofs++] = d->_lpp_type ;
276+ uint8_t sz = getDataSize (d->_lpp_type );
277+ uint32_t mult = getMultiplier (d->_lpp_type );
278+ bool is_signed = isSigned (d->_lpp_type );
279+ ofs += putFloat (&reply_data[ofs], d->_min , sz, mult, is_signed);
280+ ofs += putFloat (&reply_data[ofs], d->_max , sz, mult, is_signed);
281+ ofs += putFloat (&reply_data[ofs], d->_avg , sz, mult, is_signed);
282+ }
283+ return ofs;
171284 }
172285 return 0 ; // unknown command
173286}
@@ -604,78 +717,6 @@ void SensorMesh::setTxPower(uint8_t power_dbm) {
604717 radio_set_tx_power (power_dbm);
605718}
606719
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-
679720float SensorMesh::getTelemValue (uint8_t channel, uint8_t type) {
680721 auto buf = telemetry.getBuffer ();
681722 uint8_t size = telemetry.getSize ();
0 commit comments