Geofencing Experimente mit der Locative App
Teil 2: Node-Red

Home-Automatisierungslösungen wie FHEM sind mir eigentlich zu mächtig. Außerdem können die schon von Haus aus zu viel, man ist eher Administrator als Entwickler. Außerdem macht mir das Frickeln und Lernen uneimlich viel Spaß.

Für meine bescheidenen Anwendungsfälle reicht ein grafisches Universaltool wie Node -Red, das ideal für einen Microserver wie den Raspberry Pi geeignet ist. Es läuft sogar problemlos auf einem Raspberry Pi Zero der ersten Generation.

Was brauchen wir?

  • Einen Raspberry Pi mit installiertem Webserver , PHP und einer aus dem Internet erreichbaren URL
  • darauf installiertem Node-Red
  • Für die echte Anwendung: eventuell Schaltaktoren z.B. von Shelly sowie einen MQTT Server z.B. Mosquitto

Geradeaus mit html Node

Ich gehe davon aus, dass du Node-Red installiert hast und dich schon etwas mit den Grundzügen auskennst.

Für's Erste arbeiten wir direkt mit Locative und Node-Red, ohne PHP Klimbim.

Nachrichten im Node-Red Teststub empfangen

Dann basteln wir uns mal einen Primitiv-Flow bestehend aus einem http-in Node, einem Template- sowie einem http-out node zur Response und zum Ansehen der Daten einem Debug Node:

Anbei JSON zum importieren

Der http In Node wird konfiguriert, indem bei URL eine wahlfreie Zieladresse (hier testman) eingetragen wird. Diese URL ist dann erreichbar unter
http://NameDesServers:1880/testman

Node-Red bringt seinen eigenen Webserver mit, der unter der Portnummer 1880 erreichbar ist. Will man die Node-Red Applikation über das Internet erreichbar machen, muss im Router die Portnummer 1880 nach draußen durchgereicht, also freigeschaltet werden. Damit hat man dann ein Loch groß wie ein Scheunentor in seine Firewall gehauen. Doch dazu später mehr.

Biegen wir unsere Webhookadresse in der Locative App auf die neue Zieladresse um, werden die geschickten Daten brav entgegengenommen, im Debug Fenster rechts (Käfersymbol) angezeigt und mit "Daten sind angekommen" beantwortet.

Sehr schön, keine 5 Minuten hat das Entwickeln gedauert...

Auf den Trigger kann man direkt über msg.payload.trigger zugreifen.

Lichtsteuerung

So, jetzt wollen wir noch etwas Richtiges mit Node-Red anfangen: Wenn ich nach Sonnenuntergang - bzw. vor Sonnenaufgang heimkomme, soll das Licht angehen:

 

Ein paar Erklärungen: Den Astrodata day values Node werdet ihr wahrscheinlich nachinstallieren müssen. Leider gibt der Node keine Unix Timestamps aus, sondern echte Uhrzeiten, weshalb sie hinterher im Day or Night Function Node noch umgerechnet werden müssen. So wird sichergestellt,  dass zwischen Sonnenauf und --untergang das Licht nicht eingeschaltet wird.

Wie schon beschrieben, arbeite ich gerne mit Shelly Aktoren, die über MQTT angesteuert werden. So passiert alles über WiFi, irgendwelche Philips Hue oder sonstige Hubs brauche ich nicht.

Und hier das JSON:

Sicherheitsrisiko

Wie schon erwähnt, würdet ihr mit der Port-Freischaltung der Node-Red Portadresse 1880 im Router ein riesiges Sicherheitsproblem bekommen. Praktisch jeder, der die URL und die Portnummer kennt, könnte eure schönen Node-Red Logiken fernsteuern.

Ich habe auch noch nicht herausgefunden, wie sich das Dashboard passwortschützen lässt. Bei einem maschinellen Zugriff würde das eh nicht viel helfen.

Allermindestens müsst ihr den Editor mit Passwort schützen.

Es gibt auch noch einen installierbaren Node mit Namen "basic http auth", der funktioniert ganz gut, schützt aber nur den Flow, in dem ihr ihn einbauen könnt. Andere Flows im Dashboard bleiben ungeschützt.

