LoRaWAN TTN und openSenseMap


#1

Hallo zusammen,

ich experimentiere grade ein wenig herum um LoRa kennen zu lernen, doch habe ich noch ein paar Probleme.

Mein derzeitiger Stand ist, das die senseBox die Daten hoch zum TTN läd über LoRa, die Daten kommen also an.

Als nächstes hatte ich die HTTP Integration eingestellt und danach habe ich das “senseBox:home” Decoding-Profil im Payload Format eingestellt, alles nach der Offiziellen Anleitung https://sensebox.github.io/books-v2/home/de/komponenten/bees/lora.html.

Auf der openSenseMap habe ich dann die app_id und diedev_id eingetragen.

Leider kommen aber keine Daten auf der openSenseMap an.

Um zu schauen ob und welche Daten bei TTN Daten raus gehen, habe ich in der HTTP Integration die Ausgabe nach https://requestbin.com umgeleitet und mir angeschaut was dort raus geht.

{
“app_id”: “name_vom_projekt”,
“dev_id”: “name_der_sensebox_1”,
“hardware_serial”: “Nummer…”,
“port”: 1,
“counter”: 1716,
“payload_raw”: “rH6fFW/prREAnQAA”,
“metadata”: {
“time”: “2019-04-19T12:28:27.433849434Z”,
“frequency”: 867.3,
“modulation”: “LORA”,
“data_rate”: “SF12BW125”,
“coding_rate”: “4/5”,
“gateways”: [
{
“gtw_id”: “nummer”,
“timestamp”: 2520404524,
“time”: “2019-04-19T12:28:27.402023Z”,
“channel”: 4,
“rssi”: -115,
“snr”: -13.8,
“rf_chain”: 0,
“latitude”: 52.45755,
“longitude”: 13.527121,
“altitude”: 28,
“location_source”: “registry”
}
]
},
“downlink_url”: “https://integrations.thethingsnetwork.org/ttn-eu/api/v2/down/_name_vom_projekt/_name_der_sensebox_integration?key=ttn-account-lange Nummer
}

Natürlich habe ich die Daten anonymisiert, doch ich bin mir jetzt nicht sicher, ob das die Daten sind die vom Decoder für die senseMap aufbereitet werden, ein Gefühl sagt mir aber, das da noch etwas nicht korrekt Arbeitet, aber ich komme grade nicht dahinter.

Oder muss sich die openSenseMap die Daten für die Sensoren über den Link abholen und es ist doch alles richtig ?

Danke für Eure Tips und Frohe Ostern

Holger


#2

Moin Holger,

In Deinen Ausführungen finde ich keinen Hinweis zu einem LoRaWAN Gateway, welches die Daten Deiner SenseBox empfängt und dann über das INet ans TTN weiterleitet. Das Gateway ist in jedem Fall erforderlich. Ohne geht es nicht.

Du müsstest also zuerst einmal überprüfen, ob es in Deiner Nähe ein TTN Gataway gibt.

Schau Dir dafür einmal diese Website an: https://www.thethingsnetwork.org/

Gruß Heiner


#3

Eine weitere gute Seite um die LoRa Verfügbarkeit über TTN zu checken ist https://ttnmapper.org/


#4

Hallo Heiner und Gerald,

wie schon geschrieben, die Daten kommen definitiv über LoRa bei TTN an, denn ich habe definitiv ein Gateway was erreicht wird, die Angaben und auch das kann man gleich im Eingangspost entnehmen.

Ich habe die Daten per HTTP Integration zum Schauen was bei TTN rausgeht, statt zur openSenseMap einfach mal auf https://requestbin.com umgeleitet.

Dazu war nur nötig bei der HTTP Integration die Adresse von https://ttn.opensensemap.org/v1.1 auf https://requestbin.com zu ändern und schon konnte ich sehen, was bei TTN rausgeht und bei der openSenseMap ankommen müsste.

Ich Vermute daher bei mir einen Fehler in Richtung Decoder, da muss ich irgendwas noch falsch machen. Ich hatte nämlich erwartet, das TTN gleich die Messwerte direkt mit der Sensor ID, die ich ja beim Anlegen der sensBox erhalten habe und natürlich auch im Dekoder auf der TTN Seite angegeben habe, rausschickt.

Aber zu meinem erstaunen stellte ich fest, das TTN neben den Payload, nur einen Link mit schickt, der mir aber im Browser keine Daten anzeigt, wenn ich ihn aufrufe.

Wie nun die Kommunikation TTN zu openSenseBox läuft ist für mich der knackpunkt.

Danke für eure Mühe mir am Ostersonntag mit Rat beiseite zu stehen.

Ich wünsche noch einen schönen Ostermontag.

Viele Grüße

Holger


#5

Vielleicht sollte ich das Vorgehen mit https://requestbin.com noch etwas genauer beschreiben.

Als erstes geht man auf die Webseite https://requestbin.com und klickt dort auf den Button “Create a Request Bin”.

Darauf Hin öffnet sich ein neues Fenster und man erhält einen Link zu dem erzeugten Endpunkt.

"Your endpoint is

