Feather M0 LoRa in TFA Housing¶
This sensor node is made to showcase a use-case of LoRaWAN technology for outdoor weather monitoring. For achieving this a Feather M0 LoRa module was used with temperature and pressure sensor. The entire setup was carefully placed in the TFA Housing which is an all-weather protective cover for outdoor transmitters. In this example we measure parameters such as temperature, humidity, altitude, and air pressure.
Hardware¶
To build this sensor node we have used following hardware components:
- Adafruit Feather M0 LoRA board
- Grove - DHT-22 Temperature & Humidity Sensor
- Grove - Barometric Pressure Sensor
- Breadboard
- TFA Protective Cover
- 6600 mAH Battery
Also, as the final hardware setup with antenna couldn’t completely fit into the casing, a small hole was made at the bottom of the casing to allow the remaining portion of antenna to stay outside.
Wiring setup¶
First of all, the Feather M0 LoRa board was prepared by soldering the board with the provided grid of pins. Then the board is connected with the sensors using a breadboard. The sensor connections were made using the connector cables as following:
DHT-22 Sensor connections:¶
- Feather 3V to DHT22 pin 1
- Feather GND to DHT22 pin 4
- Feather pin 12 to DHT22 pin 2
- Resistor between DHT pin 1 and DHT pin 2
Grove-Barometer Sensor connections:¶
- Feather SCL to Barometer Sensor pin 1 (yellow)
- Feather SDA to Barometer Sensor pin 2 (white)
- Feather 3V to Barometer Sensor pin 3 (red)
- Feather GND to Barometer Sensor pin 4 (black)
Apart from this, Feather pin 6 should be permanently wired with Feather pin io1 as shown in the figure above.
To ensure the durable connections, smaller jumper wires were used on the breadboard instead of longer connecting cables. Sensors and cables were also supported with an insulating duct tape.
Final hardware setup looked as following:
Once all these connection were made, the board is connected with a computer using a USB cable. Further, steps of software part needs to be followed.
Software¶
To create this node, we use Arduino IDE for setting up the Feather M0 LoRa module. First, install the Feather M0 LoRa board to your Arduino IDE and select the correct port. Then following libraries needs to be installed before compiling the code:
- lmic.h for implementing LoRaWAN on Arduino hardware.
- hal/hal.h bundled with lmic library.
- Adafruit_SleepyDog.h for controlling low power sleep mode.
- Wire.h to communicate with I2C devices.
- BMP085.h for Barometer sensor.
- DHT.h for reading DHT-22 sensor.
- CayenneLPP.h for Cayenne Protocol.
Apart from this, SPI.h library is also used for communicating with serial peripheral interface but it is already inbuilt in Arduino IDE and is not required to be separately installed.
Now download and run the Arduino Sketch for Outdoor Weather Monitoring sensor node file in the Arduino IDE. This code was created by merging the example code of both the sensors and the ttn-otaa example from the lmic library. Some required changes were made while merging the example codes. The user should change the network session key, app session key and device address in the code before compiling. These keys can be obtained from the TTN, SWM or other service providers.
1 2 3 4 5 6 7 8 9 10 11 12 | // LoRaWAN NwkSKey, network session key
// This should be in big-endian (aka msb).
static const PROGMEM u1_t NWKSKEY[16] = {NETWORK_SESSION_KEY_HERE_IN_MSB_FORMAT};
// LoRaWAN AppSKey, application session key
// This should also be in big-endian (aka msb).
static const u1_t PROGMEM APPSKEY[16] = {APPLICATION_SESSION_KEY_HERE_IN_MSB_FORMAT};
// LoRaWAN end-device address (DevAddr)
// See http://thethingsnetwork.org/wiki/AddressSpace
// The library converts the address to network byte order as needed, so this should be in big-endian (aka msb) too.
static const u4_t DEVADDR = 0x260XXXXX ; // <-- Change this address for every node!
|
The pin mapping configured in the code should also be verified for the board that is being used. Current pin mapping is set as per the Feather M0 LoRa board.
1 2 3 4 5 6 | // Pin mapping
const lmic_pinmap lmic_pins = {
.nss = 8,
.rxtx = LMIC_UNUSED_PIN,
.rst = 4,
.dio = {3, 6, LMIC_UNUSED_PIN},
|
Following is the example code that can be used to measure the battery voltage of the Feather M0 LoRa board:
1 2 3 4 5 6 7 | measuredvbat = analogRead(VBATPIN);
measuredvbat *= 2; // we divided by 2, so multiply back
measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage
measuredvbat /= 1024; // convert to voltage
SERIALDEBUG_PRINT(" %\t");
SERIALDEBUG_PRINT("Battery Voltage: ");
|
Services¶
This node is connected using the TheThingsNetwork service. Further, a node-red work bench is used to forward this collected data from the TTN platform to the OGC Sensor Things API configured on the FROST Server. The node-red workbench that was used for forwarding the data is available at Node red flow for Outdoor Weather Monitoring sensor node. To use this node-red-workbench go to the node-red platform https://iot.gis.bgu.tum.de:1885/, login with the credentials, go to the options and select Import>Clipboard. Select the downloaded .json file with the given option and click on import. Make necessary changes and deploy the flow.
Datastreams setup for this sensor node on the FROST server can be seen at: http://iot.gis.bgu.tum.de:8081/FROST-Server-gi3/v1.0/Things(20)/Datastreams
The node-red workbench for this sensor node could be found at: https://iot.gis.bgu.tum.de:1885/#flow/f6f7a740.c6b338
The GRAFANA dash-board for visualizing the collected data is available at: https://iot.gis.bgu.tum.de:3050/d/sMJ3jAAWz/featherm0lora-in-tfa-housing?orgId=1
Code files¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | /*******************************************************************************
* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
*
*
*
*
* Permission is hereby granted, free of charge, to anyone
* obtaining a copy of this document and accompanying files,
* to do whatever they want with them without any restriction,
* including, but not limited to, copying, modification and redistribution.
* NO WARRANTY OF ANY KIND IS PROVIDED.
*
* This example sends a valid LoRaWAN packet with payload "Hello,
* world!", using frequency and encryption settings matching those of
* the The Things Network.
*
* This uses ABP (Activation-by-personalisation), where a DevAddr and
* Session keys are preconfigured (unlike OTAA, where a DevEUI and
* application key is configured, while the DevAddr and session keys are
* assigned/generated in the over-the-air-activation procedure).
*
* Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in
* g1, 0.1% in g2), but not the TTN fair usage policy (which is probably
* violated by this sketch when left running for longer)!
*
* To use this sketch, first register your application and device with
* the things network, to set or generate a DevAddr, NwkSKey and
* AppSKey. Each device should have their own unique values for these
* fields.
*
* Do not forget to define the radio type correctly in config.h.
*
*******************************************************************************/
// #define SERIALDEBUG
#ifdef SERIALDEBUG
#define SERIALDEBUG_PRINT(...) Serial.print(__VA_ARGS__)
#define SERIALDEBUG_PRINTLN(...) Serial.println(__VA_ARGS__)
#else
#define SERIALDEBUG_PRINT(...)
#define SERIALDEBUG_PRINTLN(...)
#endif
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <Adafruit_SleepyDog.h>
#include <DHT.h>
#include <CayenneLPP.h>
#include "BMP085.h"
#include <Wire.h>
CayenneLPP lpp(51);
#define DHTPIN 12 // Pin which is connected to the DHT sensor.
#define DHTTYPE DHT22 // DHT 22 (AM2302)
// DHT_Unified dht(DHTPIN, DHTTYPE);
DHT dht(DHTPIN, DHTTYPE);
#define VBATPIN A7
float temperature2;
float pressure;
float atm;
float altitude;
BMP085 myBarometer;
// LoRaWAN NwkSKey, network session key
// This should be in big-endian (aka msb).
static const PROGMEM u1_t NWKSKEY[16] = {NETWORK_SESSION_KEY_HERE_IN_MSB_FORMAT};
// LoRaWAN AppSKey, application session key
// This should also be in big-endian (aka msb).
static const u1_t PROGMEM APPSKEY[16] = {APPLICATION_SESSION_KEY_HERE_IN_MSB_FORMAT};
// LoRaWAN end-device address (DevAddr)
// See http://thethingsnetwork.org/wiki/AddressSpace
// The library converts the address to network byte order as needed, so this should be in big-endian (aka msb) too.
static const u4_t DEVADDR = 0x260XXXXX ; // <-- Change this address for every node!
// These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless
// DISABLE_JOIN is set in config.h, otherwise the linker will complain).
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }
static osjob_t sendjob;
// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 1; // seconds transmit cycle plus ...
const unsigned SLEEP_TIME = 60*9+55; // seconds sleep time plus ...
const unsigned MEASURE_TIME = 2; // seconds measuring time should lead to ...
// 5 minute(s) total cycle time
// Pin mapping
const lmic_pinmap lmic_pins = {
.nss = 8,
.rxtx = LMIC_UNUSED_PIN,
.rst = 4,
.dio = {3, 6, LMIC_UNUSED_PIN},
};
void onEvent (ev_t ev) {
// Serial.print(os_getTime());
// Serial.print(": ");
SERIALDEBUG_PRINT(os_getTime());
SERIALDEBUG_PRINT(": ");
switch(ev) {
case EV_SCAN_TIMEOUT:
SERIALDEBUG_PRINTLN(F("EV_SCAN_TIMEOUT"));
break;
case EV_BEACON_FOUND:
SERIALDEBUG_PRINTLN(F("EV_BEACON_FOUND"));
break;
case EV_BEACON_MISSED:
SERIALDEBUG_PRINTLN(F("EV_BEACON_MISSED"));
break;
case EV_BEACON_TRACKED:
SERIALDEBUG_PRINTLN(F("EV_BEACON_TRACKED"));
break;
case EV_JOINING:
SERIALDEBUG_PRINTLN(F("EV_JOINING"));
break;
case EV_JOINED:
SERIALDEBUG_PRINTLN(F("EV_JOINED"));
break;
case EV_RFU1:
SERIALDEBUG_PRINTLN(F("EV_RFU1"));
break;
case EV_JOIN_FAILED:
SERIALDEBUG_PRINTLN(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
SERIALDEBUG_PRINTLN(F("EV_REJOIN_FAILED"));
break;
case EV_TXCOMPLETE:
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
SERIALDEBUG_PRINTLN(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
SERIALDEBUG_PRINTLN(F("Received ack"));
if (LMIC.dataLen) {
SERIALDEBUG_PRINT(F("Received "));
SERIALDEBUG_PRINT(LMIC.dataLen);
SERIALDEBUG_PRINTLN(F(" bytes of payload"));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
SERIALDEBUG_PRINTLN("going to sleep now ... ");
// lmic library sleeps automatically after transmission has been completed
for(int i= 0; i < SLEEP_TIME / 16; i++) {
Watchdog.sleep(16000); // maximum seems to be 16 seconds
SERIALDEBUG_PRINT('.');
}
if (SLEEP_TIME % 16) {
Watchdog.sleep((SLEEP_TIME % 16)*1000);
SERIALDEBUG_PRINT('*');
}
SERIALDEBUG_PRINTLN("... woke up again");
break;
case EV_LOST_TSYNC:
SERIALDEBUG_PRINTLN(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
SERIALDEBUG_PRINTLN(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
SERIALDEBUG_PRINTLN(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
SERIALDEBUG_PRINTLN(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
SERIALDEBUG_PRINTLN(F("EV_LINK_ALIVE"));
break;
default:
SERIALDEBUG_PRINTLN(F("Unknown event"));
break;
}
}
void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
SERIALDEBUG_PRINTLN(F("OP_TXRXPEND, not sending"));
} else {
// Prepare upstream data transmission at the next possible time.
float temperature, humidity, measuredvbat;
int16_t int16_temperature, int16_humidity, int16_vbat;
// Start a measurement to update the sensor's internal temperature & humidity reading
SERIALDEBUG_PRINTLN("Start measurement...");
temperature = dht.readTemperature();
// delay(2000);
Watchdog.sleep(2000);
// Now read the recently measured temperature (2 secs ago) as Celsius (the default)
temperature = dht.readTemperature();
// Read the recently measured humidity (2 secs ago)
humidity = dht.readHumidity();
SERIALDEBUG_PRINTLN("... finished!");
// Check if any reads failed and exit early (to try again).
if (isnan(humidity) || isnan(temperature)) {
SERIALDEBUG_PRINTLN("Failed to read from DHT sensor!");
for (int i=0; i<5; i++) {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on by making the voltage HIGH
delay(150);
digitalWrite(LED_BUILTIN, LOW); // turn the LED on by making the voltage HIGH
delay(150);
}
// ok, then wait for another period and try it again
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
} else {
SERIALDEBUG_PRINT("Humidity: ");
SERIALDEBUG_PRINT(humidity);
SERIALDEBUG_PRINT(" %\t");
SERIALDEBUG_PRINT("Temperature: ");
SERIALDEBUG_PRINT(temperature);
SERIALDEBUG_PRINT(" *C ");
measuredvbat = analogRead(VBATPIN);
measuredvbat *= 2; // we divided by 2, so multiply back
measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage
measuredvbat /= 1024; // convert to voltage
SERIALDEBUG_PRINT(" %\t");
SERIALDEBUG_PRINT("Battery Voltage: ");
SERIALDEBUG_PRINTLN(measuredvbat);
temperature2 = myBarometer.bmp085GetTemperature(myBarometer.bmp085ReadUT()); //Get the temperature, bmp085ReadUT MUST be called first
pressure = myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP());//Get the temperature
/*
To specify a more accurate altitude, enter the correct mean sea level
pressure level. For example, if the current pressure level is 1019.00 hPa
enter 101900 since we include two decimal places in the integer value。
*/
altitude = myBarometer.calcAltitude(pressure);
atm = pressure / 101325;
lpp.reset();
lpp.addTemperature(1, temperature);
lpp.addRelativeHumidity(2, humidity);
lpp.addAnalogInput(3, measuredvbat);
lpp.addTemperature(4, temperature2);
lpp.addBarometricPressure(5, pressure/100);
lpp.addAnalogInput(6, atm);
lpp.addAnalogInput(7, altitude);
// LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
// send the 6 bytes payload to LoRaWAN port 7
LMIC_setTxData2(7, lpp.getBuffer(), lpp.getSize(), 0);
SERIALDEBUG_PRINTLN(F("Packet queued"));
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on by making the voltage HIGH
}
// LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
// Serial.println(F("Packet queued"));
}
// Next TX is scheduled after TX_COMPLETE event.
}
void setup() {
delay(5000);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
#ifdef SERIALDEBUG
Serial.begin(9600);
// while (!Serial);
#endif
dht.begin();
myBarometer.init();
SERIALDEBUG_PRINTLN(F("Starting"));
#ifdef VCC_ENABLE
// For Pinoccio Scout boards
pinMode(VCC_ENABLE, OUTPUT);
digitalWrite(VCC_ENABLE, HIGH);
delay(1000);
#endif
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
// Set static session parameters. Instead of dynamically establishing a session
// by joining the network, precomputed session parameters are be provided.
#ifdef PROGMEM
// On AVR, these values are stored in flash and only copied to RAM
// once. Copy them to a temporary buffer here, LMIC_setSession will
// copy them into a buffer of its own again.
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
#else
// If not running an AVR with PROGMEM, just use the arrays directly
LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);
#endif
#if defined(CFG_eu868)
// Set up the channels used by the Things Network, which corresponds
// to the defaults of most gateways. Without this, only three base
// channels from the LoRaWAN specification are used, which certainly
// works, so it is good for debugging, but can overload those
// frequencies, so be sure to configure the full frequency range of
// your network here (unless your network autoconfigures them).
// Setting up channels should happen after LMIC_setSession, as that
// configures the minimal channel set.
// NA-US channels 0-71 are configured automatically
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
// TTN defines an additional channel at 869.525Mhz using SF9 for class B
// devices' ping slots. LMIC does not have an easy way to define set this
// frequency and support for class B is spotty and untested, so this
// frequency is not configured here.
#elif defined(CFG_us915)
// NA-US channels 0-71 are configured automatically
// but only one group of 8 should (a subband) should be active
// TTN recommends the second sub band, 1 in a zero based count.
// https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json
LMIC_selectSubBand(1);
#endif
// Disable link check validation
LMIC_setLinkCheckMode(0);
// TTN uses SF9 for its RX2 window.
LMIC.dn2Dr = DR_SF9;
// Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)
LMIC_setDrTxpow(DR_SF7,14);
// Start job
do_send(&sendjob);
}
void loop() {
os_runloop_once();
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | [
{
"id": "f6f7a740.c6b338",
"type": "tab",
"label": "Device 2",
"disabled": false,
"info": ""
},
{
"id": "fafe9ad3.9659e8",
"type": "switch",
"z": "f6f7a740.c6b338",
"name": "Separate",
"property": "key",
"propertyType": "msg",
"rules": [
{
"t": "cont",
"v": "temperature_1",
"vt": "str"
},
{
"t": "cont",
"v": "humidity",
"vt": "str"
},
{
"t": "cont",
"v": "analog_in_3",
"vt": "str"
},
{
"t": "cont",
"v": "temperature_4",
"vt": "str"
},
{
"t": "cont",
"v": "barometric",
"vt": "str"
},
{
"t": "cont",
"v": "analog_in_6",
"vt": "str"
},
{
"t": "cont",
"v": "analog_in_7",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 7,
"x": 220,
"y": 180,
"wires": [
[
"492a1844.49a228"
],
[
"b5be1839.3121a8"
],
[
"d7e35050.187eb"
],
[
"c5363ad1.5d3418"
],
[
"ee2891fa.0dbbe"
],
[
"71354cb4.e6af04"
],
[
"d48c0c97.4eb08"
]
]
},
{
"id": "ccb2fb81.aacd58",
"type": "split",
"z": "f6f7a740.c6b338",
"name": "",
"splt": "\\n",
"spltType": "str",
"arraySplt": 1,
"arraySpltType": "len",
"stream": false,
"addname": "key",
"x": 90,
"y": 180,
"wires": [
[
"fafe9ad3.9659e8"
]
]
},
{
"id": "657fd8a7.01c5e8",
"type": "debug",
"z": "f6f7a740.c6b338",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 870,
"y": 240,
"wires": []
},
{
"id": "b5be1839.3121a8",
"type": "function",
"z": "f6f7a740.c6b338",
"name": "Humidity",
"func": "var humValue = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": humValue, \"Datastream\": {\"@iot.id\": 106}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 440,
"y": 200,
"wires": [
[
"dd5d521b.5c984"
]
]
},
{
"id": "dd5d521b.5c984",
"type": "http request",
"z": "f6f7a740.c6b338",
"name": "POST Observation",
"method": "POST",
"ret": "obj",
"paytoqs": false,
"url": "http://iot.gis.bgu.tum.de:8081/FROST-Server-gi3/v1.0/Observations",
"tls": "",
"proxy": "",
"authType": "basic",
"x": 690,
"y": 240,
"wires": [
[
"657fd8a7.01c5e8"
]
]
},
{
"id": "492a1844.49a228",
"type": "function",
"z": "f6f7a740.c6b338",
"name": "Temperature",
"func": "var tempValue = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": tempValue, \"Datastream\": {\"@iot.id\": 105}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 450,
"y": 160,
"wires": [
[
"dd5d521b.5c984"
]
]
},
{
"id": "739d03d0.606a6c",
"type": "debug",
"z": "f6f7a740.c6b338",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 490,
"y": 60,
"wires": []
},
{
"id": "cb8ef1e2.a85f6",
"type": "ttn uplink",
"z": "f6f7a740.c6b338",
"name": "TTN Input",
"app": "58ceff1f.8576a",
"dev_id": "tum-gis-device2",
"field": "",
"x": 80,
"y": 60,
"wires": [
[
"aae507e3.771c18"
]
]
},
{
"id": "aae507e3.771c18",
"type": "cayennelpp-decoder",
"z": "f6f7a740.c6b338",
"name": "",
"x": 260,
"y": 60,
"wires": [
[
"ccb2fb81.aacd58",
"739d03d0.606a6c"
]
]
},
{
"id": "d7e35050.187eb",
"type": "function",
"z": "f6f7a740.c6b338",
"name": "Battery Voltage",
"func": "var Batteryvolt = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": Batteryvolt, \"Datastream\": {\"@iot.id\": 107}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 460,
"y": 240,
"wires": [
[
"dd5d521b.5c984"
]
]
},
{
"id": "c5363ad1.5d3418",
"type": "function",
"z": "f6f7a740.c6b338",
"name": "Temperature2",
"func": "var tempValue = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": tempValue, \"Datastream\": {\"@iot.id\": 108}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 460,
"y": 280,
"wires": [
[
"dd5d521b.5c984"
]
]
},
{
"id": "ee2891fa.0dbbe",
"type": "function",
"z": "f6f7a740.c6b338",
"name": "Barometric Pressure",
"func": "var pressure = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": pressure, \"Datastream\": {\"@iot.id\": 109}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 480,
"y": 320,
"wires": [
[
"dd5d521b.5c984"
]
]
},
{
"id": "71354cb4.e6af04",
"type": "function",
"z": "f6f7a740.c6b338",
"name": "Pressure atm",
"func": "var atm = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": atm, \"Datastream\": {\"@iot.id\": 110}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 450,
"y": 360,
"wires": [
[
"dd5d521b.5c984"
]
]
},
{
"id": "d48c0c97.4eb08",
"type": "function",
"z": "f6f7a740.c6b338",
"name": "Altitude",
"func": "var altitude = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": altitude, \"Datastream\": {\"@iot.id\": 111}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 440,
"y": 400,
"wires": [
[
"dd5d521b.5c984"
]
]
},
{
"id": "58ceff1f.8576a",
"type": "ttn app",
"z": "",
"appId": "gis-tum-sensors",
"accessKey": "ttn-account-ACCESSKEY_HERE",
"discovery": "discovery.thethingsnetwork.org:1900"
}
]
|