Trotzdem gibt es für dieses Problem eine Lösung -- wie ich meine...

Maskieren mit Proxy

Mein Setup sieht wie folgt aus:

  • Raspberry Pi als "Universalserver" z.B. für dieses Blog hier, für meine Owncloud und diverse andere Funktionen, z.B. als Gateway für ein paar Reverse SSL Tunnel. Jetzt auch als Server für Node-Red.
  • Nur die Ports 80 und 443 sind im Router freigeschaltet, damit der Webserver öffentlich erreichbar ist.
  • Port 1880 ist nicht freigeschaltet. Node-Red kann also nur intern, innerhalb des privaten Netzes aufgerufen werden.

Die Lösung besteht nun darin, die bei Port 80 bzw. 443 ankommenden, für Node-Red bestimmten Befehle, intern auf Port 1880 umzuleiten. Natürlich nur dann, wenn sich der User bzw. Locative oder andere Tools mit http Basic Authorization authentifiziert haben.

Ich habe nun das in Kapitel 1 vorgestellte PHP Skript mit Basic Authentification übernommen, und um eine Forwarding Komponente (gelb markiert) erweitert. Es fungiert gewissermaßen als Proxy.

Die von einem autorisierten Nutzer an eine öffentliche Adresse (meinen Webserver)  gesendeten Daten werden nun intern im privaten Netz, abgekoppelt vom großen und weiten Internet, mit cURL an den auf derselben Maschine (localhost) installierten, nicht-öffentlichen Node-Red Webserver weitergeleitet. Der dort existierende http in Node lauscht auf der URL serverip:1880/lichtan (bzw. localhost:1880/lichtan) und arbeitet wie gewünscht. Meiner Meinung nach ist das eine sichere Lösung, oder?

Natürlich muss Locative auch entsprechend auf die öffentliche Adresse umgestellt werden, um das php Skript - hier: forwarder.php - aufzurufen. In die URL Zeile wird also sinngemäß https://meineDynIPAdresse/webhook/forwarder.php  eingetragen.

Weltweite Aktionen

Das ganze lässt sich noch mit Minimalaufwand auf eine globale Lösung ausweiten:

Einer meiner beliebtesten (und ältesten Artikel) ist  Reverse SSH Tunnel – Schritt für Schritt. Hat man so ein Reverse Tunnel realisiert um z.B. auf einen Raspberry Pi oder eine Webcam im Ferienhaus zuzugreifen, muss der Remote Rechner im Ferienhaus nur die Portadresse 1880 per Reverse SSH Tunnel auf eine freie Portadresse im Gateway Server z.B. 2300 umleiten. 2300 ist im Router nicht freigeschaltet.

Anstatt
curl_setopt($ch, CURLOPT_URL,"http://localhost:1880/lichtan");
schreibt man im Skript forwarder.php
curl_setopt($ch, CURLOPT_URL,"http://localhost:2300/lichtan");

Will sagen: An Stelle der Adresse des internen Node-Red Webservers, gibt man die interne Weiterleitungsportnummer des Gateways an. Die Bytes kommen am Remote Server an und landen schlussendlich am dortigen Node-Red Port 1880. Fertig!

Bei Interesse gerne fragen. Ich erkläre es dann. Ich habe seinerzeit mehrere Wochen gebraucht, mein Hirn um dieses Thema herumzuwinden.

Schreibe einen Kommentar

Ich freue mich über Lob und Kritik.
Falls du Probleme mit der hier vorgestellten Anleitung hast und nicht weiter kommst:
Bitte das Problem oder die Fehlermeldung(en) möglichst genau beschreiben, auch an welcher Stelle (z.B. in welchem Node oder Befehl) und unter welchen Umständen der Fehler auftritt.
Gerne kannst du mir auch ein Mail schreiben. Die Adresse findest du im Impressum.
Ich gebe mir viel Mühe, meinen Lesern weiterzuhelfen. Je konkreter du bist, desto einfacher und schneller kann ich versuchen zu helfen.
Deine E-Mail-Adresse wird nicht veröffentlicht.
Erforderliche Felder sind mit * markiert