Awesome
ttn-osem-integration
Microservice for openSenseMap that provides a direct integration with TheThingsNetwork to allow straightforward measurement upload from LoRa-WAN devices.
It decodes measurements from an uplink payload from the TTN HTTP Integrations API for a configured senseBox, and adds the decoded measurements to the database.
There are multiple decoding options provided via profiles
, which may be
easily extended to support other sensor configurations or value transformations.
configuring a box
To associate a device on TTN with a box on the openSenseMap, there is some
configuration required on the openSenseMap. The box has to contain a field
box.integrations.ttn
with the following structure:
ttn: {
// the app_id & dev_id you recieved when registering on TTN
app_id: 'abcd',
dev_id: '1234',
// decode the messages according to this profile format, see below
profile: 'lora-serialization',
// optional. some profiles require additional configuration
decodeOptions: [],
// optional. if specified, only messages recieved on this LoRa-port are stored
port: 3,
}
decoding profiles
sensebox/home
Decodes messages of all sensors of the senseBox:home. Takes registered sensors into account and decodes payload accordingly. Therefore, the senseBox:home lora sketch should not be changed except TTN IDs. The correct sensorIds are matched via their titles. Decoding fits the senseBox:home lora sketch.
lora-serialization
Allows decoding of messages that were encoded with the lora-serialization
library.
The decoders temperature
, humidity
, uint8
, uint16
, unixtime
and latLng
are supported.
Each encoded value is matched to a sensor via it's _id
, sensorType
, unit
, or title
properties.
There may be one or more property defined for each value via sensor_id
, sensor_title
, sensor_type
, sensor_unit
.
If one property matches a sensor, the other properties are discarded.
The following example config allows decoding of measurements of 3 sensors:
"ttn": {
"profile": "lora-serialization",
"decodeOptions": [
{ "decoder": "temperature", "sensor_unit": "°C" },
{ "decoder": "humidity", "sensor_id": "588876b67dd004f79259bd8b" },
{ "decoder": "uint16", "sensor_type": "TSL45315", "sensor_title": "Beleuchtungsstärke" }
]
}
special decoders unixtime
& latLng
These decoders do not generate a measurement for a sensor of the box, but will
be used as timestamp or location for the measurements.
The unixtime
and latLng
decoders must be defined before the measurements,
and are applied to all following measurements, until the next latLng
or
unixtime
decoder is specified.
This means that it is possible to send measurements of several timestamps at once:
"ttn": {
"profile": "lora-serialization",
"decodeOptions": [
// first measurement, will have time of transmission as timestamp
{ "decoder": "temperature", "sensor_unit": "°C" },
// 2nd measurement for same sensor, will have custom timestamp
{ "decoder": "unixtime" }, // no sensor properties required for special decoders
{ "decoder": "temperature", "sensor_unit": "°C" },
// 3rd measurement, another timestamp
{ "decoder": "unixtime" },
{ "decoder": "temperature", "sensor_unit": "°C" }
]
}
debug
Simple decoder, which decodes a given number of bytes to integer values.
Requires a config like the following, where the measurements are applied to the sensors in the order of box.sensors
.
ttn: {
profile: 'lora-serialization',
decodeOptions: [3, 1, 2] // specifies the number of bytes to consume for each measurement
}
json
It's also possible to add measurements which already have been decoded by a TTN payload function.
The property payload_fields
has to contain JSON in the format accepted by the openSenseMap-API.
This is the case, if the TTN application has a Payload Function defined.
cayenne-lpp
Allows decoding of messages that were encoded with the Cayene LPP
format.
The decoders temperature
, relative_humidity
, barometric_pressure
, luminosity
, and analog_in
are supported.
Each encoded value is matched to a sensor via it's _id
, sensorType
, unit
, or title
properties.
There may be one or more property defined for each value via sensor_id
, sensor_title
, sensor_type
, sensor_unit
.
If one property matches a sensor, the other properties are discarded.
If GPS measurements are provided, they will automatically be attached to the measurement in the API. No need to add GPS to the decodeOptions
. Mobile boxes will then update their location on the openSenseMap accordingly.
The following example config allows decoding of measurements of 3 sensors:
"ttn": {
"profile": "cayenne-lpp",
"decodeOptions": [
{ "decoder": "temperature", "channel": 1, "sensor_unit": "°C" },
{ "decoder": "relative_humidity", "channel": 1, "sensor_id": "588876b67dd004f79259bd8b" },
{ "decoder": "illuminance", "channel": 1, "sensor_type": "TSL45315", "sensor_title": "Beleuchtungsstärke" }
]
}
deployment
There is a Dockerfile
, as well as an docker-compose.yml
which includes a mongodb instance.
If you want to run the application directly, you need to have the dependencies listed below installed.
For configuration, see below. Once configured, run
yarn install
npm start
dependencies
node.js >= 6.x
yarn
mongodb >= 3.x
configuration
Configuration is handled by node-config. See config/default.json.
{
"port": 3000,
"loglevel": "trace",
"openSenseMap-API-models": {
"db": {
// See example config json of @sensebox/opensensemap-api-models
"mongo_uri"
}
}
}
development
- JSDoc documentation can be found under
./docs/
or sensebox.github.io/ttn-osem-integration. To update it, runnpm run docs
. - To run the test suite, either run
npm run test
while the application is running, or./run_tests.sh
(requires bash & docker). - Please follow the existing code style. Double check by running
npm run lint
.
license
MIT, see LICENSE