2018-06-16 13:18:36 +02:00
|
|
|
|
|
|
|
#include "globals.h"
|
|
|
|
#include "payload.h"
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
PayloadConvert::PayloadConvert(uint8_t size) {
|
2018-06-16 13:18:36 +02:00
|
|
|
buffer = (uint8_t *)malloc(size);
|
|
|
|
cursor = 0;
|
|
|
|
}
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
PayloadConvert::~PayloadConvert(void) { free(buffer); }
|
2018-06-16 13:18:36 +02:00
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::reset(void) { cursor = 0; }
|
2018-06-16 13:18:36 +02:00
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
uint8_t PayloadConvert::getSize(void) { return cursor; }
|
2018-06-16 13:18:36 +02:00
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
uint8_t *PayloadConvert::getBuffer(void) { return buffer; }
|
2018-06-16 13:18:36 +02:00
|
|
|
|
2018-07-21 13:36:49 +02:00
|
|
|
/* ---------------- plain format without special encoding ---------- */
|
|
|
|
|
|
|
|
#if PAYLOAD_ENCODER == 1
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::addCount(uint16_t value1, uint16_t value2) {
|
2018-07-22 16:12:46 +02:00
|
|
|
buffer[cursor++] = highByte(value1);
|
|
|
|
buffer[cursor++] = lowByte(value1);
|
|
|
|
buffer[cursor++] = highByte(value2);
|
|
|
|
buffer[cursor++] = lowByte(value2);
|
2018-06-16 13:18:36 +02:00
|
|
|
}
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::addConfig(configData_t value) {
|
2018-06-16 13:18:36 +02:00
|
|
|
buffer[cursor++] = value.lorasf;
|
2018-07-15 19:41:22 +02:00
|
|
|
buffer[cursor++] = value.txpower;
|
2018-06-16 13:18:36 +02:00
|
|
|
buffer[cursor++] = value.adrmode;
|
|
|
|
buffer[cursor++] = value.screensaver;
|
|
|
|
buffer[cursor++] = value.screenon;
|
|
|
|
buffer[cursor++] = value.countermode;
|
2018-07-22 16:12:46 +02:00
|
|
|
buffer[cursor++] = highByte(value.rssilimit);
|
|
|
|
buffer[cursor++] = lowByte(value.rssilimit);
|
2018-06-16 13:18:36 +02:00
|
|
|
buffer[cursor++] = value.sendcycle;
|
|
|
|
buffer[cursor++] = value.wifichancycle;
|
|
|
|
buffer[cursor++] = value.blescantime;
|
|
|
|
buffer[cursor++] = value.blescan;
|
|
|
|
buffer[cursor++] = value.wifiant;
|
|
|
|
buffer[cursor++] = value.vendorfilter;
|
|
|
|
buffer[cursor++] = value.rgblum;
|
|
|
|
buffer[cursor++] = value.gpsmode;
|
|
|
|
memcpy(buffer + cursor, value.version, 10);
|
2018-06-16 19:50:36 +02:00
|
|
|
cursor += 10;
|
2018-06-16 13:18:36 +02:00
|
|
|
}
|
|
|
|
|
2018-07-21 17:14:27 +02:00
|
|
|
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime,
|
|
|
|
float cputemp) {
|
2018-07-22 16:12:46 +02:00
|
|
|
uint32_t temp = (uint32_t)cputemp;
|
|
|
|
buffer[cursor++] = highByte(voltage);
|
|
|
|
buffer[cursor++] = lowByte(voltage);
|
2018-07-22 17:35:26 +02:00
|
|
|
buffer[cursor++] = (byte)((uptime & 0xFF00000000000000) >> 56);
|
|
|
|
buffer[cursor++] = (byte)((uptime & 0x00FF000000000000) >> 48);
|
|
|
|
buffer[cursor++] = (byte)((uptime & 0x0000FF0000000000) >> 40);
|
|
|
|
buffer[cursor++] = (byte)((uptime & 0x000000FF00000000) >> 32);
|
|
|
|
buffer[cursor++] = (byte)((uptime & 0x00000000FF000000) >> 24);
|
|
|
|
buffer[cursor++] = (byte)((uptime & 0x0000000000FF0000) >> 16);
|
|
|
|
buffer[cursor++] = (byte)((uptime & 0x000000000000FF00) >> 8);
|
|
|
|
buffer[cursor++] = (byte)((uptime & 0x00000000000000FF));
|
|
|
|
buffer[cursor++] = (byte)((temp & 0xFF000000) >> 24);
|
|
|
|
buffer[cursor++] = (byte)((temp & 0x00FF0000) >> 16);
|
|
|
|
buffer[cursor++] = (byte)((temp & 0x0000FF00) >> 8);
|
|
|
|
buffer[cursor++] = (byte)((temp & 0x000000FF));
|
2018-06-16 19:50:36 +02:00
|
|
|
}
|
|
|
|
|
2018-07-21 18:25:03 +02:00
|
|
|
#ifdef HAS_GPS
|
|
|
|
void PayloadConvert::addGPS(gpsStatus_t value) {
|
2018-07-22 17:35:26 +02:00
|
|
|
buffer[cursor++] = (byte)((value.latitude & 0xFF000000) >> 24);
|
|
|
|
buffer[cursor++] = (byte)((value.latitude & 0x00FF0000) >> 16);
|
|
|
|
buffer[cursor++] = (byte)((value.latitude & 0x0000FF00) >> 8);
|
|
|
|
buffer[cursor++] = (byte)((value.latitude & 0x000000FF));
|
|
|
|
buffer[cursor++] = (byte)((value.longitude & 0xFF000000) >> 24);
|
|
|
|
buffer[cursor++] = (byte)((value.longitude & 0x00FF0000) >> 16);
|
|
|
|
buffer[cursor++] = (byte)((value.longitude & 0x0000FF00) >> 8);
|
|
|
|
buffer[cursor++] = (byte)((value.longitude & 0x000000FF));
|
2018-07-21 18:25:03 +02:00
|
|
|
buffer[cursor++] = value.satellites;
|
2018-07-22 16:12:46 +02:00
|
|
|
buffer[cursor++] = highByte(value.hdop);
|
|
|
|
buffer[cursor++] = lowByte(value.hdop);
|
|
|
|
buffer[cursor++] = highByte(value.altitude);
|
|
|
|
buffer[cursor++] = lowByte(value.altitude);
|
2018-07-21 18:25:03 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAS_BUTTON
|
|
|
|
void PayloadConvert::addButton(uint8_t value) { buffer[cursor++] = value; }
|
|
|
|
#endif
|
|
|
|
|
2018-06-16 19:50:36 +02:00
|
|
|
/* ---------------- packed format with LoRa serialization Encoder ---------- */
|
2018-06-17 22:41:32 +02:00
|
|
|
// derived from
|
|
|
|
// https://github.com/thesolarnomad/lora-serialization/blob/master/src/LoraEncoder.cpp
|
2018-06-16 19:50:36 +02:00
|
|
|
|
2018-07-21 13:36:49 +02:00
|
|
|
#elif PAYLOAD_ENCODER == 2
|
2018-06-16 19:50:36 +02:00
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::addCount(uint16_t value1, uint16_t value2) {
|
2018-06-17 22:41:32 +02:00
|
|
|
writeUint16(value1);
|
|
|
|
writeUint16(value2);
|
2018-06-16 19:50:36 +02:00
|
|
|
}
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::addConfig(configData_t value) {
|
2018-06-17 22:41:32 +02:00
|
|
|
writeUint8(value.lorasf);
|
2018-07-15 19:41:22 +02:00
|
|
|
writeUint8(value.txpower);
|
2018-06-17 22:41:32 +02:00
|
|
|
writeUint16(value.rssilimit);
|
|
|
|
writeUint8(value.sendcycle);
|
|
|
|
writeUint8(value.wifichancycle);
|
|
|
|
writeUint8(value.blescantime);
|
|
|
|
writeUint8(value.rgblum);
|
|
|
|
writeBitmap(value.adrmode ? true : false, value.screensaver ? true : false,
|
|
|
|
value.screenon ? true : false, value.countermode ? true : false,
|
|
|
|
value.blescan ? true : false, value.wifiant ? true : false,
|
|
|
|
value.vendorfilter ? true : false, value.gpsmode ? true : false);
|
|
|
|
}
|
|
|
|
|
2018-07-21 17:14:27 +02:00
|
|
|
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime,
|
|
|
|
float cputemp) {
|
2018-06-17 22:41:32 +02:00
|
|
|
writeUint16(voltage);
|
2018-06-18 09:15:57 +02:00
|
|
|
writeUptime(uptime);
|
2018-06-17 22:41:32 +02:00
|
|
|
writeTemperature(cputemp);
|
|
|
|
}
|
|
|
|
|
2018-07-21 18:25:03 +02:00
|
|
|
#ifdef HAS_GPS
|
|
|
|
void PayloadConvert::addGPS(gpsStatus_t value) {
|
|
|
|
writeLatLng(value.latitude, value.longitude);
|
|
|
|
writeUint8(value.satellites);
|
|
|
|
writeUint16(value.hdop);
|
|
|
|
writeUint16(value.altitude);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAS_BUTTON
|
|
|
|
void PayloadConvert::addButton(uint8_t value) { writeUint8(value); }
|
|
|
|
#endif
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::intToBytes(uint8_t pos, int32_t i, uint8_t byteSize) {
|
2018-06-17 22:41:32 +02:00
|
|
|
for (uint8_t x = 0; x < byteSize; x++) {
|
2018-06-18 00:01:14 +02:00
|
|
|
buffer[x + pos] = (byte)(i >> (x * 8));
|
2018-06-17 22:41:32 +02:00
|
|
|
}
|
2018-06-18 00:01:14 +02:00
|
|
|
cursor += byteSize;
|
2018-06-17 22:41:32 +02:00
|
|
|
}
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::writeUptime(uint64_t uptime) {
|
2018-06-18 09:15:57 +02:00
|
|
|
intToBytes(cursor, uptime, 8);
|
2018-06-17 22:41:32 +02:00
|
|
|
}
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::writeLatLng(double latitude, double longitude) {
|
2018-06-18 09:15:57 +02:00
|
|
|
intToBytes(cursor, latitude, 4);
|
|
|
|
intToBytes(cursor, longitude, 4);
|
2018-06-17 22:41:32 +02:00
|
|
|
}
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::writeUint16(uint16_t i) { intToBytes(cursor, i, 2); }
|
2018-06-17 22:41:32 +02:00
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::writeUint8(uint8_t i) { intToBytes(cursor, i, 1); }
|
2018-06-17 22:41:32 +02:00
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::writeHumidity(float humidity) {
|
2018-06-17 22:41:32 +02:00
|
|
|
int16_t h = (int16_t)(humidity * 100);
|
2018-06-18 09:15:57 +02:00
|
|
|
intToBytes(cursor, h, 2);
|
2018-06-17 22:41:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Uses a 16bit two's complement with two decimals, so the range is
|
|
|
|
* -327.68 to +327.67 degrees
|
|
|
|
*/
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::writeTemperature(float temperature) {
|
2018-06-17 22:41:32 +02:00
|
|
|
int16_t t = (int16_t)(temperature * 100);
|
|
|
|
if (temperature < 0) {
|
|
|
|
t = ~-t;
|
|
|
|
t = t + 1;
|
|
|
|
}
|
2018-06-18 00:39:46 +02:00
|
|
|
buffer[cursor++] = (byte)((t >> 8) & 0xFF);
|
|
|
|
buffer[cursor++] = (byte)t & 0xFF;
|
2018-06-17 22:41:32 +02:00
|
|
|
}
|
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f,
|
2018-07-21 17:14:27 +02:00
|
|
|
bool g, bool h) {
|
2018-06-17 22:41:32 +02:00
|
|
|
uint8_t bitmap = 0;
|
|
|
|
// LSB first
|
|
|
|
bitmap |= (a & 1) << 7;
|
|
|
|
bitmap |= (b & 1) << 6;
|
|
|
|
bitmap |= (c & 1) << 5;
|
|
|
|
bitmap |= (d & 1) << 4;
|
|
|
|
bitmap |= (e & 1) << 3;
|
|
|
|
bitmap |= (f & 1) << 2;
|
|
|
|
bitmap |= (g & 1) << 1;
|
|
|
|
bitmap |= (h & 1) << 0;
|
|
|
|
writeUint8(bitmap);
|
2018-06-16 19:50:36 +02:00
|
|
|
}
|
|
|
|
|
2018-06-16 23:14:49 +02:00
|
|
|
/* ---------------- Cayenne LPP format ---------- */
|
2018-07-21 17:14:27 +02:00
|
|
|
// http://community.mydevices.com/t/cayenne-lpp-2-0/7510
|
2018-06-16 23:14:49 +02:00
|
|
|
|
2018-07-21 17:14:27 +02:00
|
|
|
#elif (PAYLOAD_ENCODER == 3 || PAYLOAD_ENCODER == 4)
|
2018-06-16 23:14:49 +02:00
|
|
|
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::addCount(uint16_t value1, uint16_t value2) {
|
2018-07-21 13:54:19 +02:00
|
|
|
uint16_t val1 = value1 * 100;
|
|
|
|
uint16_t val2 = value2 * 100;
|
2018-07-21 17:14:27 +02:00
|
|
|
#if (PAYLOAD_ENCODER == 3)
|
2018-06-16 23:14:49 +02:00
|
|
|
buffer[cursor++] = LPP_COUNT_WIFI_CHANNEL;
|
2018-07-21 17:14:27 +02:00
|
|
|
#endif
|
2018-06-17 13:24:20 +02:00
|
|
|
buffer[cursor++] = LPP_ANALOG_INPUT; // workaround, type meter not found?
|
2018-07-22 16:12:46 +02:00
|
|
|
buffer[cursor++] = highByte(val1);
|
|
|
|
buffer[cursor++] = lowByte(val1);
|
2018-07-21 17:14:27 +02:00
|
|
|
#if (PAYLOAD_ENCODER == 3)
|
2018-06-16 23:14:49 +02:00
|
|
|
buffer[cursor++] = LPP_COUNT_BLE_CHANNEL;
|
2018-07-21 17:14:27 +02:00
|
|
|
#endif
|
2018-06-17 13:24:20 +02:00
|
|
|
buffer[cursor++] = LPP_ANALOG_INPUT; // workaround, type meter not found?
|
2018-07-22 16:12:46 +02:00
|
|
|
buffer[cursor++] = highByte(val2);
|
|
|
|
buffer[cursor++] = lowByte(val2);
|
2018-06-16 23:14:49 +02:00
|
|
|
}
|
|
|
|
|
2018-07-21 18:25:03 +02:00
|
|
|
void PayloadConvert::addConfig(configData_t value) {
|
|
|
|
#if (PAYLOAD_ENCODER == 3)
|
|
|
|
buffer[cursor++] = LPP_ADR_CHANNEL;
|
|
|
|
#endif
|
|
|
|
buffer[cursor++] = LPP_DIGITAL_INPUT;
|
|
|
|
buffer[cursor++] = value.adrmode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime,
|
|
|
|
float celsius) {
|
2018-07-22 16:44:51 +02:00
|
|
|
uint16_t temp = celsius * 10;
|
|
|
|
uint16_t volt = voltage / 10;
|
2018-07-22 17:35:26 +02:00
|
|
|
#ifdef HAS_BATTERY_PROBE
|
2018-07-21 18:25:03 +02:00
|
|
|
#if (PAYLOAD_ENCODER == 3)
|
|
|
|
buffer[cursor++] = LPP_BATT_CHANNEL;
|
|
|
|
#endif
|
|
|
|
buffer[cursor++] = LPP_ANALOG_INPUT;
|
2018-07-22 16:44:51 +02:00
|
|
|
buffer[cursor++] = highByte(volt);
|
|
|
|
buffer[cursor++] = lowByte(volt);
|
2018-07-22 17:35:26 +02:00
|
|
|
#endif
|
2018-07-21 18:25:03 +02:00
|
|
|
#if (PAYLOAD_ENCODER == 3)
|
|
|
|
buffer[cursor++] = LPP_TEMP_CHANNEL;
|
|
|
|
#endif
|
|
|
|
buffer[cursor++] = LPP_TEMPERATURE;
|
2018-07-22 16:44:51 +02:00
|
|
|
buffer[cursor++] = highByte(temp);
|
|
|
|
buffer[cursor++] = lowByte(temp);
|
2018-07-21 18:25:03 +02:00
|
|
|
}
|
|
|
|
|
2018-06-17 13:31:24 +02:00
|
|
|
#ifdef HAS_GPS
|
2018-07-19 22:33:37 +02:00
|
|
|
void PayloadConvert::addGPS(gpsStatus_t value) {
|
2018-06-17 11:07:29 +02:00
|
|
|
int32_t lat = value.latitude / 100;
|
|
|
|
int32_t lon = value.longitude / 100;
|
2018-07-21 13:36:49 +02:00
|
|
|
int32_t alt = value.altitude * 100;
|
2018-07-21 17:14:27 +02:00
|
|
|
#if (PAYLOAD_ENCODER == 3)
|
2018-06-16 23:14:49 +02:00
|
|
|
buffer[cursor++] = LPP_GPS_CHANNEL;
|
2018-07-21 17:14:27 +02:00
|
|
|
#endif
|
2018-06-16 23:14:49 +02:00
|
|
|
buffer[cursor++] = LPP_GPS;
|
2018-07-22 17:35:26 +02:00
|
|
|
buffer[cursor++] = (byte)((lat & 0xFF0000) >> 16);
|
|
|
|
buffer[cursor++] = (byte)((lat & 0x00FF00) >> 8);
|
|
|
|
buffer[cursor++] = (byte)((lat & 0x0000FF));
|
|
|
|
buffer[cursor++] = (byte)((lon & 0xFF0000) >> 16);
|
|
|
|
buffer[cursor++] = (byte)((lon & 0x00FF00) >> 8);
|
|
|
|
buffer[cursor++] = (byte)((lon & 0x0000FF));
|
|
|
|
buffer[cursor++] = (byte)((alt & 0xFF0000) >> 16);
|
|
|
|
buffer[cursor++] = (byte)((alt & 0x00FF00) >> 8);
|
|
|
|
buffer[cursor++] = (byte)((alt & 0x0000FF));
|
2018-06-16 23:14:49 +02:00
|
|
|
}
|
2018-06-17 13:31:24 +02:00
|
|
|
#endif
|
2018-06-16 23:14:49 +02:00
|
|
|
|
2018-07-21 18:25:03 +02:00
|
|
|
#ifdef HAS_BUTTON
|
|
|
|
void PayloadConvert::addButton(uint8_t value) {
|
2018-07-21 17:14:27 +02:00
|
|
|
#if (PAYLOAD_ENCODER == 3)
|
2018-07-21 18:25:03 +02:00
|
|
|
buffer[cursor++] = LPP_BUTTON_CHANNEL;
|
2018-07-21 17:14:27 +02:00
|
|
|
#endif
|
2018-06-16 23:14:49 +02:00
|
|
|
buffer[cursor++] = LPP_DIGITAL_INPUT;
|
2018-07-21 18:25:03 +02:00
|
|
|
buffer[cursor++] = value;
|
2018-06-16 23:14:49 +02:00
|
|
|
}
|
2018-07-21 17:14:27 +02:00
|
|
|
#endif
|
2018-07-19 22:33:37 +02:00
|
|
|
|
|
|
|
#else
|
|
|
|
#error "No valid payload converter defined"
|
2018-07-21 17:14:27 +02:00
|
|
|
#endif
|