Skip to content

Commit

Permalink
Merge pull request #9 from ricaun/ttn
Browse files Browse the repository at this point in the history
Fix/add ttn and others
  • Loading branch information
sabas1080 authored Oct 24, 2019
2 parents 3daf12b + a1660d2 commit 4ae9e17
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 47 deletions.
21 changes: 21 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
13 changes: 6 additions & 7 deletions decoders/decoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -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},
};

Expand Down
2 changes: 1 addition & 1 deletion examples/Decode/Decode.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
59 changes: 59 additions & 0 deletions examples/DecodeTTN/DecodeTTN.ino
Original file line number Diff line number Diff line change
@@ -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 <CayenneLPP.h>

void setup()
{
DynamicJsonDocument jsonBuffer(1024);
CayenneLPP lpp(160);

JsonObject root = jsonBuffer.to<JsonObject>();

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()
{
}
71 changes: 36 additions & 35 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
89 changes: 85 additions & 4 deletions src/CayenneLPP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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<size; i++) {
value = (value << 8) + buffer[i];
}

return value;

}

uint8_t CayenneLPP::decode(uint8_t *buffer, uint8_t len, JsonArray& root) {

uint8_t count = 0;
Expand Down Expand Up @@ -449,6 +460,10 @@ uint8_t CayenneLPP::decode(uint8_t *buffer, uint8_t len, JsonArray& root) {
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) {

data["value"] = getValue32(&buffer[index], size);

} else {

data["value"] = getValue(&buffer[index], size, multiplier, is_signed);
Expand All @@ -462,3 +477,69 @@ uint8_t CayenneLPP::decode(uint8_t *buffer, uint8_t len, JsonArray& root) {
return count;

}

uint8_t CayenneLPP::decodeTTN(uint8_t *buffer, uint8_t len, JsonObject& root) {

uint8_t count = 0;
uint8_t index = 0;

while ((index + 2) < len) {

count++;

// Get channel #
uint8_t channel = buffer[index++];

// Get data type
uint8_t type = buffer[index++];
if (!isType(type)) {
_error = LPP_ERROR_UNKOWN_TYPE;
return 0;
}

// Type definition
uint8_t size = getTypeSize(type);
uint32_t multiplier = getTypeMultiplier(type);
bool is_signed = getTypeSigned(type);

// Check buffer size
if (index + size > 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;

}
2 changes: 2 additions & 0 deletions src/CayenneLPP.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 <typename T> uint8_t addField(uint8_t type, uint8_t channel, T value);

uint8_t * _buffer;
Expand Down

0 comments on commit 4ae9e17

Please sign in to comment.