Cayenne LPP2 protocol enhancements

This commit is contained in:
Klaus K Wilting 2019-02-24 13:35:22 +01:00
parent 98797c0fe1
commit 7dd82eb5ee
4 changed files with 84 additions and 31 deletions

View File

@ -49,6 +49,7 @@ public:
void addBME(bmeStatus_t value); void addBME(bmeStatus_t value);
void addButton(uint8_t value); void addButton(uint8_t value);
void addSensor(uint8_t[]); void addSensor(uint8_t[]);
void addTime(time_t value);
#if PAYLOAD_ENCODER == 1 // format plain #if PAYLOAD_ENCODER == 1 // format plain

View File

@ -49,28 +49,12 @@
#define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy #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] #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 // Hardware settings
#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
#define RGBLUMINOSITY 30 // RGB LED luminosity [default = 30%] #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 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] #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 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 #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] #define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds]
// settings for syncing time of node with external time source // 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_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] #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 // 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 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 #define STANDARD_TIME {"CET ", Last, Sun, Oct, 3, 60} // Central European Standard Time
// 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 // LMIC settings
// moved to src/lmic_config.h // -> in src/lmic_config.h

View File

@ -126,6 +126,14 @@ void PayloadConvert::addButton(uint8_t value) {
#endif #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 ---------- /* ---------------- packed format with LoRa serialization Encoder ----------
*/ */
// derived from // derived from
@ -133,7 +141,9 @@ void PayloadConvert::addButton(uint8_t value) {
#elif PAYLOAD_ENCODER == 2 #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) { void PayloadConvert::addAlarm(int8_t rssi, uint8_t msg) {
writeUint8(rssi); writeUint8(rssi);
@ -208,6 +218,11 @@ void PayloadConvert::addButton(uint8_t value) {
#endif #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) { void PayloadConvert::intToBytes(uint8_t pos, int32_t i, uint8_t byteSize) {
for (uint8_t x = 0; x < byteSize; x++) { for (uint8_t x = 0; x < byteSize; x++) {
buffer[x + pos] = (byte)(i >> (x * 8)); buffer[x + pos] = (byte)(i >> (x * 8));
@ -436,6 +451,24 @@ void PayloadConvert::addButton(uint8_t value) {
#endif // HAS_BUTTON #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 #else
#error No valid payload converter defined! #error No valid payload converter defined!
#endif #endif

View File

@ -8,15 +8,26 @@ void SendPayload(uint8_t port, sendprio_t prio) {
SendBuffer.MessageSize = payload.getSize(); SendBuffer.MessageSize = payload.getSize();
switch (PAYLOAD_ENCODER) { switch (PAYLOAD_ENCODER) {
case 1: case 1: // plain -> no mapping
case 2: case 2: // packed -> no mapping
SendBuffer.MessagePort = port; SendBuffer.MessagePort = port;
break; break;
case 3: case 3: // Cayenne LPP dynamic -> all payload goes out on same port
SendBuffer.MessagePort = LPP1PORT; SendBuffer.MessagePort = CAYENNE_LPP1;
break; break;
case 4: case 4: // Cayenne LPP packed -> we need to map some paxcounter ports
SendBuffer.MessagePort = LPP2PORT; 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; break;
default: default:
SendBuffer.MessagePort = port; SendBuffer.MessagePort = port;