Skip to content

Commit 112b360

Browse files
author
Scott Powell
committed
* implemented encoding responses to REQ_TYPE_GET_AVG_MIN_MAX
1 parent 2943534 commit 112b360

File tree

1 file changed

+114
-73
lines changed

1 file changed

+114
-73
lines changed

examples/simple_sensor/SensorMesh.cpp

Lines changed: 114 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
143238
uint8_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-
679720
float SensorMesh::getTelemValue(uint8_t channel, uint8_t type) {
680721
auto buf = telemetry.getBuffer();
681722
uint8_t size = telemetry.getSize();

0 commit comments

Comments
 (0)