diff --git a/API.md b/API.md index e14bf5a..4acaa3b 100644 --- a/API.md +++ b/API.md @@ -87,6 +87,27 @@ Example output: ] ``` +### Method: `decodeTTN` + +Decodes a byte array into a JsonObject (requires ArduinoJson library). The result is a json objects, each object name contain name type plus channel. The value can be a scalar or an object (for accelerometer, gyroscope and GPS data). The method call returns the number of decoded fields or 0 if error. + +```c +uint8_t decodeTTN(uint8_t *buffer, uint8_t size, JsonObject& root); +``` + +Example output: + +``` +{ + "gps_1": { + "latitude": 42.3518, + "longitude": -87.9094, + "altitude": 10 + } +} +``` + + ### Method: `getTypeName` Returns a pointer to a C-string containing the name of the requested type. diff --git a/decoders/decoder.js b/decoders/decoder.js index 0a0b41c..89c642e 100644 --- a/decoders/decoder.js +++ b/decoders/decoder.js @@ -41,11 +41,10 @@ function lppDecode(bytes) { var sensor_types = { - 0 : {'size': 1, 'name': 'digital_input', 'signed': false, 'divisor': 1}, - 1 : {'size': 1, 'name': 'digital_output', 'signed': false, 'divisor': 1}, - 2 : {'size': 2, 'name': 'analog_input', 'signed': true , 'divisor': 100}, - 3 : {'size': 2, 'name': 'analog_output', 'signed': true , 'divisor': 100}, - 4 : {'size': 2, 'name': 'counter', 'signed': false, 'divisor': 1}, + 0 : {'size': 1, 'name': 'digital_in', 'signed': false, 'divisor': 1}, + 1 : {'size': 1, 'name': 'digital_out', 'signed': false, 'divisor': 1}, + 2 : {'size': 2, 'name': 'analog_in', 'signed': true , 'divisor': 100}, + 3 : {'size': 2, 'name': 'analog_out', 'signed': true , 'divisor': 100}, 100: {'size': 4, 'name': 'generic', 'signed': false, 'divisor': 1}, 101: {'size': 2, 'name': 'illuminance', 'signed': false, 'divisor': 1}, 102: {'size': 1, 'name': 'presence', 'signed': false, 'divisor': 1}, @@ -61,10 +60,10 @@ function lppDecode(bytes) { 128: {'size': 2, 'name': 'power', 'signed': false, 'divisor': 1}, 130: {'size': 4, 'name': 'distance', 'signed': false, 'divisor': 1000}, 131: {'size': 4, 'name': 'energy', 'signed': false, 'divisor': 1000}, - 132: {'size': 1, 'name': 'direction', 'signed': false, 'divisor': 1}, + 132: {'size': 2, 'name': 'direction', 'signed': false, 'divisor': 1}, 133: {'size': 4, 'name': 'time', 'signed': false, 'divisor': 1}, 134: {'size': 6, 'name': 'gyrometer', 'signed': true , 'divisor': 100}, - 136: {'size': 9, 'name': 'location', 'signed': true, 'divisor': [10000,10000,100]}, + 136: {'size': 9, 'name': 'gps', 'signed': true, 'divisor': [10000,10000,100]}, 142: {'size': 1, 'name': 'switch', 'signed': false, 'divisor': 1}, }; diff --git a/examples/Decode/Decode.ino b/examples/Decode/Decode.ino index 14c8da9..879bdc7 100644 --- a/examples/Decode/Decode.ino +++ b/examples/Decode/Decode.ino @@ -35,7 +35,7 @@ void setup() lpp.addUnixTime(1, 135005160); - lpp.addGenericSensor(1, 12345); + lpp.addGenericSensor(1, 4294967295); lpp.addVoltage(1, 3.35); lpp.addCurrent(1, 0.321); lpp.addFrequency(1, 50); diff --git a/examples/DecodeTTN/DecodeTTN.ino b/examples/DecodeTTN/DecodeTTN.ino new file mode 100644 index 0000000..4bb2c48 --- /dev/null +++ b/examples/DecodeTTN/DecodeTTN.ino @@ -0,0 +1,59 @@ +/* + DecodeTTN.ino + + This code create a CayenneLPP package and decode to Json. + + created 22 October 2019 + by Luiz H. Cassettari +*/ + +#include + +void setup() +{ + DynamicJsonDocument jsonBuffer(1024); + CayenneLPP lpp(160); + + JsonObject root = jsonBuffer.to(); + + Serial.begin(115200); + Serial.println(); + + lpp.reset(); + lpp.addDigitalInput(1, 0); + lpp.addDigitalOutput(2, 1); + lpp.addAnalogInput(3, 1.23f); + lpp.addAnalogOutput(4, 3.45f); + lpp.addLuminosity(5, 20304); + lpp.addPresence(6, 1); + lpp.addTemperature(7, 26.5f); + lpp.addRelativeHumidity(8, 86.6f); + lpp.addAccelerometer(9, 1.234f, -1.234f, 0.567f); + lpp.addBarometricPressure(10, 1023.4f); + lpp.addGyrometer(1, -12.34f, 45.56f, 89.01f); + lpp.addGPS(1, -12.34f, 45.56f, 9.01f); + + lpp.addUnixTime(1, 135005160); + + lpp.addGenericSensor(1, 4294967295); + lpp.addVoltage(1, 3.35); + lpp.addCurrent(1, 0.321); + lpp.addFrequency(1, 50); + lpp.addPercentage(1, 100); + lpp.addAltitude(1 , 50); + lpp.addPower(1 , 50000); + lpp.addDistance(1 , 10.555); + lpp.addEnergy(1 , 19.055); + lpp.addDirection(1 , 90); + lpp.addSwitch(1 , 0); + + lpp.decodeTTN(lpp.getBuffer(), lpp.getSize(), root); + + serializeJsonPretty(root, Serial); + Serial.println(); + +} + +void loop() +{ +} \ No newline at end of file diff --git a/keywords.txt b/keywords.txt index 1990b0f..e875831 100644 --- a/keywords.txt +++ b/keywords.txt @@ -6,46 +6,47 @@ # Class (KEYWORD1) ####################################### -CayenneLPP KEYWORD1 +CayenneLPP KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### -reset KEYWORD2 -getSize KEYWORD2 -*getBuffer KEYWORD2 -copy KEYWORD2 - -addDigitalInput KEYWORD2 -addDigitalOutput KEYWORD2 -addAnalogInput KEYWORD2 -addAnalogOutput KEYWORD2 -addLuminosity KEYWORD2 -addPresence KEYWORD2 -addTemperature KEYWORD2 -addRelativeHumidity KEYWORD2 -addAccelerometer KEYWORD2 -addBarometricPressure KEYWORD2 -addGyrometer KEYWORD2 -addGPS KEYWORD2 - -addUnixTime KEYWORD2 - -addGenericSensor KEYWORD2 -addVoltage KEYWORD2 -addCurrent KEYWORD2 -addFrequency KEYWORD2 -addPercentage KEYWORD2 -addAltitude KEYWORD2 -addPower KEYWORD2 -addDistance KEYWORD2 -addEnergy KEYWORD2 -addDirection KEYWORD2 -addSwitch KEYWORD2 - -getTypeName KEYWORD2 -decode KEYWORD2 +reset KEYWORD2 +getSize KEYWORD2 +*getBuffer KEYWORD2 +copy KEYWORD2 + +addDigitalInput KEYWORD2 +addDigitalOutput KEYWORD2 +addAnalogInput KEYWORD2 +addAnalogOutput KEYWORD2 +addLuminosity KEYWORD2 +addPresence KEYWORD2 +addTemperature KEYWORD2 +addRelativeHumidity KEYWORD2 +addAccelerometer KEYWORD2 +addBarometricPressure KEYWORD2 +addGyrometer KEYWORD2 +addGPS KEYWORD2 + +addUnixTime KEYWORD2 + +addGenericSensor KEYWORD2 +addVoltage KEYWORD2 +addCurrent KEYWORD2 +addFrequency KEYWORD2 +addPercentage KEYWORD2 +addAltitude KEYWORD2 +addPower KEYWORD2 +addDistance KEYWORD2 +addEnergy KEYWORD2 +addDirection KEYWORD2 +addSwitch KEYWORD2 + +getTypeName KEYWORD2 +decode KEYWORD2 +decodeTTN KEYWORD2 ####################################### # Constants (LITERAL1) diff --git a/src/CayenneLPP.cpp b/src/CayenneLPP.cpp index e7ad3be..c8d86b6 100644 --- a/src/CayenneLPP.cpp +++ b/src/CayenneLPP.cpp @@ -70,10 +70,10 @@ bool CayenneLPP::isType(uint8_t type) { } const char * CayenneLPP::getTypeName(uint8_t type) { - if (LPP_DIGITAL_INPUT == type) return "digital_input"; - if (LPP_DIGITAL_OUTPUT == type) return "digital_output"; - if (LPP_ANALOG_INPUT == type) return "analog_input"; - if (LPP_ANALOG_OUTPUT == type) return "analog_output"; + if (LPP_DIGITAL_INPUT == type) return "digital_in"; + if (LPP_DIGITAL_OUTPUT == type) return "digital_out"; + if (LPP_ANALOG_INPUT == type) return "analog_in"; + if (LPP_ANALOG_OUTPUT == type) return "analog_out"; if (LPP_GENERIC_SENSOR == type) return "generic"; if (LPP_LUMINOSITY == type) return "luminosity"; if (LPP_PRESENCE == type) return "presence"; @@ -398,6 +398,17 @@ float CayenneLPP::getValue(uint8_t * buffer, uint8_t size, uint32_t multiplier, } +uint32_t CayenneLPP::getValue32(uint8_t * buffer, uint8_t size) { + + uint32_t value = 0; + for (uint8_t i=0; i len) { + _error = LPP_ERROR_OVERFLOW; + return 0; + } + + // Init object + String name = String(getTypeName(type)) + "_" + channel; + + // Parse types + if (LPP_ACCELEROMETER == type || LPP_GYROMETER == type) { + + JsonObject object = root.createNestedObject(name); + object["x"] = getValue(&buffer[index], 2, multiplier, is_signed); + object["y"] = getValue(&buffer[index+2], 2, multiplier, is_signed); + object["z"] = getValue(&buffer[index+4], 2, multiplier, is_signed); + + } else if (LPP_GPS == type) { + + JsonObject object = root.createNestedObject(name); + object["latitude"] = getValue(&buffer[index], 3, 10000, is_signed); + object["longitude"] = getValue(&buffer[index+3], 3, 10000, is_signed); + object["altitude"] = getValue(&buffer[index+6], 3, 100, is_signed); + + } else if (LPP_GENERIC_SENSOR == type || LPP_UNIXTIME == type) { + + root[name] = getValue32(&buffer[index], size); + + } else { + + root[name] = getValue(&buffer[index], size, multiplier, is_signed); + + } + + index += size; + + } + + return count; + +} diff --git a/src/CayenneLPP.h b/src/CayenneLPP.h index 187a888..a490383 100644 --- a/src/CayenneLPP.h +++ b/src/CayenneLPP.h @@ -107,6 +107,7 @@ class CayenneLPP { // Decoder methods const char * getTypeName(uint8_t type); uint8_t decode(uint8_t *buffer, uint8_t size, JsonArray& root); + uint8_t decodeTTN(uint8_t *buffer, uint8_t size, JsonObject& root); // Original LPPv1 data types uint8_t addDigitalInput(uint8_t channel, uint32_t value); @@ -144,6 +145,7 @@ class CayenneLPP { bool getTypeSigned(uint8_t type); float getValue(uint8_t * buffer, uint8_t size, uint32_t multiplier, bool is_signed); + uint32_t getValue32(uint8_t * buffer, uint8_t size); template uint8_t addField(uint8_t type, uint8_t channel, T value); uint8_t * _buffer;