https://enc0znmu0pd0g.x.pipedream.net" ( Beispiel Link wie er dann aussieht, ist natürlich Ohne Funktion da immer wieder ein neuer Link generiert wird… )

Diesen Link kann man dann nehmen und auf der Webconsole von TTN bei Intregration eintragen, wo normalerweise bei uns der Link https://ttn.opensensemap.org/v1.1 hin gehört.

TTN schickt darauf hin die Daten, die normal zur openSenseMap gehen würde, auf die Seite von requestbin und man kann sich genauer anschauen, was bei TTN rausgegangen ist, so jedenfalls mein Verständnis bis zu dem Punkt.

Viele Grüße

Holger


#6

Moin Holger,

ich habe das Beispiel mit “request.bin” gerade mal nachvollzogen und komme zu einem ähnlichen Ergebnis. Die gesendeten Daten kommen also beim TTN an und werden auch weitergeschickt.

Jetzt solltest Du noch mal bei opensensemap.org überprüfen, ob die richtigen Parameter für TheThingsNetwork (TTN) eingetragen sind, damit Deine Daten auch zugeordnet werden können. Speziell die TTN Application-ID und die Device-ID.

Das Portal opensensemap.org ist heute sehr langsam. Das kann also etwas dauern.

Gruß Loobster


#7

Hallo Heiner,

vielen Herzlichen Dank für ausprobieren, das hilft mir wirklich sehr weiter.

Ich werde so schnell wie möglich schauen, was bei mir noch nicht ganz rund läuft, aber ich habe jetzt einen Anhaltspunkt mehr.

Viele Grüße

Holger


#8

Hallo Zusammen,

hab den Fehler gefunden, es lag wirklich wie vermutet am Decoder bei TTN.

Ich habe erst alles rauskopiert, dann den Standart Decoder ausprobiert und danach einfach wieder alles eingefügt und auf einmal Funktionierte es.

Es ist mir grade noch ein Rätsel, wo ich was falsch gemacht hatte, aber ich habe durch die Fehlersuche sehr interessante dinge gelernt.

Viele Grüße

Holger


#9

Dear Holger,

Akzeptiere es bitte das ich im English weiter schreibe weil ich die Deutsche sprache nicht gut kontrolliere, aber jedoch verstehe.

A little question, in your last post you stated that you found the solution on the TTN side for your decoding problem.
Can you describe a bit further while we have the same problem.
With our sensebox defined as a lora node on TTN, how can we show the data in OSeM when it arrives on TTN and from their onwards my fine dust sensor data is being forwarded to OSeM with an HTTP integration to https://ttn.opensensemap.org/v1.1 ?
I read somewhere in the docs about the JSON profile to choose in the decoding profile on OSeM. But what I do not understand is what kind of payload format I have to use on the TTN side for my registered device. Can you show me yours (decoder or encoder) on the console of TTN?

I really appreciate your help as I am stuck for this moment.
Have a great evening.


#10

Dear Sensebox members,

