Nach dem mein Mini Node nun schon gut 3 Monate ohne Probleme seine Messdaten über das TTN (TheThingsNetwork) an unsere Datenbank versendet war es an der Zeit diese Daten auch auf die openSenseMap zu bringen.
Die openSenseMap ist eine offene Plattform um dort unterschiedliche Sensoren auf einer Karze anzeigen zu lassen. Diese Karte ist als Visualisierungspattform für die openSenseBox entstanden und kann von jedem mit Daten versorgt werden. So entsteht ein dichtes Sensoren-Netzwerk welches von Bildungseinrichtungen und Privatpersonen betrieben wird.Die Hardware meines Nodes besteht aus einem 10€ Node auf Basis des Arduino 328 mini pro, dem RFM95W um an LoRaWAN teilzunehmen und einem BME280 als Umweltdaten Sensor der Temperatur, Luftdruck und relative Luftfeuchte messen kann. Der Node wird mit einem 700 mAh LiPo Akku betrieben der mit einem TP4056 1A Laderegler verbunden ist. Somit kann der Node später auch mit einer Solarzelle zusätzlich mit Strom versorgt werden und eigentlich über den Sommer vollkommen autonom laufen.
Bis jetzt werden die Messwerte über das TTN an unsere eigene InfluxDB gesendet und mittels Grafana visualisiert. Hier der Link zur Auswertung auf unserer Plattform. Ich finde es aber besser wenn die Daten auch bei anderen Projekten sichtbar sind, so kann man diese dann auch besser weiter verarbeiten und zum Beispiel in Regionalen Klimaauswertungen verwenden.
Um seine Daten bei openSenseMap zu visualisieren muss man sich als erstes dort anmelden. Link zur openSenseMap.org
Dort muss man dann eine neue SenseBox registrieren. Auch wenn man halt keine original SenseBox nutzt kann man jeden beliebigen Sensor Node dort anmelden.
Nach dem klick auf Neue SenseBox erscheint ein Hinweis auf die vom Projekt gespeicherten Daten und deren Verwendung. Das finde ich persönlich sehr gut gelöst und ist in kaum einem anderen Projekt so deutlich gezeigt worden.
Hier geht es dann weiter wenn ihr der Speicherung der Daten zustimmt.
Als nächstes werden Informationen über die neue Box angefragt.
Allgemein
- Name der Station
ich verwende immer die Postleitzahl um den meine Sensoren schnell wieder zu finden oder einen Prefix der mir den Typen des Node mitteilt. Also dieser Sensor wird TTN Wetter als Prefix erhalten. - Aufstellungsort
outdoor, indoor, mobile - Gruppenkennzeichnung
diese Kennzeichnung kann wohl Sensoren zu den diversen Projekten zusammen fassen die ihre Daten dort abliefern. Wir könnten zum Beispiel alle unsere Sensoren TTN-Schleswig nennen. Ich habe zur Zeit die Gruppe FFSLFL gewählt, da mein erster Sensor halt noch vor der IoT-UG Zeit erstellt worden ist.Standort
- Abfrage der Geo Location mittels Karte oder Koordinaten
Hardware
Hier gibt es nun eine Auswahl von vorkonfigurierten SenseBoxen so wie diversen Node Kombinationen aus dem Projekt Luftdaten.info dem Feinstanub Projekt aus Stuttgart. Da wir aber einen Sensor aus dem TTN einrichten möchten der nicht vorkonfiguriert ist wählen wir an dieser Stellen die manuelle Konfiguration aus.
Dort können wir nun die Sensoren des Node erstellen.
- Spannung
- Temperatur
- Luftfeuchtigkeit
- Luftdruck
Erweitert
Der letzte Bereich beinhaltet nun die Schnittstellen die eigentlich funktionieren sollten um die Daten von anderen Plattformen einzusammeln.
- MQTT
- TheThingsNetwork – TTN
Aber an genau dieser Stelle beginnt mein Drama, weder die MQTT Schnittstelle noch die TTN Schnittstelle bekomme ich konfiguriert.
Bei MQTT ist es noch relativ einfach die URL zu benennen um auf den MQTT Server beim TTN zuzugreifen. Diese lautet eu.thethings.network das Topic ist auch noch gut im TTN dokumentiert, es lautet:
<app-id>/devices/<dev-id>/up/<field>
Und hier klemmt es dann schon das erste mal ordentlich, denn unsere SenseBox hat ja 4 Sensoren. Also kann man den MQTT an dieser Stelle nicht gebrauchen ohne das man aus dem möglichen Payload_raw Feld die Daten endcodet.
Wie sieht es mit dem TTN Bereich aus?
Die TTN Application-ID und TTN-Device-ID sind noch einfach, diese findet man ja in der TTN Console. Aber wie wird nun eine Authentifizierung am Netzwerk möglich? Die Antwort bleibt das Formular schuldig, die verlinkten Informationen helfen auch nur semi weiter. Bei den Dekodierungsoptionen kann ich mir noch zusammen reimen das die wohl die Zuordnung der SenseBox Sensoren zu den Payload Feldern aus dem TTN gemacht werden soll. Na ja aber ohne eine Option zur Authentifizierung wird das erst einmal direkt nicht funktionieren. Es ist in der Verlinkung aber von einem Docker File die Rede mit der man wahrscheinlich diese Daten über den Umweg holen kann.
Lange Rede, kurzer Sinn mittels MQTT oder TTN wird es nichts mit den Daten für meinen Node. Leider sind alle Plattformen relativ schweigsam wenn die Parameter nicht richtig eingestellt sind, Fehlermeldungen gibt es halt keine und ein Log in der man nach Fehlern forschen könnte gibt es auch nicht. Also muss etwas genommen werden mit der man ein wenig licht ins Dunkel bringen kann.
Nach dem die neue SenseBox konfiguriert ist erhaltet Ihr eine Mail mit einem Arduino Sketch und den wichtigen Informationen zu eurer neuen SenseBox.
Dort ist nun auch die SenseBox ID enthalten mit der Ihr mit der Box kommunizieren könnt und für jeden eingerichteten Sensor gibt es auch eine eigene ID. In diesem Beispiel sind es:
- senseBox ID
- Spannung
- Temperatur
- Luftfeuchtigkeit
- Luftdruck
Diese Kennungen werden wir später nutzen um damit die url zusammen zu bauen.
Die Stunde von Node-Red ist gekommen
Es ist ja nicht so als hätte man keine weiteren Möglichkeiten, die openSenseMap hat eine eigene API dessen Dokumentation sehr ordentlich ist.
Mittels dieser API, der TTN API und Node-Red ist es auch möglich die Daten aus dem TTN an die openSenseMap zu transportieren. Wir haben eine Node-Red Installation unter https://node-red.iot-usergroup.de eingerichtet um genau für diese Fälle etwas zu experimentieren. Besucher können sich die Flows gerne ansehen, dazu haben wir einen Viewer eingerichtet dessen Passwort bei uns erfragt werden kann.
Anmelden bei Node-Red
Meldet euch nun an eurer Node-Red Instanz an und erstellt einen neuen Flow.
Durch ein doppelklick auf den Reiter des Flow könnt ihr einen passenden Namen vergeben und den Flow beschreiben. Eine Dokumentation im Flow erleichtert euch eurer Werk auch nach einigen Wochen noch zu verstehen.
Den Flow planen
Es ist natürlich immer gut wenn man sich im klaren ist was man denn so machen möchte, also planen wir unseren Flow einfach mal kurz.
- Daten vom TTN Node abholen
- Daten in das passende Format bringen
- Das Ergebnis an die SenseBox übertragen
- Header und URL setzen
- HTTP Request absetzen
So, war doch schon mal einfach. Aber wie bekommen wir denn nun diese Daten abgeholt?
Daten vom TTN abholen
In Node-Red gibt es einen Code Block “node-red-contrib-ttn” der für das TTN nachinstalliert werden muss. Auf die Installation gehe ich hier nicht weiter ein und nehme an das ihr dieses selber schon erledigt habt.
Weitere Infos findet Ihr hier zum Thema Installation von node-red-contrib-ttn
Das Plugin liefert einige Nodes für den Flow, uns interessiert hier nun der Node
“ttn uplink” In diesem Node stellen wir die Verbindung zur TTN Applikation her. Ein doppelklick öffnet den Editor in dem nun die TTN Application erstellt werden kann.
Wir vergeben einen Namen und klicken auf den Stift um die TTN App zu bearbeiten oder wählen eine vorher schon erstellte TTN App aus. Nun müssen wir noch das Device benennen von dem wir die Daten haben möchten.
Ist die Application noch nicht erstellt finden wir nach dem klick auf den Stift folgenden Dialog. Dort muss die App ID und der Access Key eingetragen werden. die Discovery Adress ist voreingestellt und passt wenn man direkt mit dem TTN arbeitet. Danach können wir den Dialog schließen und die passende App ist in der Auswahl schon eingestellt. Damit können wir nun die Daten der App in diesen Flow holen.
Den Payload aufbereiten
Nun nutzen wir den Node template um den vorhandenen Payload in die für openSenseMap verträglichen Stücke zu zerlegen.
Ein doppelklick öffnet den Editor. Hier benennen wir den Node mit “Payload Sensor1” und schreiben im Editor Feld unseren Code.
{ "value": {{payload.batt}} }
Diesen Schritt wiederholen wir für alle Sensoren mit den passenden Code Schnipseln:
{ "value": {{payload.temperature}} }
{ "value": {{payload.pressure}} }
{ "value": {{payload.humidity}} }
Wichtig ist das wir das Output Format der template Nodes von plain Text auf JSON umstellen.
Jetzt haben wir also 4 Template Nodes für jeden Sensor einen. Als nächstes bereiten wir das Übertragen der Daten vor in dem wir die Header und die URL zusammen sethen.
Dazu nutzen wir den Node change . Dieser Node ermöglicht uns die diverse Message Regeln zu setzen. Ein doppelklick bringt uns zum Editor, dort erzeugen wir 3 neuen Einträge. Header, url und method
Der Eintrag Header bekommt die Information
{ "Content-Type" : "application/json", "Host": "www.opensensemap.org"}
Der Eintrag url
http://www.opensensemap.org:8000/boxes/5a9523ebbc2d4100192e7d2c/5a9523ebbc2d4100192e7d2e
Dieser Eintrag besteht aus der url http://www.opensensemap.org:8000/boxes/ der SenseBox-ID so wie der Sensor-ID
Der Eintrag method POST
Diesen Node müssen wir nun auch vier mal erstellen da jeder Sensor seine eigen url bekommt.
Übertragen der Daten an openSenseMap
Damit wir nun die Daten an die openSenseMap versenden können benötigen wir den Node “http request” welcher die Übertragung der im letzten Schritt erstellten Daten übernimmt.
Um den Editor zu öffnen wie immer ein doppelklick auf den Node. Hier stellen Wir die Methode auf “set by msg method” und das Return auf “a paresed JSON object” ein.
Somit wird die Rückgabe com Server als JSON Objekt geliefert.
Dieses lassen wir uns mittels einem Debug Node anzeigen.
Debug Nodes erstellen
Damit wir etwas sehen können erstellen wir uns an drei Stellen Debug Nodes. Diese Nodes haben auch einen Editor den man mit einem doppelklick erreicht.
Grundeinstellung ist msg.payload als Output, dieses stellen wir für den Node ttn uplink aber auf “complete msg object” um.
Geben dem Node noch einen aussagekräftigen Namen und platzieren ihn unter dem ttn uplink.
Einen weiteren Debug Node erstellen wir für die template Nodes. Bei diesem können wir bis auf dem Namen die Einstellungen so belassen.
Nun verbinden wie die Nodes und setzen noch einige Kommentare so das unser Flow dann wie folgend ausschaut.
Nun noch rechts oben auf Deploy drücken und dann sollte der Flow arbeiten.
Nach einigen Minuten erscheint dann im Debug Tab das Ergebnis des aktuellen Durchlaufs und auf der openSenseMap erscheinen die Werte bei der neu eingestellten SenseBox
Der nächste Schritt kann dann eine Belieferung der SenseBox mittels MQTT Mücke Server aus unsere InfluxDB sein. Dazu dann aber bei Gelegenheit mehr.
Die kleine Dokumentation ist dann doch etwas umfangreicher geworden, ich hoffe aber das es sich für euch gelohnt hat und ich etwas beitragen konnte.
Hallo,
ich bin noch relativ neu und unerfahren im IOT Geschäft, habe aber mit dem Hauskauf damit begonnen ein altes Haus IOT Flott zu machen. Mit Shelly, Sonoffbasic, WemosD1Mini Zigbee und 433Mhz Zeug. Ich habe meine Wettersensoren, frage Ölpreis, pegelstände der Paddelflüsse aus dem Netz ab und schaue, wie es im Ferienhaus der Familie mit dem Wetter so aussieht. Ebenso überwache ich Heizungen … Mit großer Freude habe ich von Opensense erfahren und dachte ich klemme die Klamotte mal flott in Node-Red an, aber irgendwie verstehe ich meinen Syntaxfehler nicht. Er mag das Template Beispiel nicht, welches ich hier übernommen habe.
Hier mal ein debug-Auszug am Beispiel Pressure sowie meinem Flow Würde mich sehr über Tipps freuen und hätte auch gerne Zugang zu https://node-red.iot-usergroup.de/:
bmp180 : msg.payload : number
1000.1
11.3.2019, 05:56:26node: 92fec934.985f58
msg : string[41]
“Unexpected token } in JSON at position 12”
[{“id”:”fbb6762.7001688″,”type”:”change”,”z”:”8cb95ed9.c2b95″,”name”:””,”rules”:[{“t”:”set”,”p”:”Header”,”pt”:”msg”,”to”:”{ \”Content-Type\” : \”application/json\”, \”Host\”: \”www.opensensemap.org\”}”,”tot”:”str”},{“t”:”set”,”p”:”url”,”pt”:”msg”,”to”:”http://www.opensensemap.org:8000/boxes/5c84ae51922ca900196d0a44/5c84ae51922ca900196d0a47″,”tot”:”str”},{“t”:”set”,”p”:”method”,”pt”:”msg”,”to”:”POST”,”tot”:”str”}],”action”:””,”property”:””,”from”:””,”to”:””,”reg”:false,”x”:1735.5,”y”:795,”wires”:[[“1e936d0c.169fc3”]]},{“id”:”1e936d0c.169fc3″,”type”:”http request”,”z”:”8cb95ed9.c2b95″,”name”:””,”method”:”use”,”ret”:”obj”,”url”:””,”tls”:””,”x”:1800.5,”y”:735,”wires”:[[“a88f4bc6.908018”]]},{“id”:”92fec934.985f58″,”type”:”template”,”z”:”8cb95ed9.c2b95″,”name”:””,”field”:”payload”,”fieldType”:”msg”,”format”:”handlebars”,”syntax”:”mustache”,”template”:”{ \”value\”: {{payload.pressure}} }”,”output”:”json”,”x”:1844.5,”y”:886,”wires”:[[“fbb6762.7001688″,”aaa7920f.f7db7”]]},{“id”:”a88f4bc6.908018″,”type”:”debug”,”z”:”8cb95ed9.c2b95″,”name”:””,”active”:true,”console”:”false”,”complete”:”false”,”x”:1763,”y”:640,”wires”:[]},{“id”:”aaa7920f.f7db7″,”type”:”debug”,”z”:”8cb95ed9.c2b95″,”name”:””,”active”:true,”console”:”false”,”complete”:”false”,”x”:1761,”y”:590,”wires”:[]}]
Viele Grüße
Tobias
Nachtrag, zu meinem Voreintrag.
Erledigt, das Problem lag vor der Tastatur 🙂