Mapping The Things Network with a LoPy (4). Node-Red backend

This page will not go into the details on how to install and run Node-Red on a Raspberry Pi. Other resources about that can be found here and here.

A primer on how to use the TTN nodes in Node-Red can be found here

Messages from our Tracker node as received by any (some) of the TTN gateways are made available through the TTN Node-Red node. A received message not only contains the message itself but also the meta data which contains details on the gateways who recieved the me’ssage. Thus we can calculate the distance between LoRa sender and LoRa receiver(s).TTN mapper Node-RED

At the core is the function node which processes each received packet. It calculates the distance between receiver (from the array of gateways in the received meta data) and the sender (from the data in the actual message). It keeps track of the number of messages (packets) received and the number of unique gatways which received a message. The tracker itself will keep track of the longest distance of messages received so we don’t need to send that back to the tracker for display.

Apart from data being send back to the tracker the function also prepares data to be logged. By doing so we can later evaluate the results of our tracking journey. Also the  current location of the Tracker will be shown on the page of Node-Red.

//function claculates distance between locations in meters
function getdistance(lat1, lon1, lat2, lon2) {
 var R = 6371000; // Radius of the earth in m
 var dLat = (lat2 - lat1) * Math.PI / 180;
 var dLon = (lon2 - lon1) * Math.PI / 180;
 var a = 
 0.5 - Math.cos(dLat)/2 + 
 Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
 (1 - Math.cos(dLon))/2;

return Math.ceil(R * 2 * Math.asin(Math.sqrt(a)));

//reset gateways, packets and couter if tracker did restart
var counter = flow.get("counter");
if (msg.counter < counter){
 gateways = 0;
 packets = 0;
 var unique_gateways = [];
} else {
 gateways = flow.get("gateways");
 packets = flow.get("packets");
 var unique_gateways = flow.get("unique_gateways"); 

flow.set("counter", msg.counter);

var lat_m = msg.payload_fields.latitude;
var lon_m = msg.payload_fields.longitude;

var gatewaysarray = msg.metadata.gateways;
var distancesarray = [];

//log received data on second port
var logMsgs = [];
var currentTime = new Date().getTime();

//process new packet
packets = packets + 1;
for (i = 0; i < gatewaysarray.length; i++){
 distancesarray[i] = getdistance(lat_m, lon_m, gatewaysarray[i].latitude, gatewaysarray[i].longitude);
 logMsgs.push({payload: {time: currentTime,
 my_lat: lat_m,
 my_lon: lon_m,
 gateway: gatewaysarray[i]
 if(unique_gateways.indexOf(gatewaysarray[i].gtw_id) == -1){
 //new gateway found
 gateways = gateways + 1;
var distance = Math.max(...distancesarray);

//store results of this packet
flow.set("unique_gateways", unique_gateways);

return [{
 dev_id: msg.dev_id,
 port: msg.port,
 payload: {
 packets: packets,
 gateways: gateways,
 distance: distance


Note that data received from the tracking node and send back to it needs to be packed in a byte array to limit the number of bytes transferred over the wireless link. The conversion between a javascript object and the byte array is handled by the decoder and encoder found under “payload formats” of your application in The Things Network console.

The decoder will convert the packed payload as received from the Tracker by the gatewato a JS object while the encoder will encode the JS object Node-Red returns to reply it back to the Tracker which can then display it. Find the encoder and decoder as encoder.js and decoder.js on Github

This entry was posted in LoRa and tagged , , . Bookmark the permalink.

3 Responses to Mapping The Things Network with a LoPy (4). Node-Red backend

  1. Pingback: A LoRa 868MHz Collinear antenna | Projects by Keptenkurk

  2. richardwenner says:

    I have made this video but I can not find where you get your ttn message or ttn send nodes. Could you tell me please?

    Liked by 1 person

  3. keptenkurk says:

    Brilliant Video @richardwenner
    The TTN nodes were added through the palette mananger. Search for node-red-contrib-ttn
    Current version is 2.0.4.
    Or install it from the commandline by
    cd $HOME/.node-red
    sudo npm install node-red-contrib-ttn


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s