{"id":1747,"date":"2022-09-11T17:50:04","date_gmt":"2022-09-11T15:50:04","guid":{"rendered":"https:\/\/www.rustimation.eu\/?p=1747"},"modified":"2024-09-03T11:48:32","modified_gmt":"2024-09-03T09:48:32","slug":"geofencing-experimente-mit-der-locative-app-teil-2","status":"publish","type":"post","link":"https:\/\/www.rustimation.eu\/index.php\/geofencing-experimente-mit-der-locative-app-teil-2\/","title":{"rendered":"Geofencing Experimente mit der Locative App <br> Teil 2: Node-Red"},"content":{"rendered":"<p><span style=\"font-family: 'Source Sans Pro', Helvetica, sans-serif; font-size: 16px;\">Home-Automatisierungsl\u00f6sungen wie FHEM sind mir eigentlich zu m\u00e4chtig. Au\u00dferdem k\u00f6nnen die schon von Haus aus zu viel, man ist eher Administrator als Entwickler. Au\u00dferdem macht mir das Frickeln und Lernen uneimlich viel Spa\u00df.<\/span><\/p>\n<p>F\u00fcr meine bescheidenen <a href=\"https:\/\/www.rustimation.eu\/index.php\/keller-entfeuchten-mit-node-red\/\" target=\"_blank\" rel=\"noopener\">Anwendungsf\u00e4lle<\/a> reicht ein grafisches Universaltool wie Node -Red, das ideal f\u00fcr einen Microserver wie den Raspberry Pi geeignet ist. Es l\u00e4uft sogar problemlos auf einem Raspberry Pi Zero der ersten Generation.<\/p>\n<p><!--more--><\/p>\n<h2>Was brauchen wir?<\/h2>\n<ul>\n<li>Einen Raspberry Pi mit installiertem Webserver, PHP und einer aus dem Internet erreichbaren URL<\/li>\n<li>darauf installiertem Node-Red<\/li>\n<li>F\u00fcr die echte Anwendung: eventuell Schaltaktoren z.B. von Shelly sowie einen MQTT Server z.B. Mosquitto<\/li>\n<\/ul>\n<h2>Geradeaus mit html Node<\/h2>\n<p>Ich gehe davon aus, dass du Node-Red installiert hast und dich schon etwas mit den Grundz\u00fcgen auskennst.<\/p>\n<p>F\u00fcr's Erste arbeiten wir direkt mit Locative und Node-Red, ohne PHP Klimbim.<\/p>\n<h3>Nachrichten im Node-Red Teststub empfangen<\/h3>\n<p>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:<\/p>\n<h3><a href=\"https:\/\/www.rustimation.eu\/index.php\/geofencing-experimente-mit-der-locative-app-teil-2\/nr_primtive\/\" rel=\"attachment wp-att-1775\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1775 aligncenter\" src=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/NR_Primtive.png\" alt=\"\" width=\"883\" height=\"240\" srcset=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/NR_Primtive.png 883w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/NR_Primtive-300x82.png 300w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/NR_Primtive-768x209.png 768w\" sizes=\"auto, (max-width: 883px) 100vw, 883px\" \/><\/a><\/h3>\n<p>Anbei JSON zum importieren<\/p>\n<pre class=\"height-set:true lang:js decode:true\">[{\"id\":\"c7b69f70141df5bd\",\"type\":\"tab\",\"label\":\"PHP-POST Remote\",\"disabled\":false,\"info\":\"\",\"env\":[]},{\"id\":\"747f98cb845836e5\",\"type\":\"debug\",\"z\":\"c7b69f70141df5bd\",\"name\":\"debug 1\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"false\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":420,\"y\":240,\"wires\":[]},{\"id\":\"9c4d9ad0982bbaae\",\"type\":\"http in\",\"z\":\"c7b69f70141df5bd\",\"name\":\"\",\"url\":\"testman\",\"method\":\"post\",\"upload\":false,\"swaggerDoc\":\"\",\"x\":180,\"y\":240,\"wires\":[[\"747f98cb845836e5\",\"77a737f18c60340f\"]]},{\"id\":\"77a737f18c60340f\",\"type\":\"template\",\"z\":\"c7b69f70141df5bd\",\"name\":\"Response\",\"field\":\"payload\",\"fieldType\":\"msg\",\"format\":\"html\",\"syntax\":\"mustache\",\"template\":\"Daten sind angekommen\",\"output\":\"str\",\"x\":420,\"y\":180,\"wires\":[[\"0c817e6bb44a55a3\"]]},{\"id\":\"0c817e6bb44a55a3\",\"type\":\"http response\",\"z\":\"c7b69f70141df5bd\",\"name\":\"\",\"statusCode\":\"\",\"headers\":{},\"x\":650,\"y\":180,\"wires\":[]}]<\/pre>\n<p>Der http In Node wird konfiguriert, indem bei URL eine wahlfreie Zieladresse (hier <em>testman<\/em>) eingetragen wird. Diese URL ist dann erreichbar unter<br \/>\n<span class=\"lang:js decode:true crayon-inline\">http:\/\/NameDesServers:1880\/testman<\/span><\/p>\n<p><a href=\"https:\/\/www.rustimation.eu\/index.php\/geofencing-experimente-mit-der-locative-app-teil-2\/http-in_node\/\" rel=\"attachment wp-att-1776\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1776 aligncenter\" src=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/http-in_Node.png\" alt=\"\" width=\"629\" height=\"414\" srcset=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/http-in_Node.png 629w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/http-in_Node-300x197.png 300w\" sizes=\"auto, (max-width: 629px) 100vw, 629px\" \/><\/a>Node-Red bringt seinen eigenen Webserver mit, der unter der Portnummer 1880 erreichbar ist. Will man die Node-Red Applikation \u00fcber das Internet erreichbar machen, muss im Router die Portnummer 1880 nach drau\u00dfen durchgereicht, also freigeschaltet werden. Damit hat man dann ein Loch gro\u00df wie ein Scheunentor in seine Firewall gehauen. Doch dazu sp\u00e4ter mehr.<\/p>\n<p>Biegen wir unsere Webhookadresse in der Locative App auf die neue Zieladresse um, <a href=\"https:\/\/www.rustimation.eu\/index.php\/geofencing-experimente-mit-der-locative-app-teil-2\/img_1811\/\" rel=\"attachment wp-att-1805\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1805\" src=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/IMG_1811-e1662966742205-1024x245.png\" alt=\"\" width=\"604\" height=\"145\" srcset=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/IMG_1811-e1662966742205-1024x245.png 1024w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/IMG_1811-e1662966742205-300x72.png 300w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/IMG_1811-e1662966742205-768x184.png 768w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/IMG_1811-e1662966742205.png 1536w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a>werden die geschickten Daten brav entgegengenommen, im Debug Fenster rechts (K\u00e4fersymbol) angezeigt und mit \"Daten sind angekommen\" beantwortet.<\/p>\n<p><a href=\"https:\/\/www.rustimation.eu\/index.php\/geofencing-experimente-mit-der-locative-app-teil-2\/nr_debug\/\" rel=\"attachment wp-att-1778\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1778 size-full aligncenter\" src=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/NR_debug-e1662908548153.png\" alt=\"\" width=\"379\" height=\"424\" srcset=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/NR_debug-e1662908548153.png 379w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/NR_debug-e1662908548153-268x300.png 268w\" sizes=\"auto, (max-width: 379px) 100vw, 379px\" \/><\/a><\/p>\n<p>Sehr sch\u00f6n, keine 5 Minuten hat das Entwickeln gedauert&#8230;<\/p>\n<p>Auf den Trigger kann man direkt \u00fcber msg.payload.trigger zugreifen.<\/p>\n<h3>Lichtsteuerung<\/h3>\n<p>So, jetzt wollen wir noch etwas Richtiges mit Node-Red anfangen: Wenn ich nach Sonnenuntergang &#8211; bzw. vor Sonnenaufgang heimkomme, soll das Licht angehen:<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/www.rustimation.eu\/index.php\/geofencing-experimente-mit-der-locative-app-teil-2\/lightman\/\" rel=\"attachment wp-att-1807\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1807\" src=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/lightman-1024x273.png\" alt=\"\" width=\"604\" height=\"161\" srcset=\"https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/lightman-1024x273.png 1024w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/lightman-300x80.png 300w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/lightman-768x204.png 768w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/lightman-1536x409.png 1536w, https:\/\/www.rustimation.eu\/wordpress\/wp-content\/uploads\/2022\/09\/lightman.png 1563w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><\/p>\n<p>Ein paar Erkl\u00e4rungen: Den <em>Astrodata day values <\/em>Node werdet ihr wahrscheinlich nachinstallieren m\u00fcssen. Leider gibt der Node keine Unix Timestamps aus, sondern echte Uhrzeiten, weshalb sie hinterher im Day or Night Function Node noch umgerechnet werden m\u00fcssen. So wird sichergestellt,\u00a0 dass zwischen Sonnenauf und &#8211;untergang das Licht nicht eingeschaltet wird.<\/p>\n<p>Wie schon beschrieben, arbeite ich gerne mit Shelly Aktoren, die \u00fcber MQTT angesteuert werden. So passiert alles \u00fcber WiFi, irgendwelche Philips Hue oder sonstige Hubs brauche ich nicht.<\/p>\n<p>Und hier das JSON:<\/p>\n<pre class=\"height:200 lang:js decode:true\">[{\"id\":\"7a50cffc5bf09d25\",\"type\":\"tab\",\"label\":\"Flow 1\",\"disabled\":false,\"info\":\"\",\"env\":[]},{\"id\":\"a077b0897e8725c2\",\"type\":\"function\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"Day or Night\",\"func\":\"var rTime = msg.sunRise;\\nrTime = rTime.split(\\\":\\\");\\nvar hours = parseInt(rTime[0]);\\nvar mins = parseInt(rTime[1]);\\nvar secs = parseInt(rTime[2]);\\nrTime =  hours * 3600 + mins * 60 + secs;\\n\\nvar sTime = msg.sunSet;\\nsTime = sTime.split(\\\":\\\");\\nhours = parseInt(sTime[0]);\\nmins = parseInt(sTime[1]);\\nsecs = parseInt(sTime[2]);\\nsTime = hours * 3600 + mins * 60 + secs;\\n\\nvar aTime = new Date();\\nhours = aTime.getHours();\\nmins = aTime.getMinutes();\\nsecs = aTime.getSeconds();\\naTime = hours * 3600 + mins * 60 + secs;\\n\\nif (rTime &lt;= aTime &amp;&amp; aTime &lt;= sTime) \\n    {msg.payload = \\\"day\\\";}\\nelse\\n    {msg.payload = \\\"night\\\";}\\n\\nreturn msg;\\n\",\"outputs\":1,\"noerr\":0,\"initialize\":\"\",\"finalize\":\"\",\"libs\":[],\"x\":770,\"y\":500,\"wires\":[[\"53757a5dd04a31e5\"]]},{\"id\":\"f165134d4df1475a\",\"type\":\"debug\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"enter\",\"active\":true,\"tosidebar\":true,\"console\":false,\"tostatus\":false,\"complete\":\"payload\",\"targetType\":\"msg\",\"statusVal\":\"\",\"statusType\":\"auto\",\"x\":600,\"y\":540,\"wires\":[]},{\"id\":\"370b5f0349a479ce\",\"type\":\"http in\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"\",\"url\":\"lightman\",\"method\":\"post\",\"upload\":false,\"swaggerDoc\":\"\",\"x\":260,\"y\":540,\"wires\":[[\"2b1ba4c3062bff09\"]]},{\"id\":\"2c43054e86ea35e0\",\"type\":\"http response\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"response\",\"statusCode\":\"\",\"headers\":{},\"x\":1320,\"y\":500,\"wires\":[]},{\"id\":\"c70704402596a1be\",\"type\":\"template\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"Nighttime Message \",\"field\":\"payload\",\"fieldType\":\"msg\",\"format\":\"html\",\"syntax\":\"mustache\",\"template\":\"Entering area - nighttime. Command executed.\",\"output\":\"str\",\"x\":1110,\"y\":540,\"wires\":[[\"2c43054e86ea35e0\"]]},{\"id\":\"53757a5dd04a31e5\",\"type\":\"switch\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"\",\"property\":\"payload\",\"propertyType\":\"msg\",\"rules\":[{\"t\":\"eq\",\"v\":\"day\",\"vt\":\"str\"},{\"t\":\"eq\",\"v\":\"night\",\"vt\":\"str\"}],\"checkall\":\"true\",\"repair\":false,\"outputs\":2,\"x\":920,\"y\":500,\"wires\":[[\"dbfb6da8ffbdfa6e\"],[\"c70704402596a1be\",\"4557f7131cdab0f2\"]]},{\"id\":\"dbfb6da8ffbdfa6e\",\"type\":\"template\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"Daytime Message\",\"field\":\"payload\",\"fieldType\":\"msg\",\"format\":\"html\",\"syntax\":\"mustache\",\"template\":\"Entering area. Daytime, no need for lights...\",\"output\":\"str\",\"x\":1110,\"y\":480,\"wires\":[[\"2c43054e86ea35e0\"]]},{\"id\":\"4557f7131cdab0f2\",\"type\":\"change\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"Send ON command\",\"rules\":[{\"t\":\"set\",\"p\":\"payload\",\"pt\":\"msg\",\"to\":\"on\",\"tot\":\"str\"}],\"action\":\"\",\"property\":\"\",\"from\":\"\",\"to\":\"\",\"reg\":false,\"x\":980,\"y\":640,\"wires\":[[\"9748e9698d6fddfd\"]]},{\"id\":\"2e179d331123df50\",\"type\":\"astrodata dayvalues\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"sun up\/down\",\"lon\":\"11.542510\",\"lat\":\"48.148691\",\"height\":\"600\",\"lang\":\"de\",\"offset\":0,\"x\":610,\"y\":500,\"wires\":[[\"a077b0897e8725c2\"]]},{\"id\":\"2b1ba4c3062bff09\",\"type\":\"switch\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"enter\/exit\",\"property\":\"payload.trigger\",\"propertyType\":\"msg\",\"rules\":[{\"t\":\"eq\",\"v\":\"enter\",\"vt\":\"str\"},{\"t\":\"eq\",\"v\":\"exit\",\"vt\":\"str\"}],\"checkall\":\"true\",\"repair\":false,\"outputs\":2,\"x\":430,\"y\":540,\"wires\":[[\"2e179d331123df50\",\"f165134d4df1475a\"],[\"1aa9c0085172028f\"]]},{\"id\":\"aefe93299f2ea6d6\",\"type\":\"http response\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"response\",\"statusCode\":\"\",\"headers\":{},\"x\":750,\"y\":600,\"wires\":[]},{\"id\":\"1aa9c0085172028f\",\"type\":\"template\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"\",\"field\":\"payload\",\"fieldType\":\"msg\",\"format\":\"html\",\"syntax\":\"mustache\",\"template\":\"Leaving perimeter...   \",\"output\":\"str\",\"x\":590,\"y\":600,\"wires\":[[\"aefe93299f2ea6d6\"]]},{\"id\":\"9748e9698d6fddfd\",\"type\":\"mqtt out\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"Licht Haust\u00fcre\",\"topic\":\"shellies\/\/haustuere\/relay\/0\/command\",\"qos\":\"2\",\"retain\":\"\",\"respTopic\":\"\",\"contentType\":\"\",\"userProps\":\"\",\"correl\":\"\",\"expiry\":\"\",\"broker\":\"c3ec39dc.4614f\",\"x\":1200,\"y\":740,\"wires\":[]},{\"id\":\"2c0b6399243d0a5f\",\"type\":\"ui_switch\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"\",\"label\":\"Haust\u00fcre\",\"tooltip\":\"\",\"group\":\"eb55fbe3.b2bcd8\",\"order\":1,\"width\":0,\"height\":0,\"passthru\":false,\"decouple\":\"true\",\"topic\":\"\",\"style\":\"\",\"onvalue\":\"on\",\"onvalueType\":\"str\",\"onicon\":\"\",\"oncolor\":\"\",\"offvalue\":\"off\",\"offvalueType\":\"str\",\"officon\":\"\",\"offcolor\":\"\",\"x\":1000,\"y\":740,\"wires\":[[\"9748e9698d6fddfd\"]]},{\"id\":\"9d6a6d8fcf352951\",\"type\":\"mqtt in\",\"z\":\"7a50cffc5bf09d25\",\"name\":\"\",\"topic\":\"shellies\/haustuere\/relay\/0\",\"qos\":\"2\",\"datatype\":\"auto\",\"broker\":\"c3ec39dc.4614f\",\"nl\":false,\"rap\":false,\"inputs\":0,\"x\":770,\"y\":740,\"wires\":[[\"2c0b6399243d0a5f\"]]},{\"id\":\"c3ec39dc.4614f\",\"type\":\"mqtt-broker\",\"name\":\"CentralinaPi\",\"broker\":\"192.168.1.25\",\"port\":\"1883\",\"clientid\":\"\",\"autoConnect\":true,\"usetls\":false,\"compatmode\":false,\"protocolVersion\":\"4\",\"keepalive\":\"60\",\"cleansession\":true,\"birthTopic\":\"\",\"birthQos\":\"0\",\"birthPayload\":\"\",\"birthMsg\":{},\"closeTopic\":\"\",\"closeQos\":\"0\",\"closePayload\":\"\",\"closeMsg\":{},\"willTopic\":\"\",\"willQos\":\"0\",\"willPayload\":\"\",\"willMsg\":{},\"sessionExpiry\":\"\"},{\"id\":\"eb55fbe3.b2bcd8\",\"type\":\"ui_group\",\"name\":\"Au\u00dfenlicht\",\"tab\":\"5807093d.850828\",\"order\":1,\"disp\":true,\"width\":\"6\",\"collapse\":false,\"className\":\"\"},{\"id\":\"5807093d.850828\",\"type\":\"ui_tab\",\"name\":\"Lichtsteuerung\",\"icon\":\"dashboard\",\"order\":1,\"disabled\":false,\"hidden\":false}]<\/pre>\n<h2>Sicherheitsrisiko<\/h2>\n<p>Wie schon erw\u00e4hnt, w\u00fcrdet 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\u00f6nnte eure sch\u00f6nen Node-Red Logiken fernsteuern.<\/p>\n<p>Ich habe auch noch nicht herausgefunden, wie sich das Dashboard passwortsch\u00fctzen l\u00e4sst. Bei einem maschinellen Zugriff w\u00fcrde das eh nicht viel helfen.<\/p>\n<p>Allermindestens m\u00fcsst ihr den Editor mit Passwort sch\u00fctzen.<\/p>\n<p>Es gibt auch noch einen installierbaren Node mit Namen \"basic http auth\", der funktioniert ganz gut, sch\u00fctzt aber nur den Flow, in dem ihr ihn einbauen k\u00f6nnt. Andere Flows im Dashboard bleiben ungesch\u00fctzt.<\/p>\n<p>Trotzdem gibt es f\u00fcr dieses Problem eine L\u00f6sung &#8212; wie ich meine&#8230;<\/p>\n<h3>Maskieren mit Proxy<\/h3>\n<p>Mein Setup sieht wie folgt aus:<\/p>\n<ul>\n<li>Raspberry Pi als \"Universalserver\" z.B. f\u00fcr dieses Blog hier, f\u00fcr meine Nextcloud und diverse andere Funktionen, z.B. als Gateway f\u00fcr ein paar Reverse SSH Tunnel. Jetzt auch als Server f\u00fcr Node-Red.<\/li>\n<li>Nur die Ports 80 und 443 sind im Router freigeschaltet, damit der Webserver \u00f6ffentlich erreichbar ist.<\/li>\n<li>Port 1880 ist <strong>nicht<\/strong> freigeschaltet. Node-Red kann also nur intern, innerhalb des privaten Netzes aufgerufen werden.<\/li>\n<\/ul>\n<p>Die L\u00f6sung besteht nun darin, die bei Port 80 bzw. 443 ankommenden, f\u00fcr Node-Red bestimmten Befehle, <strong>intern<\/strong> auf Port 1880 umzuleiten. Nat\u00fcrlich nur dann, wenn sich der User bzw. Locative oder andere Tools mit http Basic Authorization authentifiziert haben.<\/p>\n<p>Ich habe nun das in Kapitel 1 vorgestellte PHP Skript mit Basic Authentification \u00fcbernommen, und um eine Forwarding Komponente (gelb markiert) erweitert. Es fungiert gewisserma\u00dfen als Proxy.<\/p>\n<pre class=\"lang:php mark:29-42 decode:true\" title=\"forwarder.php\">\/\/forwarder.php\r\n&lt;?php\r\n    \/\/debug setting\r\n    error_reporting (E_ALL | E_STRICT);\r\n    ini_set ('display_errors' , 1);\r\n    \/\/ Ende Debug\r\n\r\n    \/\/check if exists basic auth in request\r\n    if (isset($_SERVER[\"HTTP_AUTHORIZATION\"])) {\r\n        $auth = $_SERVER[\"HTTP_AUTHORIZATION\"];\r\n        $auth_array = explode(\" \", $auth);\r\n        $un_pw = explode(':', base64_decode($auth_array[1]));\r\n        $un = $un_pw[0];\r\n        $pw = $un_pw[1]; \r\n\r\n        \/\/ check Uname &amp; PW    \r\n        $fh = file_get_contents('.password\/pwds.env');\r\n        $pline = explode(':', $fh);\r\n        $encpw = preg_replace('\/\\s+\/', '', $pline[1]);\r\n        $verify = password_verify($pw, $encpw);\r\n        \r\n        \/\/ if password is correct, continue\r\n        if ($un == $pline[0] &amp;&amp; $verify) {\r\n            \/\/receiving part\r\n            $request = file_get_contents('php:\/\/input');\r\n            \/\/$req_dump = print_r( $request, true );\r\n            $fp = file_put_contents( 'request.log', $request );\r\n\r\n            \/\/forwarding part\r\n            $ch = curl_init();\r\n            curl_setopt($ch, CURLOPT_URL,\"http:\/\/localhost:1880\/lichtan\");\r\n            curl_setopt($ch, CURLOPT_POST, 1);\r\n            curl_setopt($ch, CURLOPT_POSTFIELDS, $request);\r\n\r\n            \/\/ receive server response and send back to locative app\r\n            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\r\n            $server_output = curl_exec ($ch);\r\n            print_r($server_output);\r\n            curl_close ($ch);}       \r\n        else {\r\n            echo \"UNAUTHORIZED!!!!!\";}\r\n    }\r\n    else {\r\n        echo \"Missing credentials\";}            \r\n?&gt;<\/pre>\n<p>Die von einem <strong>autorisierten<\/strong> Nutzer an eine \u00f6ffentliche Adresse (meinen Webserver)\u00a0 gesendeten Daten werden nun intern im privaten Netz, abgekoppelt vom gro\u00dfen und weiten Internet, mit cURL an den auf derselben Maschine (localhost) installierten, nicht-\u00f6ffentlichen Node-Red Webserver weitergeleitet. Der dort existierende <em>http in<\/em> Node lauscht auf der URL <em>serverip:1880\/lichtan <\/em>(bzw.<em> localhost:1880\/lichtan<\/em>) und arbeitet wie gew\u00fcnscht. Meiner Meinung nach ist das eine sichere L\u00f6sung, oder?<\/p>\n<p>Nat\u00fcrlich muss Locative auch entsprechend auf die \u00f6ffentliche Adresse umgestellt werden, um das php Skript &#8211; hier: forwarder.php &#8211; aufzurufen. In die URL Zeile wird also sinngem\u00e4\u00df <span class=\"lang:python decode:true crayon-inline\">https:\/\/meineDynIPAdresse\/webhook\/forwarder.php<\/span>\u00a0 eingetragen.<\/p>\n<h4>Weltweite Aktionen<\/h4>\n<p>Das ganze l\u00e4sst sich noch mit Minimalaufwand auf eine globale L\u00f6sung ausweiten:<\/p>\n<p>Einer meiner beliebtesten (und \u00e4ltesten) Artikel ist\u00a0 <a href=\"https:\/\/www.rustimation.eu\/index.php\/reverse-ssh-tunnel-schritt-fur-schritt\/\">Reverse SSH Tunnel \u2013 Schritt f\u00fcr Schritt<\/a>. 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 <strong>nicht<\/strong> freigeschaltet.<\/p>\n<p>Anstatt<br \/>\n<span class=\"lang:python decode:true crayon-inline\">curl_setopt($ch, CURLOPT_URL,\"http:\/\/localhost:1880\/lichtan\");<\/span><br \/>\nschreibt man im Skript forwarder.php<br \/>\n<span class=\"lang:python decode:true crayon-inline \">curl_setopt($ch, CURLOPT_URL,\"http:\/\/localhost:2300\/lichtan\");<\/span><\/p>\n<p>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!<\/p>\n<p>Bei Interesse gerne fragen. Ich erkl\u00e4re es dann. Ich habe seinerzeit mehrere Wochen gebraucht, mein Hirn um dieses Thema herumzuwinden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Home-Automatisierungsl\u00f6sungen wie FHEM sind mir eigentlich zu m\u00e4chtig. Au\u00dferdem k\u00f6nnen die schon von Haus aus zu viel, man ist eher Administrator als Entwickler. Au\u00dferdem macht mir das Frickeln und Lernen uneimlich viel Spa\u00df. F\u00fcr meine bescheidenen Anwendungsf\u00e4lle reicht ein grafisches Universaltool wie Node -Red, das ideal f\u00fcr einen Microserver wie den Raspberry Pi geeignet ist. &hellip; <a href=\"https:\/\/www.rustimation.eu\/index.php\/geofencing-experimente-mit-der-locative-app-teil-2\/\" class=\"more-link\"><span class=\"screen-reader-text\">Geofencing Experimente mit der Locative App <br \/> Teil 2: Node-Red<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[150,53,137,151,8,10],"tags":[126,55,158,36,41],"class_list":["post-1747","post","type-post","status-publish","format-standard","hentry","category-geofencing","category-iot","category-mqtt","category-node-red","category-php","category-raspberry-pi","tag-node-red","tag-programmieren","tag-proxy","tag-raspberry-pi","tag-router"],"_links":{"self":[{"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/posts\/1747","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/comments?post=1747"}],"version-history":[{"count":1,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/posts\/1747\/revisions"}],"predecessor-version":[{"id":2940,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/posts\/1747\/revisions\/2940"}],"wp:attachment":[{"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/media?parent=1747"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/categories?post=1747"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rustimation.eu\/index.php\/wp-json\/wp\/v2\/tags?post=1747"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}