Indoor Ambient Monitoring¶
This sensor node is made to showcase a use-case of LoRaWAN for indoor ambience monitoring. For achieving this a multitude of sensors were used which can monitor the quality of the ambience. In this example we measure parameters such as temperature, humidity, air pressure, air quality, CO2, loudness, gas, PM2.5, and light.
Hardware¶
To realize the objective, following components were used:
Wiring setup¶
First of all, the grove base shield was connected over the Seeeduino LoRaWAN board. The board was set at the 5V mode. Then, the sensor connections were made using the connector cables as following:
- Loudness Sensor – Analog Pin A0
- PM 2.5 Sensor – I2C pin
- Digital Light Sensor – I2C pin
- BME680 Sensor – I2C pin
- MHZ19B CO2 Sensor – Digital Pin D4
- Air Quality Sensor - A2
Apart from this, there is no need of any other wiring in this case.
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 Seeeduino LoRaWAN device. First, install the Seeeduino LoRaWAN board board to your Arduino IDE and select the correct port. Then following libraries needs to be installed before compiling the code:
- Digital_Light_TSL2561.h for Digital Light Sensor
- Air_Quality_Sensor.h for Air Quality Sensor
- Seeed_bme680.h for BME680 Sensor
- Seeed_HM330X.h for Laser PM2.5 Sensor
- MHZ19.h for MHZ19B CO2 Sensor
- Wire.h to communicate with I2C devices
- SoftwareSerial.h for Serial Communication
- RTCZero.h for controlling internal clock for time
- CayenneLPP.h for Cayenne Protocol
Apart from this LoRaWan.h library is also used but it is bundled within Seeeduino Board and is not required to be separately installed.
Now download and run the Arduino Sketch for Indoor Ambient Monitoring sensor node file in the Arduino IDE. This code was created by merging the example code of each of these attached sensor and the ttn-otaa example from the Seeeduino board. Some required changes were made while merging the example codes. For example, as there are multiple sensors each needs to be defined with a unique name. So, here HM330X was named as sensor while AirqualitySensor as sensors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | AirQualitySensor sensors(A2);
SoftwareSerial ss(4,5);
MHZ19 mhz(&ss);
#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10
#define IIC_ADDR uint8_t(0x76)
Seeed_BME680 bme680(IIC_ADDR);
int loudness,a;
HM330X sensor;
u8 buf[30];
|
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 any other service providers.
1 2 3 4 5 6 7 8 9 | // The EUIs and the AppKey must be given in big-endian format, i.e. the
// most-significant-byte comes first (as displayed in the TTN console).
// For TTN issued AppEUIs the first bytes should be 0x70, 0xB3, 0xD5.
// void setId(char *DevAddr, char *DevEUI, char *AppEUI);
lora.setId(NULL, "00942FBXXXXXXXXX", "70B3D57XXXXXXXXX");
// setKey(char *NwkSKey, char *AppSKey, char *AppKey);
lora.setKey(NULL, NULL, "CB89A0AA43F6C5XXXXXXXXXXXXXXXXXX");
|
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 Indoor Ambient 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(21)/Datastreams
The node-red workbench for this sensor node could be found at: https://iot.gis.bgu.tum.de:1885/#flow/7d5c6b14.d2af94
The GRAFANA dash-board for visualizing the collected data is available at: https://iot.gis.bgu.tum.de:3050/d/jDJ1li1Wz/indoor-ambient-monitoring-with-seeeduino-lorawan-and-sensors?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 | #include <Wire.h>
#include <Digital_Light_TSL2561.h>
#include "Air_Quality_Sensor.h"
#include "seeed_bme680.h"
#include "Seeed_HM330X.h"
#include <SoftwareSerial.h>
#include <MHZ19.h>
#include <RTCZero.h>
#include <LoRaWan.h>
#include <CayenneLPP.h>
RTCZero rtc;
char buffer[256]; // buffer for text messages received from the LoRaWAN module for display
CayenneLPP lpp(51);
AirQualitySensor sensors(A2);
SoftwareSerial ss(4,5);
MHZ19 mhz(&ss);
#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10
#define IIC_ADDR uint8_t(0x76)
Seeed_BME680 bme680(IIC_ADDR);
int loudness,a;
HM330X sensor;
u8 buf[30];
const char *str[]={"sensor num: ","PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM10 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
"PM1.0 concentration(Atmospheric environment,unit:ug/m3): ",
"PM2.5 concentration(Atmospheric environment,unit:ug/m3): ",
"PM10 concentration(Atmospheric environment,unit:ug/m3): ",
};
err_t print_result(const char* str,u16 value)
{
if(NULL==str)
return ERROR_PARAM;
SerialUSB.print(str);
SerialUSB.println(value);
return NO_ERROR;
}
/*parse buf with 29 u8-data*/
err_t parse_result(u8 *data)
{
u16 value=0;
err_t NO_ERROR;
if(NULL==data)
return ERROR_PARAM;
for(int i=1;i<8;i++)
{
value = (u16)data[i*2]<<8|data[i*2+1];
print_result(str[i-1],value);
if(i==6)
{ a=value;
SerialUSB.println(a);
}
}
}
err_t parse_result_value(u8 *data)
{
if(NULL==data)
return ERROR_PARAM;
for(int i=0;i<28;i++)
{
SerialUSB.print(data[i],HEX);
SerialUSB.print(" ");
if((0==(i)%5)||(0==i))
{
SerialUSB.println(" ");
}
}
u8 sum=0;
for(int i=0;i<28;i++)
{
sum+=data[i];
}
if(sum!=data[28])
{
SerialUSB.println("wrong checkSum!!!!");
}
SerialUSB.println(" ");
SerialUSB.println(" ");
return NO_ERROR;
}
void setup()
{
Wire.begin();
for(int i = 0; i < 26; i ++) // Set all pins to HIGH to save power (reduces the
{ // current drawn during deep sleep by around 0.7mA).
if (i!=13) { // Don't switch on the onboard user LED (pin 13).
pinMode(i, OUTPUT);
digitalWrite(i, HIGH);
}
}
delay(5000);
SerialUSB.begin(115200);
delay(100);
SerialUSB.println("SerialUSB start");
lora.init(); // Initialize the LoRaWAN module
memset(buffer, 0, 256); // clear text buffer
lora.getVersion(buffer, 256, 1);
memset(buffer, 0, 256); // We call getVersion() two times, because after a reset the LoRaWAN module can be
lora.getVersion(buffer, 256, 1); // in sleep mode and then the first call only wakes it up and will not be performed.
SerialUSB.print(buffer);
memset(buffer, 0, 256);
lora.getId(buffer, 256, 1);
SerialUSB.print(buffer);
// The following three constants (AppEUI, DevEUI, AppKey) must be changed
// for every new sensor node. We are using the LoRaWAN OTAA mode (over the
// air activation). Each sensor node must be manually registered in the
// TTN console at https://console.thethingsnetwork.org before it can be
// started. In the TTN console create a new device with the DevEUI also
// being automatically generated. After the registration of the device the
// three values can be copied from the TTN console. A detailed explanation
// of these steps is given in
// https://learn.adafruit.com/the-things-network-for-feather?view=all
// The EUIs and the AppKey must be given in big-endian format, i.e. the
// most-significant-byte comes first (as displayed in the TTN console).
// For TTN issued AppEUIs the first bytes should be 0x70, 0xB3, 0xD5.
// void setId(char *DevAddr, char *DevEUI, char *AppEUI);
lora.setId(NULL, "00942FBXXXXXXXXX", "70B3D57XXXXXXXXX");
// setKey(char *NwkSKey, char *AppSKey, char *AppKey);
lora.setKey(NULL, NULL, "CB89A0AA43F6C5XXXXXXXXXXXXXXXXXX");
lora.setDeciveMode(LWOTAA); // select OTAA join mode (note that setDeciveMode is not a typo; it is misspelled in the library)
// lora.setDataRate(DR5, EU868); // SF7, 125 kbps (highest data rate)
lora.setDataRate(DR3, EU868); // SF9, 125 kbps (medium data rate and range)
// lora.setDataRate(DR0, EU868); // SF12, 125 kbps (lowest data rate, highest max. distance)
// lora.setAdaptiveDataRate(false);
lora.setAdaptiveDataRate(true); // automatically adapt the data rate
lora.setChannel(0, 868.1);
lora.setChannel(1, 868.3);
lora.setChannel(2, 868.5);
lora.setChannel(3, 867.1);
lora.setChannel(4, 867.3);
lora.setChannel(5, 867.5);
lora.setChannel(6, 867.7);
lora.setChannel(7, 867.9);
// The following two commands can be left commented out;
// TTN works with the default values. (It also works when
// uncommenting the commands, though.)
// lora.setReceiceWindowFirst(0, 868.1);
// lora.setReceiceWindowSecond(869.525, DR0);
lora.setDutyCycle(false); // for debugging purposes only - should normally be activated
lora.setJoinDutyCycle(false); // for debugging purposes only - should normally be activated
lora.setPower(14); // LoRa transceiver power (14 is the maximum for the 868 MHz band)
// while(!lora.setOTAAJoin(JOIN));
while(!lora.setOTAAJoin(JOIN,20)); // wait until the node has successfully joined TTN
lora.setPort(33);
if(sensor.init())
{
SerialUSB.println("HM330X init failed!!!");
while(1);
}
if (sensors.init()) {
SerialUSB.println("Sensor ready.");
}
else {
SerialUSB.println("Sensor ERROR!");
}
TSL2561.init();
while (!bme680.init())
{
SerialUSB.println("bme680 init failed ! can't find device!");
delay(10000);
}
ss.begin(9600);
}
void loop()
{
bool result = false;
float temperature,humidity,pressure,airquality,light,gas,CO2;
loudness = analogRead(0);
SerialUSB.print("The Loudness Sensor value is: ");
SerialUSB.println(loudness);
SerialUSB.println();
delay(3000);
int quality = sensors.slope();
SerialUSB.print("Air Quality Sensor value is: ");
SerialUSB.println(airquality=sensors.getValue());
if (quality == AirQualitySensor::FORCE_SIGNAL) {
SerialUSB.println("High pollution! Force signal active.");
}
else if (quality == AirQualitySensor::HIGH_POLLUTION) {
SerialUSB.println("High pollution!");
}
else if (quality == AirQualitySensor::LOW_POLLUTION) {
SerialUSB.println("Low pollution!");
}
else if (quality == AirQualitySensor::FRESH_AIR) {
SerialUSB.println("Fresh air.");
}
SerialUSB.println();
delay(3000);
SerialUSB.print("The Light Sensor value is: ");
SerialUSB.println(light=TSL2561.readVisibleLux());
SerialUSB.println();
delay(3000);
if(sensor.read_sensor_value(buf,29))
{
SerialUSB.println("HM330X read result failed!!!");
}
parse_result_value(buf);
parse_result(buf);
SerialUSB.println(" ");
delay(3000);
if (bme680.read_sensor_data())
{
SerialUSB.println("Failed to perform reading :(");
return;
}
SerialUSB.print("temperature ===>> ");
SerialUSB.print(temperature = bme680.sensor_result_value.temperature);
SerialUSB.println(" C");
SerialUSB.print("pressure ===>> ");
SerialUSB.print(pressure = bme680.sensor_result_value.pressure/ 1000.0);
SerialUSB.println(" KPa");
SerialUSB.print("humidity ===>> ");
SerialUSB.print(humidity = bme680.sensor_result_value.humidity);
SerialUSB.println(" %");
SerialUSB.print("gas ===>> ");
SerialUSB.print(gas = bme680.sensor_result_value.gas/ 1000.0);
SerialUSB.println(" Kohms");
SerialUSB.println();
delay(3000);
MHZ19_RESULT response = mhz.retrieveData();
if (response == MHZ19_RESULT_OK)
{
SerialUSB.print(F("CO2: "));
SerialUSB.println(CO2=mhz.getCO2());
SerialUSB.print(F("Min CO2: "));
SerialUSB.println(mhz.getMinCO2());
SerialUSB.print(F("Temperature: "));
SerialUSB.println(mhz.getTemperature());
SerialUSB.print(F("Accuracy: "));
SerialUSB.println(mhz.getAccuracy());
SerialUSB.println();
}
else
{
SerialUSB.print(F("Error, code: "));
SerialUSB.println(response);
}
lpp.reset();
lpp.addTemperature(1, temperature);
lpp.addRelativeHumidity(2, humidity);
lpp.addAnalogInput(3, airquality);
lpp.addLuminosity(4, light);
lpp.addBarometricPressure(5, pressure);
lpp.addLuminosity(6, CO2);
lpp.addAnalogInput(7, gas);
lpp.addLuminosity(8, loudness);
lpp.addLuminosity(9, a);
result = lora.transferPacket(lpp.getBuffer(), lpp.getSize(), 5); // send the data packet (n byts) with a default timeout of 5 secs
if(result)
{
short length;
short rssi;
memset(buffer, 0, 256);
length = lora.receivePacket(buffer, 256, &rssi);
if(length)
{
SerialUSB.print("Length is: ");
SerialUSB.println(length);
SerialUSB.print("RSSI is: ");
SerialUSB.println(rssi);
SerialUSB.print("Data is: ");
for(unsigned char i = 0; i < length; i ++)
{
SerialUSB.print("0x");
SerialUSB.print(buffer[i], HEX);
SerialUSB.print(" ");
}
SerialUSB.println();
}
}
lora.setDeviceLowPower(); // bring the LoRaWAN module to sleep mode
doSleep((5*60-8)*1000); // deep sleep for 292 secs (+ 3 secs transmission time + 5 secs timeout = 300 secs period)
lora.setPort(33);
}
void doSleep(uint32_t millis) {
if (!rtc.isConfigured()) { // if called for the first time,
rtc.begin(false); // then initialize the real time clock (RTC)
}
uint32_t now = rtc.getEpoch();
rtc.setAlarmEpoch(now + millis/1000);
rtc.enableAlarm(rtc.MATCH_HHMMSS);
rtc.standbyMode(); // bring CPU into deep sleep mode (until woken up by the RTC)
}
|
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 | [
{
"id": "7d5c6b14.d2af94",
"type": "tab",
"label": "Device3",
"disabled": false,
"info": ""
},
{
"id": "4d581d8.f14c0e4",
"type": "switch",
"z": "7d5c6b14.d2af94",
"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": "luminosity_4",
"vt": "str"
},
{
"t": "cont",
"v": "barometric",
"vt": "str"
},
{
"t": "cont",
"v": "luminosity_6",
"vt": "str"
},
{
"t": "cont",
"v": "analog_in_7",
"vt": "str"
},
{
"t": "cont",
"v": "luminosity_8",
"vt": "str"
},
{
"t": "cont",
"v": "luminosity_9",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 9,
"x": 220,
"y": 180,
"wires": [
[
"92425d9f.bca98"
],
[
"9b919750.d6fff8"
],
[
"620b1ab2.a69224"
],
[
"eee677bf.fe16d8"
],
[
"4b424590.139b4c"
],
[
"bc3f8433.7b89f8"
],
[
"13968bca.c2cd34"
],
[
"c7fcb372.4b2df"
],
[
"b52fa683.7c5fb8"
]
]
},
{
"id": "9010a80d.dfcdb8",
"type": "split",
"z": "7d5c6b14.d2af94",
"name": "",
"splt": "\\n",
"spltType": "str",
"arraySplt": 1,
"arraySpltType": "len",
"stream": false,
"addname": "key",
"x": 90,
"y": 180,
"wires": [
[
"4d581d8.f14c0e4"
]
]
},
{
"id": "a3b86e6f.56637",
"type": "debug",
"z": "7d5c6b14.d2af94",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 870,
"y": 240,
"wires": []
},
{
"id": "9b919750.d6fff8",
"type": "function",
"z": "7d5c6b14.d2af94",
"name": "Humidity",
"func": "var humValue = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": humValue, \"Datastream\": {\"@iot.id\": 113}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 440,
"y": 200,
"wires": [
[
"c67491fc.f4755"
]
]
},
{
"id": "c67491fc.f4755",
"type": "http request",
"z": "7d5c6b14.d2af94",
"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": [
[
"a3b86e6f.56637"
]
]
},
{
"id": "92425d9f.bca98",
"type": "function",
"z": "7d5c6b14.d2af94",
"name": "Temperature",
"func": "var tempValue = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": tempValue, \"Datastream\": {\"@iot.id\": 112}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 450,
"y": 160,
"wires": [
[
"c67491fc.f4755"
]
]
},
{
"id": "a16b3beb.1a5028",
"type": "debug",
"z": "7d5c6b14.d2af94",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 490,
"y": 60,
"wires": []
},
{
"id": "681442b7.1266ac",
"type": "ttn uplink",
"z": "7d5c6b14.d2af94",
"name": "TTN Input",
"app": "58ceff1f.8576a",
"dev_id": "tum-gis-device3",
"field": "",
"x": 80,
"y": 60,
"wires": [
[
"531b0b35.751284"
]
]
},
{
"id": "531b0b35.751284",
"type": "cayennelpp-decoder",
"z": "7d5c6b14.d2af94",
"name": "",
"x": 260,
"y": 60,
"wires": [
[
"9010a80d.dfcdb8",
"a16b3beb.1a5028"
]
]
},
{
"id": "620b1ab2.a69224",
"type": "function",
"z": "7d5c6b14.d2af94",
"name": "Air Quality",
"func": "var quality = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": quality, \"Datastream\": {\"@iot.id\": 119}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 450,
"y": 240,
"wires": [
[
"c67491fc.f4755"
]
]
},
{
"id": "eee677bf.fe16d8",
"type": "function",
"z": "7d5c6b14.d2af94",
"name": "Light",
"func": "var light = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": light, \"Datastream\": {\"@iot.id\": 117}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 430,
"y": 280,
"wires": [
[
"c67491fc.f4755"
]
]
},
{
"id": "4b424590.139b4c",
"type": "function",
"z": "7d5c6b14.d2af94",
"name": "Barometric Pressure",
"func": "var pressure = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": pressure, \"Datastream\": {\"@iot.id\": 114}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 480,
"y": 320,
"wires": [
[
"c67491fc.f4755"
]
]
},
{
"id": "bc3f8433.7b89f8",
"type": "function",
"z": "7d5c6b14.d2af94",
"name": "co2",
"func": "var co2 = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": co2, \"Datastream\": {\"@iot.id\": 118}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 430,
"y": 360,
"wires": [
[
"c67491fc.f4755"
]
]
},
{
"id": "13968bca.c2cd34",
"type": "function",
"z": "7d5c6b14.d2af94",
"name": "Gas",
"func": "var gas = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": gas, \"Datastream\": {\"@iot.id\": 121}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 430,
"y": 400,
"wires": [
[
"c67491fc.f4755"
]
]
},
{
"id": "c7fcb372.4b2df",
"type": "function",
"z": "7d5c6b14.d2af94",
"name": "Loudness",
"func": "var loudness = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": loudness, \"Datastream\": {\"@iot.id\": 120}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 440,
"y": 440,
"wires": [
[
"c67491fc.f4755"
]
]
},
{
"id": "b52fa683.7c5fb8",
"type": "function",
"z": "7d5c6b14.d2af94",
"name": "Dust-PM2.5",
"func": "var Dust = msg.payload.valueOf();\nvar newMessage = { payload: { \"result\": Dust, \"Datastream\": {\"@iot.id\": 128}} };\nnewMessage.headers = {\"Content-type\" : \"application/json\"}\nreturn newMessage;",
"outputs": 1,
"noerr": 0,
"x": 450,
"y": 480,
"wires": [
[
"c67491fc.f4755"
]
]
},
{
"id": "58ceff1f.8576a",
"type": "ttn app",
"z": "",
"appId": "gis-tum-sensors",
"accessKey": "ttn-account-ACCESSKEY_HERE",
"discovery": "discovery.thethingsnetwork.org:1900"
}
]
|