From 7dd82eb5eeea4610bc044fa41ed740305c3bccff Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Sun, 24 Feb 2019 13:35:22 +0100 Subject: [PATCH] Cayenne LPP2 protocol enhancements --- include/payload.h | 1 + src/paxcounter.conf | 54 ++++++++++++++++++++++++++------------------- src/payload.cpp | 37 +++++++++++++++++++++++++++++-- src/senddata.cpp | 23 ++++++++++++++----- 4 files changed, 84 insertions(+), 31 deletions(-) diff --git a/include/payload.h b/include/payload.h index 686a5b62..d8fe468b 100644 --- a/include/payload.h +++ b/include/payload.h @@ -49,6 +49,7 @@ public: void addBME(bmeStatus_t value); void addButton(uint8_t value); void addSensor(uint8_t[]); + void addTime(time_t value); #if PAYLOAD_ENCODER == 1 // format plain diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 0579e8b5..ac0a22b7 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -11,7 +11,7 @@ // Payload send cycle and encoding #define SEND_SECS 30 // payload send cycle [seconds/2] -> 60 sec. -#define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=CayenneLPP dynamic, 4=CayenneLPP packed +#define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=Cayenne LPP dynamic, 4=Cayenne LPP packed // Set this to include BLE counting and vendor filter functions #define VENDORFILTER 1 // comment out if you want to count things, not people @@ -49,28 +49,12 @@ #define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy #define SEND_QUEUE_SIZE 10 // maximum number of messages in payload send queue [1 = no queue] -// Ports on which the device sends and listenes on LoRaWAN and SPI -#define COUNTERPORT 1 // Port on which device sends counts -#define RCMDPORT 2 // Port on which device listenes for remote commands -#define STATUSPORT 2 // Port on which device sends remote command results -#define CONFIGPORT 3 // Port on which device sends config query results -#define GPSPORT 4 // Port on which device sends gps data -#define BUTTONPORT 5 // Port on which device sends button pressed signal -#define LPP1PORT 1 // Port for Cayenne LPP 1.0 dynamic sensor encoding -#define LPP2PORT 2 // Port for Cayenne LPP 2.0 packed sensor encoding -#define BEACONPORT 6 // Port on which device sends beacon alarms -#define BMEPORT 7 // Port on which device sends BME680 sensor data -#define BATTPORT 8 // Port on which device sends battery voltage data -#define SENSOR1PORT 10 // Port on which device sends User sensor #1 data -#define SENSOR2PORT 11 // Port on which device sends User sensor #2 data -#define SENSOR3PORT 12 // Port on which device sends User sensor #3 data - -// Some hardware settings +// Hardware settings #define RGBLUMINOSITY 30 // RGB LED luminosity [default = 30%] #define DISPLAYREFRESH_MS 40 // OLED refresh cycle in ms [default = 40] -> 1000/40 = 25 frames per second #define HOMECYCLE 30 // house keeping cycle in seconds [default = 30 secs] -// Settings for BME680 environmental sensor (if present) +// Settings for BME680 environmental sensor #define BME_TEMP_OFFSET 5.0f // Offset sensor on chip temp <-> ambient temp [default = 5°C] #define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // update every 360 minutes = 4 times a day @@ -82,12 +66,36 @@ #define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds] // settings for syncing time of node with external time source -#define TIME_SYNC_INTERVAL 10 // sync time each .. minutes from time source (GPS/LORA) [default = 10], comment out means off -#define TIME_SYNC_LORA 1 // use LORA network as time source, comment out means off [default = off] +#define TIME_SYNC_INTERVAL 2 // sync time attempt each .. minutes from time source (GPS/LORA), comment out means [default = 5] +#define TIME_SYNC_LORA 1 // use LORA network as time source, comment out means off [default = off] // time zone, see https://github.com/JChristensen/Timezone/blob/master/examples/WorldClock/WorldClock.ino #define DAYLIGHT_TIME {"CEST", Last, Sun, Mar, 2, 120} // Central European Summer Time #define STANDARD_TIME {"CET ", Last, Sun, Oct, 3, 60} // Central European Standard Time -// LMIC settings -// moved to src/lmic_config.h \ No newline at end of file +// Ports on which the device sends and listenes on LoRaWAN and SPI +#define COUNTERPORT 1 // counts +#define RCMDPORT 2 // remote commands +#define STATUSPORT 2 // remote command results +#define CONFIGPORT 3 // config query results +#define GPSPORT 4 // gps +#define BUTTONPORT 5 // button pressed signal +#define BEACONPORT 6 // beacon alarms +#define BMEPORT 7 // BME680 sensor +#define BATTPORT 8 // battery voltage +#define TIMEPORT 9 // time +#define SENSOR1PORT 10 // user sensor #1 +#define SENSOR2PORT 11 // user sensor #2 +#define SENSOR3PORT 12 // user sensor #3 + +// Cayenne LPP Ports, see https://community.mydevices.com/t/cayenne-lpp-2-0/7510 +#define CAYENNE_LPP1 1 // dynamic sensor payload (LPP 1.0) +#define CAYENNE_LPP2 2 // packed sensor payload (LPP 2.0) +#define CAYENNE_GPS 3 // full scale GPS payload +#define CAYENNE_ACTUATOR 10 // actuator commands +#define CAYENNE_DEVICECONFIG 11 // device period configuration +#define CAYENNE_SENSORREAD 13 // sensor period configuration +#define CAYENNE_SENSORENABLE 14 // sensor enable configuration + +// LMIC settings +// -> in src/lmic_config.h \ No newline at end of file diff --git a/src/payload.cpp b/src/payload.cpp index eebe88d7..b94c07f3 100644 --- a/src/payload.cpp +++ b/src/payload.cpp @@ -126,6 +126,14 @@ void PayloadConvert::addButton(uint8_t value) { #endif } +void PayloadConvert::addTime(time_t value) { + uint32_t time = (uint32_t)value; + buffer[cursor++] = (byte)((time & 0xFF000000) >> 24); + buffer[cursor++] = (byte)((time & 0x00FF0000) >> 16); + buffer[cursor++] = (byte)((time & 0x0000FF00) >> 8); + buffer[cursor++] = (byte)((time & 0x000000FF)); +} + /* ---------------- packed format with LoRa serialization Encoder ---------- */ // derived from @@ -133,7 +141,9 @@ void PayloadConvert::addButton(uint8_t value) { #elif PAYLOAD_ENCODER == 2 -void PayloadConvert::addCount(uint16_t value, uint8_t snifftype) { writeUint16(value); } +void PayloadConvert::addCount(uint16_t value, uint8_t snifftype) { + writeUint16(value); +} void PayloadConvert::addAlarm(int8_t rssi, uint8_t msg) { writeUint8(rssi); @@ -208,6 +218,11 @@ void PayloadConvert::addButton(uint8_t value) { #endif } +void PayloadConvert::addTime(time_t value) { + uint32_t time = (uint32_t)value; + writeUint32(time); +} + void PayloadConvert::intToBytes(uint8_t pos, int32_t i, uint8_t byteSize) { for (uint8_t x = 0; x < byteSize; x++) { buffer[x + pos] = (byte)(i >> (x * 8)); @@ -282,7 +297,7 @@ void PayloadConvert::writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f, #elif (PAYLOAD_ENCODER == 3 || PAYLOAD_ENCODER == 4) void PayloadConvert::addCount(uint16_t value, uint8_t snifftype) { - switch(snifftype) { + switch (snifftype) { case MAC_SNIFF_WIFI: #if (PAYLOAD_ENCODER == 3) buffer[cursor++] = LPP_COUNT_WIFI_CHANNEL; @@ -436,6 +451,24 @@ void PayloadConvert::addButton(uint8_t value) { #endif // HAS_BUTTON } +void PayloadConvert::addTime(time_t value) { +#if (PAYLOAD_ENCODER == 4) + uint32_t t = (uint32_t)value; + uint32_t tx_period = (uint32_t)SEND_SECS * 2; + buffer[cursor++] = 0x03; // set config mask to UTCTime + TXPeriod + // UTCTime in seconds + buffer[cursor++] = (byte)((t & 0xFF000000) >> 24); + buffer[cursor++] = (byte)((t & 0x00FF0000) >> 16); + buffer[cursor++] = (byte)((t & 0x0000FF00) >> 8); + buffer[cursor++] = (byte)((t & 0x000000FF)); + // TXPeriod in seconds + buffer[cursor++] = (byte)((tx_period & 0xFF000000) >> 24); + buffer[cursor++] = (byte)((tx_period & 0x00FF0000) >> 16); + buffer[cursor++] = (byte)((tx_period & 0x0000FF00) >> 8); + buffer[cursor++] = (byte)((tx_period & 0x000000FF)); +#endif +} + #else #error No valid payload converter defined! #endif \ No newline at end of file diff --git a/src/senddata.cpp b/src/senddata.cpp index c13d907f..386ab6ab 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -8,15 +8,26 @@ void SendPayload(uint8_t port, sendprio_t prio) { SendBuffer.MessageSize = payload.getSize(); switch (PAYLOAD_ENCODER) { - case 1: - case 2: + case 1: // plain -> no mapping + case 2: // packed -> no mapping SendBuffer.MessagePort = port; break; - case 3: - SendBuffer.MessagePort = LPP1PORT; + case 3: // Cayenne LPP dynamic -> all payload goes out on same port + SendBuffer.MessagePort = CAYENNE_LPP1; break; - case 4: - SendBuffer.MessagePort = LPP2PORT; + case 4: // Cayenne LPP packed -> we need to map some paxcounter ports + SendBuffer.MessagePort = CAYENNE_LPP2; + switch (SendBuffer.MessagePort) { + case COUNTERPORT: + SendBuffer.MessagePort = CAYENNE_LPP2; + break; + case RCMDPORT: + SendBuffer.MessagePort = CAYENNE_ACTUATOR; + break; + case TIMEPORT: + SendBuffer.MessagePort = CAYENNE_DEVICECONFIG; + break; + } break; default: SendBuffer.MessagePort = port;