Wednesday, February 22, 2017

Update from Farm-Team: Information flow on the ioBroker

Main hub IO

We have our wireless sensor nodes sending in information over MQTT to the Eclipse Mosquitto broker (localhost) and we have the main hub controller sending data over serial.

We are using Node-RED flows for the receiving and sending end.

Input

Main hub sensor

Our Node-RED flow is very simple as you will see on the screenshot below. We already mentioned in an earlier blog that we send the data in form of JSON over serial from the nanoESP.


Flow:

Data coming over serial port (node-red-node-serialport) => JSON conversion to object => next is a simple JavaScript function that breaks down the object (see code on the right) => and writes the values to ioBroker objects

This is how the ioBroker retains the data:

We added the history node (adapter), which is a multifunctional (in memory and on disk) database. The objects can be setup to be stored in the database.


Enabling the data retention

Table with historical values

Sensor nodes

Our sensor nodes are sending data to our Eclipse Mosquitto broker in the main hub.

Flow:

MQTT listener (mqtt) listening to topic moisture (as an example as we have more than one) => and writes the values to ioBroker objects. The data is retained like we showed before.


Output

Due to us sending data over GSM/Edge we will stich the main hub and sensor data together to avoid sending to many packages as the number of sensor nodes are not limited (and we can monitor a defined message standard better). We have written a script that does just that (stitching) using the Javascript node (adapter). This is basically a JavaScript IDE for the ioBroker.

This code runs every ten seconds and reads all the measurement objects in the database and writes it all to a JSON array in an ioBroker object.




Script:

 schedule("*/10 * * * * *", function () {  
   var altitude = getState('node-red.0.smartwatering.mainhub.altitude');  
   var calcpressuresealevel = getState('node-red.0.smartwatering.mainhub.calcpressuresealevel');  
   var humidity = getState('node-red.0.smartwatering.mainhub.humidity');  
   var light = getState('node-red.0.smartwatering.mainhub.light');  
   var pressure = getState('node-red.0.smartwatering.mainhub.pressure');  
   var rain = getState('node-red.0.smartwatering.mainhub.rain');  
   var realaltitude = getState('node-red.0.smartwatering.mainhub.realaltitude');  
   var temperature1 = getState('node-red.0.smartwatering.mainhub.temperature1');  
   var temperature2 = getState('node-red.0.smartwatering.mainhub.temperature2');  
   var soilmoisture1 = getState('node-red.0.smartwatering.sensornodes.soilmoisture1');  
   var soilmoisture2 = getState('node-red.0.smartwatering.sensornodes.soilmoisture2');  
   var soilmoisture3 = getState('node-red.0.smartwatering.sensornodes.soilmoisture3');  
   var soilmoisture4 = getState('node-red.0.smartwatering.sensornodes.soilmoisture4');  
   var sensordataobj = '{\"d\" : { \"altitude\" : ' + JSON.stringify(altitude)   
   + ', \"calcpressuresealevel\" : ' + JSON.stringify(calcpressuresealevel)  
   + ', \"humidity\" : ' + JSON.stringify(humidity)  
   + ', \"light\" : ' + JSON.stringify(light)   
   + ', \"pressure\" : ' + JSON.stringify(pressure)   
   + ', \"rain\" : ' + JSON.stringify(rain)   
   + ', \"realaltitude\" : ' + JSON.stringify(realaltitude)   
   + ', \"temperature1\" : ' + JSON.stringify(temperature1)   
   + ', \"temperature2\" : ' + JSON.stringify(temperature2)   
   + ', \"soilmoisture1\" : ' + JSON.stringify(soilmoisture1)  
   + ', \"soilmoisture2\" : ' + JSON.stringify(soilmoisture2)  
   + ', \"soilmoisture3\" : ' + JSON.stringify(soilmoisture3)   
   + ', \"soilmoisture4\" : ' + JSON.stringify(soilmoisture4)  
   +'}}';  
   createState('sensordataobj');  
   setState('sensordataobj', sensordataobj);  
   console.log(sensordataobj);  
 });  


So now that we have all of our data in an object (called "sensordataobj) we send it all to our cloud using Node-RED:


Flow:

At an interval of 3 minutes (testing) => we send the object sensordataobj as an array => to the cloud using the IBMIoT node (node-red-contrib-scx-ibmiotapp and node-red-contrib-iotclouddev

The quick start mode allows us to see the result (without any registration to the platform) using the MAC address of our main hub as device id:


The data we are sending to the cloud looks like this:
  {“d” : { "altitude" : {"val":421.48,"ack":true,"ts":1486933460625,"q":0,"from":"system.adapter.node-red.0","lc":1486933460625}, "calcpressuresealevel" : {"val":96365,"ack":true,"ts":1486933460634,"q":0,"from":"system.adapter.node-red.0","lc":1486933460634}, "humidity" : {"val":54,"ack":true,"ts":1486933460647,"q":0,"from":"system.adapter.node-red.0","lc":1486933419447}, "light" : {"val":63,"ack":true,"ts":1486933460409,"q":0,"from":"system.adapter.node-red.0","lc":1486932505750}, "pressure" : {"val":96365,"ack":true,"ts":1486933460576,"q":0,"from":"system.adapter.node-red.0","lc":1486933460576}, "rain" : {"val":106,"ack":true,"ts":1486933460660,"q":0,"from":"system.adapter.node-red.0","lc":1486933460660}, "realaltitude" : {"val":435.81,"ack":true,"ts":1486933460641,"q":0,"from":"system.adapter.node-red.0","lc":1486933460641}, "temperature1" : {"val":22.5,"ack":true,"ts":1486933460467,"q":0,"from":"system.adapter.node-red.0","lc":1486933460467}, "temperature2" : {"val":21.9,"ack":true,"ts":1486933460654,"q":0,"from":"system.adapter.node-red.0","lc":1486931918181}, "soilmoisture1" : {"val":"91","ack":true,"ts":1486933451665,"q":0,"from":"system.adapter.node-red.0","lc":1486923522504}, "soilmoisture2" : {"val":"91","ack":true,"ts":1486933451665,"q":0,"from":"system.adapter.node-red.0","lc":1486923522504}, "soilmoisture3" : {"val":"91","ack":true,"ts":1486933451665,"q":0,"from":"system.adapter.node-red.0","lc":1486923522504}, "soilmoisture4" : {"val":"91","ack":true,"ts":1486933451665,"q":0,"from":"system.adapter.node-red.0","lc":1486923522504}}}  

See link for description of meta data.

No comments:

Post a Comment