i want to bring up this post again as we still struggle with our fine dust sensor.
Uptil now, we succeeded in using a lora connection via TTN to display our temperature and humidity values. But the fine dust values are not in the correct format as seen here (https://opensensemap.org/explore/5dd3c45c4ec04e001ae4aef7):
fine_dut_osem
No way the actual dust level is 4096.1 µg/m³ !!!

It is mentioned in the docs that a JSON profile should be used to format the PM values in the right way. As a result, in TTN one should create a decoder to format the payload. I have used this payload format in the console of TTN, but to no avail:

function Decoder(bytes, port) {
 // bytes is of type Buffer.
 'use strict';
 var TEMPSENSOR_ID="5dce6d08306947001ae15f4e",
   HUMISENSOR_ID="5dce6d08306947001ae15f4d",
   PM10_ID="5dd27c104ec04e001a8596eb",
   PM25_ID="5dd27c104ec04e001a8596ea";
  var lat = 0,lng = 0;
 var bytesToInt = function (bytes) {
   var i = 0;
   for (var x = 0; x < bytes.length; x++) {
     i |= +(bytes[x] << (x * 8));
   }
   return i;
 };

 var latLng = function(bytes) {
  if (bytes.length !== latLng.BYTES) {
    throw new Error('Lat/Long must have exactly 8 bytes');
  }

  lat = (bytesToInt(bytes.slice(0, latLng.BYTES / 2))/1e2)/10000;
  lng = (bytesToInt(bytes.slice(latLng.BYTES / 2, latLng.BYTES))/1e2)/10000;

};
latLng.BYTES = 8;

 var uint8 = function (bytes) {
   if (bytes.length !== uint8.BYTES) {
     throw new Error('int must have exactly 1 byte');
   }
   return bytesToInt(bytes);
 };
 uint8.BYTES = 1;

 var uint16 = function (bytes) {
   if (bytes.length !== uint16.BYTES) {
     throw new Error('int must have exactly 2 bytes');
   }
   return bytesToInt(bytes);
 };
 uint16.BYTES = 2;


 var humidity = function (bytes) {
   if (bytes.length !== humidity.BYTES) {
     throw new Error('Humidity must have exactly 2 bytes');
   }

   var h = bytesToInt(bytes);
   return h / 1e2;
 };
 humidity.BYTES = 2;
var decode = function (bytes, mask, names) {

   var maskLength = mask.reduce(function (prev, cur) {
     return prev + cur.BYTES;
   }, 0);
   if (bytes.length < maskLength) {
     throw new Error('Mask length is ' + maskLength + ' whereas input is ' + bytes.length);
   }

   names = names || [];
   var offset = 0;
   return mask
     .map(function (decodeFn) {
       var current = bytes.slice(offset, offset += decodeFn.BYTES);
       return decodeFn(current);
     })
     .reduce(function (prev, cur, idx) {
       prev[names[idx] || idx] = cur;
       return prev;
     }, {});
 };
 var bytesToSenseBoxJson = function (bytes) {
   var json;

   try {
     json = decode(bytes,
       [
       uint16,
       humidity,
       uint16,
       uint16,
       latLng,
       uint16,
       uint16,
       uint16,
       uint16,
       uint16,
       uint16
       ],
       [
       TEMPSENSOR_ID,
       HUMISENSOR_ID,
       PM10_ID,
       PM25_ID,
       "location",
       "year",
       "month",
       "day",
       "hour",
       "minute",
       "second",
       ]);

    if(json['month'] === 0){
      json['month'] = 1;
    }
    if(json['day'] === 0){
      json['day'] = 1;
    }
     //temp
     json[TEMPSENSOR_ID] = [String(parseFloat(((json[TEMPSENSOR_ID] / 771) - 18).toFixed(1))),String(json["year"])+"-"+String(("0" + json["month"]).slice(-2))+"-"+String(("0" + json["day"]).slice(-2))+"T"+String(("0" + json["hour"]).slice(-2))+":"+String(("0" + json["minute"]).slice(-2))+":"+String(("0" + json["second"]).slice(-2))+"Z",[lng,lat]];

     //hum
     json[HUMISENSOR_ID] = [String(parseFloat(json[HUMISENSOR_ID].toFixed(1))),String(json["year"])+"-"+String(("0" + json["month"]).slice(-2))+"-"+String(("0" + json["day"]).slice(-2))+"T"+String(("0" + json["hour"]).slice(-2))+":"+String(("0" + json["minute"]).slice(-2))+":"+String(("0" + json["second"]).slice(-2))+"Z",[lng,lat]];

     // pm10
     json[PM10_ID] = [String(parseFloat((json[PM10_ID] / 10).toFixed(1))),String(json["year"])+"-"+String(("0" + json["month"]).slice(-2))+"-"+String(("0" + json["day"]).slice(-2))+"T"+String(("0" + json["hour"]).slice(-2))+":"+String(("0" + json["minute"]).slice(-2))+":"+String(("0" + json["second"]).slice(-2))+"Z",[lng,lat]];
     // pm25
     json[PM25_ID] = [String(parseFloat((json[PM25_ID] / 10).toFixed(1))),String(json["year"])+"-"+String(("0" + json["month"]).slice(-2))+"-"+String(("0" + json["day"]).slice(-2))+"T"+String(("0" + json["hour"]).slice(-2))+":"+String(("0" + json["minute"]).slice(-2))+":"+String(("0" + json["second"]).slice(-2))+"Z",[lng,lat]];
     delete json.year;
     delete json.month;
     delete json.day;
     delete json.hour;
     delete json.minute;
     delete json.second;

   } catch (e) {
     json = { payload: bytes };
   }

   return json;
 };

 return bytesToSenseBoxJson(bytes);
}

Any one has a clue on where the problem is?


#11

Moin lieber Mitglieder von die SenseBox community,

Ich wollte gern wieder diesem Umsatz Problem ansprechen. In English leider :sweat_smile:

We are using the SDS fine dust and the HDC temp/hum sensor on the MCU with a lora connectivity via TheThingsNetwork. Their data is well received on the TTN console and an HTTP integration is made to OSeM, no problem with this one.

But the values of the dust sensor are not the correct ones when visualised in OSeM. I have tried a JSON profile with a Payload Function in TTN as described in my previous post.

Today I tried a lora-serialisation profile with these decode options filled in:

[{“decoder”:“latLng”},{“decoder”:“temperature”,“sensor_title”:“Temperatur”},{“decoder”:“humidity”,“sensor_title”:“rel. Luftfeuchte”},{“decoder”:“temperature”,“sensor_title”:“PM2.5”},{“decoder”:“temperature”,“sensor_title”:“PM10”}]

I found this info on https://github.com/sensebox/mobile-sensebox/tree/master/lora-gps
But no result whatsoever; no measurements are coming in on https://opensensemap.org/explore/5ddf8b232b3516001a522ec3 after resetting the decoding profile in the OSeM page.

This is a real difficulty and I wonder if some one could help me out in displaying the right PM values when using lora connectivity.

Danke vielmal.


#12

Hi @wdebbaut,

sorry for this late response and that the values are not correctly displayed on openSenseMap. I have some pretty busy work days. I will try to find some spare time this weekend and have a look at it.

Best, Matthias