This README describes a simple Node-Red support for our low-cost LoRa gateway. It can be improved in many ways, according to your needs. The current implementation comes with a Node-Red flow that takes the received messages from the gateway, through a file created by a Node-Red dedicated cloud script, to publish data on a topic.
The SD card image has Node-Red installed. You can manually start Node-Red with
> node-red-start
Use your browser on http://192.168.2.8:1880
for instance if this is your gateway's IP address. Make sure that your gateway has internet connection.
If the Node-Red cloud (CloudNodeRed.py
) is enabled in clouds.json
then Node-Red will be started by the start_gw.sh
script. So you do no need to worry about starting manually Node-Red (and you should not start it manually actually).
In the case you use Node-Red for other purposes than CloudNodeRed.py
(the cloud is disabled), then you can enable Node-Red at boot with:
> sudo systemctl enable nodered.service
But be sure that this is what you want because having Node-Red running is resource-consuming. If you just want to test, just use the node-red-start
command. You can disable the service at any time with:
> sudo systemctl disable nodered.service
This is the flow that you can import (copy and then Import/Clipboard):
[{"id":"9da4dd8a.c9626","type":"tab","label":"Node-Red interfacing"},{"id":"34e04f53.c35af8","type":"tail","z":"9da4dd8a.c9626","name":"nodered.txt","filetype":"text","split":true,"filename":"/home/pi/lora_gateway/nodered/nodered.txt","x":100.10000610351562,"y":306.75,"wires":[["2e4be554.fc6ad2"]]},{"id":"2e4be554.fc6ad2","type":"json","z":"9da4dd8a.c9626","name":"","x":256.1000061035156,"y":417.44998931884766,"wires":[["bbed2f33.5940f","84480d69.07fa38"]]},{"id":"952f753f.73ff4","type":"mqtt out","z":"9da4dd8a.c9626","name":"test.mosquitto.org","topic":"","qos":"","retain":"","broker":"1d208c6e.fbfaf4","x":698.1000061035156,"y":354.00000762939453,"wires":[]},{"id":"bbed2f33.5940f","type":"debug","z":"9da4dd8a.c9626","name":"","active":true,"console":"false","complete":"payload","x":427.0999755859375,"y":505.00000762939453,"wires":[]},{"id":"84480d69.07fa38","type":"function","z":"9da4dd8a.c9626","name":"set topic and payload","func":"if (msg.payload.measure==="")\n msg.topic=msg.payload.source\nelse\n msg.topic=msg.payload.source+'/'+msg.payload.measure\nmsg.payload=msg.payload.value\nreturn msg;","outputs":1,"noerr":0,"x":435.10003662109375,"y":362.5499954223633,"wires":[["952f753f.73ff4","6e5a5193.5fd558","12b019d2.0ee98e","db23413e.2bf7d8"]]},{"id":"6e5a5193.5fd558","type":"debug","z":"9da4dd8a.c9626","name":"","active":true,"console":"false","complete":"true","x":618.0999450683594,"y":442.4000015258789,"wires":[]},{"id":"12b019d2.0ee98e","type":"mqtt out","z":"9da4dd8a.c9626","name":"broker.mqttdashboard.com","topic":"","qos":"","retain":"","broker":"6dcd8952.61264","x":727.6000061035156,"y":266.00000762939453,"wires":[]},{"id":"b164c1a3.07001","type":"comment","z":"9da4dd8a.c9626","name":"nodered/nodered.txt is generated by CloudNodeRed.py","info":"","x":229.70001220703125,"y":254.3500213623047,"wires":[]},{"id":"1d208c6e.fbfaf4","type":"mqtt-broker","z":"","broker":"test.mosquitto.org","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""},{"id":"6dcd8952.61264","type":"mqtt-broker","z":"","broker":"broker.mqttdashboard.com","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]
If you also want the version with the contributed ThingSpeak42 node, then import this one but you need to have node-red-contrib-thingspeak42 installed (see below)
[{"id":"9da4dd8a.c9626","type":"tab","label":"Node-Red interfacing"},{"id":"34e04f53.c35af8","type":"tail","z":"9da4dd8a.c9626","name":"nodered.txt","filetype":"text","split":true,"filename":"/home/pi/lora_gateway/nodered/nodered.txt","x":100.10000610351562,"y":306.75,"wires":[["2e4be554.fc6ad2"]]},{"id":"2e4be554.fc6ad2","type":"json","z":"9da4dd8a.c9626","name":"","x":256.1000061035156,"y":417.44998931884766,"wires":[["bbed2f33.5940f","84480d69.07fa38"]]},{"id":"952f753f.73ff4","type":"mqtt out","z":"9da4dd8a.c9626","name":"test.mosquitto.org","topic":"","qos":"","retain":"","broker":"1d208c6e.fbfaf4","x":698.1000061035156,"y":354.00000762939453,"wires":[]},{"id":"bbed2f33.5940f","type":"debug","z":"9da4dd8a.c9626","name":"","active":true,"console":"false","complete":"payload","x":427.0999755859375,"y":505.00000762939453,"wires":[]},{"id":"84480d69.07fa38","type":"function","z":"9da4dd8a.c9626","name":"set topic and payload","func":"if (msg.payload.measure==="")\n msg.topic=msg.payload.source\nelse\n msg.topic=msg.payload.source+'/'+msg.payload.measure\nmsg.payload=msg.payload.value\nreturn msg;","outputs":1,"noerr":0,"x":435.10003662109375,"y":362.5499954223633,"wires":[["952f753f.73ff4","6e5a5193.5fd558","12b019d2.0ee98e","db23413e.2bf7d8"]]},{"id":"6e5a5193.5fd558","type":"debug","z":"9da4dd8a.c9626","name":"","active":true,"console":"false","complete":"true","x":618.0999450683594,"y":442.4000015258789,"wires":[]},{"id":"12b019d2.0ee98e","type":"mqtt out","z":"9da4dd8a.c9626","name":"broker.mqttdashboard.com","topic":"","qos":"","retain":"","broker":"6dcd8952.61264","x":727.6000061035156,"y":266.00000762939453,"wires":[]},{"id":"db23413e.2bf7d8","type":"thingspeak42","z":"9da4dd8a.c9626","name":"ThingSpeak LoRa test channel","delay":"0","topic1":"","topic2":"","topic3":"","topic4":"","topic5":"waziup/UPPA/Sensor6/TC","topic6":"","topic7":"","topic8":"","endpoint":"https://thingspeak.com","x":697.699951171875,"y":170.25,"wires":[]},{"id":"b164c1a3.07001","type":"comment","z":"9da4dd8a.c9626","name":"nodered/nodered.txt is generated by CloudNodeRed.py","info":"","x":229.70001220703125,"y":254.3500213623047,"wires":[]},{"id":"1d208c6e.fbfaf4","type":"mqtt-broker","z":"","broker":"test.mosquitto.org","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""},{"id":"6dcd8952.61264","type":"mqtt-broker","z":"","broker":"broker.mqttdashboard.com","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]
CloudNodeRed.py
will be called by post-processing-gw.py
if a Node-Red cloud is enabled in clouds.json
:
{
"name":"NodeRed flow",
"script":"python CloudNodeRed.py",
"type":"nodered",
"enabled":true
}
Additionally, key_NodeRed.py
will define project_name
, organization_name
and sensor_name
that will be used to build the full sensor name. For instance, with:
project_name="waziup"
organization_name="UPPA"
sensor_name="Sensor"
then, when device 2 sends "TC/22.5/HU/85" to the gateway, CloudNodeRed.py
will generate the following json entries in nodered/nodered.txt
file:
{"source":"waziup/UPPA/Sensor2","measure":"TC","value":22.5}
{"source":"waziup/UPPA/Sensor2","measure":"HU","value":85}
The Node-Red flow is composed of a tail node that follows the nodered/nodered.txt
file for new entries. You may need to install the tail node with:
> cd .node-red/node_modules
> npm install node-red-node-tail
Each entry will be converted into a json object with a json node. A function node will use the json entry to build a message as follows:
if (msg.payload.measure==="")
msg.topic=msg.payload.source
else
msg.topic=msg.payload.source+'/'+msg.payload.measure
msg.payload=msg.payload.value
return msg;
Note the test if (msg.payload.measure==="")
that allow encrypted payload to be passed without trying to append a measure nomenclature (such as TC for instance). Finally, there are 2 MQTT nodes, one using the test.mosquitto.org
broker and the other one using the broker.mqttdashboard.com
broker. The advantage of the latter is to also provide a web interface at http://www.hivemq.com/demos/websocket-client/
for publishing and subscribing. These brokers will receive the messages with the topic defined as waziup/UPPA/Sensor2/TC
and waziup/UPPA/Sensor2/HU
, and will then respectively publish 22.5 and 85 under these topics. The default topic is then project_name+"/"+organization_name+"/"+sensor_name+sensor_address+"/"+measure_name. You can change the function if you want to build a different topic.
There is also a ThingSpeak node sending to our LoRa test channel (https://thingspeak.com/channels/66794). The ThingSpeak node can be installed with:
> cd .node-red/node_modules
> npm install node-red-contrib-thingspeak42
You may need to have npm installed beforehand:
> sudo apt-get install npm
More info on the ThingSpeak node can be found at https://flows.nodered.org/node/node-red-contrib-thingspeak42. The ThingSpeak node waits for the waziup/UPPA/Sensor6/TC
topic to upload the data on field 5. That means real data should come from a device which address is 6. Also, note that if you change project_name
, organization_name
or sensor_name
in key_NodeRed.py
then you have to change the topic name for Topic 5
in the ThingSpeak node configuration.
First, install the mosquitto client software:
sudo apt-get install mosquitto-clients
If you want to install the full package including the mosquitto
MQTT broker and python lib, then:
> sudo apt-get install mosquitto mosquitto-clients python-mosquitto
But if you just want to enable MQTT client, it is advise to just have the mosquitto-clients package.
In a terminal, run:
mosquitto_sub -v -h test.mosquitto.org -t 'waziup/UPPA/Sensor2/#'
or
mosquitto_sub -v -h broker.mqttdashboard.com -i testclient -t 'waziup/UPPA/Sensor2/#'
You can of course subscribe to only one topic if you want:
mosquitto_sub -v -h test.mosquitto.org -t 'waziup/UPPA/Sensor2/TC'
In a terminal, run:
mosquitto_pub -h test.mosquitto.org -t 'waziup/UPPA/Sensor2/TC' -m 22.5
Publishing with http://www.hivemq.com/demos/websocket-client/ to test
In a browser, connect to http://www.hivemq.com/demos/websocket-client/
, then connect to the server and use the publish tab to indicate the topic under which you want to publish and the message you want to publish.
With Node-Red started and the flow loaded and deployed with the web browser, use echo
or printf
in a terminal to write into the nodered/nodered.txt
file:
printf '{"source":"waziup/UPPA/Sensor2","measure":"TC","value":22.5}\n{"source":"waziup/UPPA/Sensor2","measure":"HU","value":85}\n' >> nodered/nodered.txt
You should see in the web browser debug information indicating that new data has been processed by the flow and, most importantly, in the terminal where you subscribed to the `waziup/UPPA/Sensor2/# topics, you should see:
waziup/UPPA/Sensor2/TC 22.5
waziup/UPPA/Sensor2/HU 85
If you want to test the ThingSpeak node:
printf '{"source":"waziup/UPPA/Sensor6","measure":"TC","value":22.5}\n' >> nodered/nodered.txt
- enable
CloudNodeRed.py
inclouds.json
- start Node-Red on your gateway if needed:
node-red-start
- import the flow and deploy it
- use the simple temperature sensor to send data to the gateway:
TC/22.5
for instance - use the gateway or another computer to subscribe to the topic:
waziup/UPPA/Sensor2/TC
for instance, depending on the address of your sensor node and yourkey_NodeRed.py
configuration
Of course, it is very simple to simply publish to an MQTT topic directly with the gateway. Look at the CloudMQTT.py
cloud script that again uses the test.mosquitto.org
broker. key_MQTT.py
defines variables that will be used by CloudMQTT.py
to build the MQTT topic.
Enjoy! C. Pham