Ankündigung

Einklappen
Keine Ankündigung bisher.

Erweiterte HTTP-Remote-Schnittstelle (mit Unterstützung für POST Requests)

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Erweiterte HTTP-Remote-Schnittstelle (mit Unterstützung für POST Requests)

    Hallo zusammen,

    ich habe die HTTP-Remote-Schnittstelle um die Möglichkeit erweitert, auch POST-Requests verarbeiten zu können.
    Der gesamte Inhalt des HTTP Body wird dann in das angegebene interne KO geschrieben.

    Ich nutze diese Funktionalität im Zusammenhang mit Webhooks, also quasi Callbacks auf HTTP-Basis.
    Diese Callbacks nutzen in der Regel HTTP POST Requests mit JSON-Daten im Body.
    Diese JSON-Daten kann man nun direkt einem internen KO zuweisen.

    Als Beispiel sei hier die Node.js HTTP-API für SONOS genannt, die über Webhooks diverse Ereignisse meldet, wie zum Beispiel Topologie-Änderungen, Zustandsänderung eines Players, etc. Diese Infos stehen mit Hilfe des unten angehängten Patches direkt in Edomi zur Verfügung und kann sie mit entsprechenden LBS weiterverarbeiten.

    Es wird die Datei index.php in /usr/local/edomi/www/remote geändert.

    Code:
    --- index.php.orig      2017-03-21 01:12:48.000000000 +0100
    +++ index.php   2017-05-21 15:58:33.445629414 +0200
    @@ -46,6 +46,8 @@
     header("Content-Type: text/plain");
     if (checkRemoteLoginPass(httpGetVar('login'),httpGetVar('pass'))) {
    
    +        switch($_SERVER['REQUEST_METHOD']) {
    +           case 'GET':
            if (isset($_GET['kovalue'])) {
                    $gaValue=httpGetVar('kovalue');
    
    @@ -67,6 +69,22 @@
                    }
    
            }
    +           break;
    +
    +           case 'POST':
    +               $postdata = file_get_contents("php://input");
    +               //Wert setzen, hier den kompletten Body des HTTP POST Requests
    +               if (httpKoSet($gaId,$postdata)) {
    +                       echo 'OK;'.$gaId.';'.$postdata.';';
    +               } else {
    +                       echo 'ERROR;'.$gaId.';FORBIDDEN;';              //KO ist nicht in db.httpKo gelistet
    +               }
    +
    +           break;
    +
    +           default:
    +        }
    +
    
     } else {
            echo 'ERROR;LOGIN;';                                                    //falsches Login/Pass
    Angehängte Dateien
    Zuletzt geändert von Nanosonde; 21.05.2017, 15:15.

    #2
    Wäre so etwas nicht in einem LBS besser aufgehoben?

    Ich hatte einen solchen Request schon mal in einen LBS gegossen. Allerdings mit der Prüfung auf einen vailden JSON-String, der nur eine Ebene enthät, damit man die Ausgabe auch mit anderen JSON-LBS weiterverarbeiten kann. Diese Prüfung könnte man auch weglassen und es der nachgeschalteten Logik überlassen.

    http://service.knx-user-forum.de/?co...ad&id=19000933

    Decoder:
    von Nanosonde http://service.knx-user-forum.de/?co...ad&id=19001074
    von hartwigm http://service.knx-user-forum.de/?co...ad&id=19000973
    Gruß
    Stefan

    Kommentar


      #3
      Zitat von MrIcemanLE Beitrag anzeigen
      Wäre so etwas nicht in einem LBS besser aufgehoben?

      Ich hatte einen solchen Request schon mal in einen LBS gegossen. Allerdings mit der Prüfung auf einen vailden JSON-String, der nur eine Ebene enthät, damit man die Ausgabe auch mit anderen JSON-LBS weiterverarbeiten kann. Diese Prüfung könnte man auch weglassen und es der nachgeschalteten Logik überlassen.

      http://service.knx-user-forum.de/?co...ad&id=19000933
      Hi!
      Deinen Bautein nutze ich auch.

      Aber: ich benötigte die andere Richtung. Es wird also ein LBS benötigt, der quasi auf einen HTTP POST Request reagieren kann, um auf Events reagieren zu können, die ein anderer Webdienst sendet.
      Daher hatte ich ja auch Callbacks erwähnt.

      Ich habe aber gleich den Webhook LBS hoffentlich fertig. Dann ist der Patch nicht notwendig. Dachte mir schon, dass der nicht auf Gegenliebe stößt.

      Kommentar


        #4
        Wahrscheinlich ist deine Anwendung "hausintern", sodass der Request aus dem LAN kommt. Ich habe den Webhook über einen externen Webserver gelöst und lasse EDOMI zyklisch checken. So muss ich EDOMI nicht von außen zugänglich machen. Das hat aber entsprechende Verzögerungen zur Folge, die je nach Anwendung akzeptabel sind.

        Für deinen Webhook würde ich ja dann einen DynDNS-Dienst benötigen um aus einer App o. ä. den Request an EDOMI zu schicken, oder?

        Der Telegram Receiver von jonofe macht auch nur eine zyklische Abfrage, oder?
        Gruß
        Stefan

        Kommentar


          #5
          Ja, die Anwendung läuft bei mir nur im internen LAN. Es ist - wie im ersten Posting bereits erwähnt - die Node.js HTTP API für Sonos und die nutzt halt HTTP Callbacks.
          Polling, also zyklisches Abfragen empfinde ich in der Regel als die schlechteste Variante, wenn eine API auch eine Event-getriggerte Verarbeitung ermöglicht.

          Der Webhook LBS ist gerade fertig geworden. Es ist aber nur für interne Geschichten gedacht. Es wird per HTTP ein kleines PHP-Skript im WWW-Verzeichnis von Edomi aufgerufen, dass dann dem LBS per Message Queue den POST Body hinterlässt. Dieser Inhalt steht dann am LBS Ausgang zur Verfügung.
          Dieses Skript könnte man natürlich auch über einen Reverse Proxy entsprechend absichern und dann ggf. doch von außen erreichbar machen.

          Eine weitere interessante Möglichkeit, um Daten mit externen Diensten auszutauschen , ist diese hier: https://aws.amazon.com/de/sqs/
          Bin darüber hier gestolpert: https://github.com/rgraciano/echo-so...echo-sqs-proxy

          Kommentar


            #6
            Zitat von Nanosonde Beitrag anzeigen

            Eine weitere interessante Möglichkeit, um Daten mit externen Diensten auszutauschen , ist diese hier: https://aws.amazon.com/de/sqs/
            Bin darüber hier gestolpert: https://github.com/rgraciano/echo-so...echo-sqs-proxy
            Dem stimme ich zu. Auch der IoT Service könnte interessant sein, wenn man per MQTT aus dem Internet mit EDOMI kommunizieren möchte.

            Habe übrigens gerade einen LBS fertiggestellt, welcher Amazon Polly einbindet (Veröffentlichung heute oder morgen). Dieser kommt dann mit aws-sdk-php und PHP 5.6. Damit wird die Einbindung anderer AWS Services leichter möglich. Es ist dafür nur ein Github Repository einzubinden.

            Kommentar


              #7
              Hallo Nanosonde
              Ich versuche grad den Webhook Baustein von Dir einzubauen. Leider steh ich grad etwas aufn Schlauch und komm nicht so recht weiter.
              Verwenden wollte ich ihn für Callbacks vom Nuki Türschloss.

              So wie ich das verstehe ist der Baustein ja genau dafür gemacht.

              snipping api.PNG

              Bisheriges Vorgehen:
              • Deinen LBS installiert, und webhook.php nach /user/local/edomi/www kopiert
              • beim Nuki die Callback URL definiert
              • Alles aktiviert und neugestartet

              snipping lbs.PNG

              Leider bekomme ich rein gar nichts auf die Ausgänge, und weiß nicht wo ich da ansetzen soll um auf Fehlersuche zu gehen.
              Ich vermute das der Nuki Callback Link so nicht passt.

              Im Log erhalte ich sowas
              Code:
               [TABLE="border: 0, cellpadding: 0, cellspacing: 0"]
              [TR]
              [TD]2017-06-17 12:20:13[/TD]
               			[TD]449995[/TD]
               			[TD]1461[/TD]
               			[TD]debug[/TD]
               			[TD]LBS19001076 [v0.2] id=1100: LBS started[/TD]
               		[/TR]
              [TR]
              [TD]2017-06-17 12:20:13[/TD]
               			[TD]452447[/TD]
               			[TD]1461[/TD]
               			[TD]debug[/TD]
               			[TD]LBS19001076 [v0.2] id=1100: LBS ended[/TD]
               		[/TR]
              [TR]
              [TD]2017-06-17 12:22:26[/TD]
               			[TD]325889[/TD]
               			[TD]21036[/TD]
               			[TD]debug[/TD]
               			[TD]EXE19001076 [v0.2] id=1100:[/TD]
               		[/TR]
              [TR]
              [TD]2017-06-17 12:22:26[/TD]
               			[TD]326229[/TD]
               			[TD]21036[/TD]
               			[TD]debug[/TD]
               			[TD]EXE19001076 [v0.2] id=1100: File: /usr/local/edomi/www/data/liveproject/lbs/EXE19001076.php | Error: 2 | Line: 87 | array_key_exists() expects parameter 2 to be array, null given[/TD]
               		[/TR]
              [TR]
              [TD]2017-06-17 12:22:26[/TD]
               			[TD]326441[/TD]
               			[TD]21036[/TD]
               			[TD]debug[/TD]
               			[TD]EXE19001076 [v0.2] id=1100: File: /usr/local/edomi/www/data/liveproject/lbs/EXE19001076.php | Error: 2 | Line: 89 | array_key_exists() expects parameter 2 to be array, null given[/TD]
               		[/TR]
              [TR]
              [TD]2017-06-17 12:22:29[/TD]
               			[TD]328399[/TD]
               			[TD]21036[/TD]
               			[TD]debug[/TD]
               			[TD]EXE19001076 [v0.2] id=1100:[/TD]
               		[/TR]
              [TR]
              [TD]2017-06-17 12:22:29[/TD]
               			[TD]328630[/TD]
               			[TD]21036[/TD]
               			[TD]debug[/TD]
               			[TD]EXE19001076 [v0.2] id=1100: File: /usr/local/edomi/www/data/liveproject/lbs/EXE19001076.php | Error: 2 | Line: 87 | array_key_exists() expects parameter 2 to be array, null given[/TD]
               		[/TR]
              [TR]
              [TD]2017-06-17 12:22:29[/TD]
               			[TD]328816[/TD]
               			[TD]21036[/TD]
               			[TD]debug[/TD]
               			[TD]EXE19001076 [v0.2] id=1100: File: /usr/local/edomi/www/data/liveproject/lbs/EXE19001076.php | Error: 2 | Line: 89 | array_key_exists() expects parameter 2 to be array, null given[/TD]
               		[/TR]
              [TR]
              [TD]2017-06-17 12:27:41[/TD]
               			[TD]753515[/TD]
               			[TD]21036[/TD]
               			[TD]debug[/TD]
               			[TD]EXE19001076 [v0.2] id=1100:[/TD]
               		[/TR]
              [/TABLE]
              Ich glaub die Fehlermeldungen sind entstanden als ich versucht hab http://edomi/webhook.php im Browser aufzurufen

              Zusammenfassung:
              Ist der Baustein dafür überhaupt geeignet?
              Wie sollte die Richtige URL aussehn?
              bzw. wie könnte man sehen ob Nuki überhaupt was Sendet?
              muss vll. noch was in der webhook.php konfiguriert werden?
              oder kann bzw sollte man das anders lösen?

              Vielen Dank schon Mal
              Tom

              Kommentar


                #8
                Zitat von tomki Beitrag anzeigen
                Ist der Baustein dafür überhaupt geeignet?
                Ja, genau für diesen Fall ist er eigentlich gemacht.

                Zitat von tomki Beitrag anzeigen
                Wie sollte die Richtige URL aussehn?
                Eine ID brauchst Du eigentlich nicht mitzusenden.
                Der Query-String in der URL wird einfach an A1 durchgereicht.
                Ansonsten sieht das schon so richtig aus.

                Zitat von tomki Beitrag anzeigen
                bzw. wie könnte man sehen ob Nuki überhaupt was Sendet?
                Ich würde zunächst mal ohne Nuki testen, ob Du überhaupt durch einen HTTP Post Request etwas an A1/A2 generieren kannst.
                Ich nutze unter Firefox dafür das Addon "HttpRequester": https://addons.mozilla.org/de/firefo...httprequester/
                Also mit dem Addon einfach einen HTTP Post request generieren für http://192.168.0.115:8000/webhook.php
                Als "Content" könntest Du dann den Text reinpacken, der an A2 des LBS erscheinen soll.
                Hier würde Nuki die Antwort im JSON-Format ablegen. Ob JSON oder nicht ist erstmal irrelevant.
                Einfach ein paar Buchstaben eintippen.

                Wenn das klappt, dann sollte man bei Nuki weiterforschen.
                Die Kommunikation würde ich mit Wireshark anschauen.

                Zitat von tomki Beitrag anzeigen
                muss vll. noch was in der webhook.php konfiguriert werden?
                Eigentlich musst Du nur darauf achten, dass der Port frei ist, mit dem webhook.php und der LBS über eine TCP-Verbindung kommunizieren.
                Zuletzt geändert von Nanosonde; 17.06.2017, 13:36.

                Kommentar


                  #9
                  Danke für die Hilfe
                  Ich weiß zwar jetzt nicht genau, was ich gemacht hab, aber jetzt funktioniert es.

                  Danke auch für den Tipp mit dem Http Requester.
                  Nachdem ich damit etwas auf A2 bekommen hab, (nach unzähligen Neustarts) konnte es dann nicht mehr viel sein.

                  Als nächstes dann mit der Callback Url gespielt,
                  und die mußte ohne Port angegeben werden? Sprich schaut jetzt so aus (http://192.168.0.115/webhook.php)

                  Eine ID brauchst Du eigentlich nicht mitzusenden.
                  das mit der ID hatte ich aus der webhook.php beilage
                  Code:
                  // Expected URL format: http://<server_ip>/webhook.php?id=<LBS_ID>
                  in der webhook.php hab ich ebenfalls probiert, und
                  Code:
                  //
                  $targets = array(
                      array(
                          'lbsid' => '1100',
                          'ip' => '192.168.0.115',
                          'protocol' => 'tcp',
                          'port' => 8000,
                          'status' => true
                      )
                  );
                  das angepasst.

                  Was schlußendlich zum Erfolg geführt hat kann ich nicht sagen, aber jetzt scheint zu funktionieren.
                  Wahrscheinlich eine Mischung aus allem

                  Danke

                  Kommentar


                    #10
                    tomki oder ?

                    Kannst Du bitte den Baustein Webhook (LBS 19001076) hier reinstellen ?
                    In der Downloadliste ist er leider nicht mehr.
                    Danke !

                    Zuletzt geändert von WagoKlemme; 20.09.2019, 18:21.
                    >>Smelly One<<
                    >> BURLI <<
                    Grüße Armin

                    Kommentar


                      #11
                      Hallo WagoKlemme


                      Code:
                      ###[DEF]###
                      [name        = Webhook v0.2]
                      
                      [e#1        = Start/Stop #init=1]
                      [e#2        = Loglevel #init=8]
                      [e#3        = Protocol #init=tcp ]
                      [e#4        = Port ]
                          
                      [a#1        = Query string]
                      [a#2        = POST data]
                      
                      [v#1        = 0    ]                 # start daemon only once
                      [v#2    = 0 ]                              # Message Queue ID
                      [v#100    = 0.2 ]                        # Version
                      [v#101    = 19001076 ]              # LBS No.
                      [v#102    = Webhook ]                # LBS Name
                      [v#103    = 0 ]                          # Log Level
                      
                      ###[/DEF]###
                      
                      ###[HELP]###
                      Webhook
                      ========================
                      This LBS is used to provide a HTTP POST webhook to receive HTTP Requests from other webservices.
                      This LBS is meant to be used for internal LAN webservices only as it does not provide any security like authentication, etc.
                      The LBS uses a socket connection to receive the POST data from the called PHP script (webhook.php).
                      To call the webhook LBS use the URL: http://<edomi-ip>/webhook.php
                      
                      The webhook PHP script is included in the ZIP archive. 
                      It should be placed here: /usr/local/edomi/www
                      Other locations are possible, but the above URL has to be adjusted accordingly.
                      
                      E1: Enable Logging (0-none|1-emerg|2-alert|3-crit|4-err|5-warning|6-notice|7-info|8-debug)
                      E3: Protocol - udp|tcp
                      E4: Port to listen on. Has to be configured accordingly in webhook.php
                      
                      A1: Request query string received
                      A2: POST data received
                      
                      V1: Indicator whether daemon is running
                      V2: PID to kill EXEC from LBS
                      
                      V100: Version
                      V101: LBS Number
                      V102: Log file name
                      V103: Log level
                      
                      Changelog:
                      ==========
                      v0.1: Initial version
                      v0.2: Changed from message queue to socket communication
                      
                      ###[/HELP]###
                          
                      
                      ###[LBS]###
                      <?
                      
                      function LB_LBSID_logging($id, $msg, $var = NULL, $priority = 8)
                      {
                          $E = logic_getInputs($id);
                          $logLevel = logic_getVar($id, 103);
                          if (is_int($priority) && $priority <= $logLevel && $priority > 0) {
                              $logLevelNames = array(
                                  'none',
                                  'emerg',
                                  'alert',
                                  'crit',
                                  'err',
                                  'warning',
                                  'notice',
                                  'info',
                                  'debug'
                              );
                              $version = logic_getVar($id, 100);
                              $lbsNo = logic_getVar($id, 101);
                              $logName = logic_getVar($id, 102) . '  ---  LBS' . $lbsNo;
                              strpos($_SERVER['SCRIPT_NAME'], $lbsNo) ? $scriptname = 'EXE' . $lbsNo : $scriptname = 'LBS' . $lbsNo;
                              writeToCustomLog($logName, str_pad($logLevelNames[$logLevel], 7), $scriptname . " [v$version] id=".$id.":\t" . $msg);
                              if (is_object($var))
                                  $var = get_object_vars($var); // transfer object into array
                              if (is_array($var)) // print out array
                              {
                                  writeToCustomLog($logName, str_pad($logLevelNames[$logLevel], 7), $scriptname . " [v$version]:\t================ ARRAY/OBJECT START ================");
                                  foreach ($var as $index => $line)
                                      writeToCustomLog($logName, str_pad($logLevelNames[$logLevel], 7), $scriptname . " [v$version]:\t" . $index . " => " . $line);
                                  writeToCustomLog($logName, str_pad($logLevelNames[$logLevel], 7), $scriptname . " [v$version]:\t================ ARRAY/OBJECT  END  ================");
                              }
                          }
                      }
                      
                      function LB_LBSID($id) {
                          if ($E = logic_getInputs($id)) {
                              setLogicElementVar($id, 103, $E[2]['value']); // set loglevel to #VAR 103
                              LB_LBSID_logging($id, 'LBS started');
                              
                              if ($E[1]['value'] != 0 && $E[1]['refresh'] == 1) {
                                  
                                  if (logic_getVar($id, 1) != 1) { // dieses Konstrukt stellt sicher, dass das EXEC-Script nur einmal gestartet wird
                                      logic_setVar($id, 1, 1);
                                      logic_callExec(LBSID, $id);
                                  }
                              } elseif ($E[1]['value'] == 0 && $E[1]['refresh'] == 1) {
                                  $pid = getLogicElementVar($id,2);
                                  posix_kill($pid, SIGTERM);
                                  logic_setVar($id, 1, 0);
                              }
                              LB_LBSID_logging($id, 'LBS ended');
                          }
                      }
                      ?>
                      ###[/LBS]###
                      
                      
                      ###[EXEC]###
                      <?
                      require(dirname(__FILE__)."/../../../../main/include/php/incl_lbsexec.php");
                      set_time_limit(0);
                      sql_connect();
                      setLogicElementVar($id,2,getmypid());
                      //
                      // error_off() : switch off error reporting
                      // error_on() : switch on error reporting
                      //
                      function myErrorHandler($errno, $errstr, $errfile, $errline)
                      {
                          global $id;
                          logging($id, "File: $errfile | Error: $errno | Line: $errline | $errstr ");
                      }
                      
                      function error_off()
                      {
                          $error_handler = set_error_handler("myErrorHandler");
                          error_reporting(0);
                      }
                      
                      function error_on()
                      {
                          restore_error_handler();
                          error_reporting(E_ALL);
                      }
                      
                      function logging($id, $msg, $var = NULL, $priority = 8)
                      {
                          $E = logic_getInputs($id);
                          $logLevel = logic_getVar($id, 103);
                          if (is_int($priority) && $priority <= $logLevel && $priority > 0) {
                              $logLevelNames = array(
                                  'none',
                                  'emerg',
                                  'alert',
                                  'crit',
                                  'err',
                                  'warning',
                                  'notice',
                                  'info',
                                  'debug'
                              );
                              $version = logic_getVar($id, 100);
                              $lbsNo = logic_getVar($id, 101);
                              $logName = logic_getVar($id, 102) . '  ---  LBS' . $lbsNo;
                              strpos($_SERVER['SCRIPT_NAME'], $lbsNo) ? $scriptname = 'EXE' . $lbsNo : $scriptname = 'LBS' . $lbsNo;
                              writeToCustomLog($logName, str_pad($logLevelNames[$logLevel], 7), $scriptname . " [v$version] id=".$id.":\t" . $msg);
                              if (is_object($var))
                                  $var = get_object_vars($var); // transfer object into array
                              if (is_array($var)) // print out array
                      {
                                  writeToCustomLog($logName, str_pad($logLevelNames[$logLevel], 7), $scriptname . " [v$version]:\t================ ARRAY/OBJECT START ================");
                                  foreach ($var as $index => $line)
                                      writeToCustomLog($logName, str_pad($logLevelNames[$logLevel], 7), $scriptname . " [v$version]:\t" . $index . " => " . $line);
                                  writeToCustomLog($logName, str_pad($logLevelNames[$logLevel], 7), $scriptname . " [v$version]:\t================ ARRAY/OBJECT  END  ================");
                              }
                          }
                      }
                      
                      // -------------------------------
                      // Daemon was started
                      // -------------------------------
                      
                      error_off();
                      
                      
                      if ($E = logic_getInputs($id)) {
                          $port = $E[4]['value'];
                          $protocol = $E[3]['value'];
                          $socket = stream_socket_server("$protocol://0.0.0.0:$port", $errno, $errstr);
                          stream_set_timeout($socket, 3);
                          
                          if (! $socket) {
                              logging($id, "Error creating socket: $errstr ($errno)");
                          } 
                          else {
                              while (getSysInfo(1) >= 1) { // Hauptschleife (wird beim Beenden oder Neustart von EDOMI verlassen)
                                  
                                  while ($conn = stream_socket_accept($socket,-1)) {
                                      sql_connect();
                                      stream_set_timeout($conn, 3);
                                      $msg = fread($conn, 8192);
                                      $msg = json_decode($msg, true);
                                      
                                      logging($id, print_r($msg, true));
                                      if (array_key_exists('query', $msg)) 
                                          logic_setOutput($id, 1, json_encode($msg['query']));
                                      if (array_key_exists('post', $msg)) 
                                          logic_setOutput($id, 2, $msg['post']);
                                      
                                      $recMsg = 'success';
                                             // Send answer to webhook.php script
                                             $w = fwrite($conn, $recMsg);
                                          
                                      // close connection to webhook.php script
                                      fclose($conn);
                                  }
                                  
                                  usleep(1000 * 10); // CPU-Last verteilen (die Länge der Pause sollte je nach Bedarf angepasst werden - je länger, desto ressourcenschonender)
                              }
                              
                              fclose($socket);
                          }
                      }
                      
                      error_on();
                      
                      sql_disconnect();
                      
                      ?>
                      ###[/EXEC]###

                      Kommentar


                        #12
                        webhook.php

                        Code:
                        <?php
                        //
                        // webhook.php
                        //
                        // HTTP POST receiver
                        //
                        // To be used with Edomi LBS19001076
                        //
                        // Expected URL format: http://<server_ip>/webhook.php?id=<LBS_ID>
                        //
                        
                        //
                        // ============================= configuration ================================
                        //
                        $targets = array(
                            array(
                                'lbsid' => '1100',
                                'ip' => '192.168.0.115',
                                'protocol' => 'tcp',
                                'port' => 8000,
                                'status' => true
                            )
                        );
                        
                        // ============================================================================
                        
                        $okResponse = '
                            {
                                          "status": "success"
                                        }';
                        
                        $failureResponse = '
                            {
                                          "status": "failure"
                                        }';
                        
                        error_off();
                        
                        
                        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
                        
                            $postData = file_get_contents("php://input");
                        
                            $data = array(
                                                                                "query" => $_REQUEST,
                                                                                "post"  => $postData
                                                                         );
                            $jsonEncodedData = json_encode($data);
                        
                            foreach ($targets as $target) {
                                        // open stream in blocking mode with 3 seconds timeout
                                        $client = stream_socket_client($target['protocol'] . '://' . $target['ip'] . ':' . $target['port'], $errno, $errorMessage);
                                        stream_set_timeout($client, 4);
                                        stream_set_blocking($client, TRUE);
                        
                                        if ($client === false) {
                                            throw new UnexpectedValueException("Failed to connect: $errorMessage");
                                        }
                        
                                        // send data to EDOMI Webhook LBS
                        $result = fwrite($client, $jsonEncodedData);
                        logging("Data sent to EDOMI: $jsonEncodedData\n");
                        
                        if ($target['status']) {
                        
                        logging("Waiting for status response from " . $target['ip'] . "\n");
                        // wait for response from EDOMI
                        $edomiStatus = fread($client, 1024); // blocking, 3s timeout
                        logging("Status received from EDOMI: $edomiStatus\n");
                        if ($edomiStatus === 'success')
                        $edomiResponse = $okResponse;
                        else
                        $edomiResponse = $failureResponse;
                        } else {
                        logging("Ignoring status response from " . $target['ip'] . "\n");
                        $edomiResponse = $okResponse;
                        }
                        
                        fclose($client);
                        }
                        }
                        
                        sendResponse($edomiResponse);
                        error_on();
                        die();
                        
                        function sendResponse($response)
                        {
                        if ($response) {
                        logging(print_r($response, true));
                        $size = strlen($response);
                        header('Content-Type: application/json; charset=utf-8');
                        header("Content-length: $size");
                        echo $response;
                        }
                        }
                        
                        function fail($message)
                        {
                        file_put_contents('/usr/local/edomi/www/data/log/webhook.log', $message . "\n", FILE_APPEND);
                        error_log($message);
                        die();
                        }
                        
                        function logging($message)
                        {
                        file_put_contents('/usr/local/edomi/www/data/log/webhook.log', $message . "\n", FILE_APPEND);
                        }
                        
                        //
                        // error_off() : switch off error reporting
                        // error_on() : switch on error reporting
                        //
                        function error_off()
                        {
                        $error_handler = set_error_handler("myErrorHandler");
                        error_reporting(0);
                        }
                        function myErrorHandler($errno, $errstr, $errfile, $errline)
                        {
                        logging("File: $errfile | Error: $errno | Line: $errline | $errstr ");
                        }
                        
                        function error_on()
                        {
                        restore_error_handler();
                        error_reporting(E_ALL);
                        }
                        
                        ?>

                        Kommentar


                          #13
                          tomki
                          Danke, läuft !
                          >>Smelly One<<
                          >> BURLI <<
                          Grüße Armin

                          Kommentar


                            #14
                            Hallo,

                            ich habe mich gestern den ganzen Tag und auch heute noch bis jetzt mit dem Thema herumgeschlagen, ich glaube ich habe irgendwo einen Denkfehler oder dergleichen.
                            Mein Edomi läuft auf CentOS7 auf einem Mini-Rechner (alleine), und ich möchte einen Shelly PM2 ansprechen, der im Cover (Rollladen)-Modus ist.
                            Mit den http-Befehlen kann ich ihm problemlos sagen wohin gefahren werden soll.

                            Für mich stellt sich nun die Frage für die Rückmeldung.
                            Da ich gesehen habe, dass Shelly webhooks unterstützt habe ich den webhook-Baustein ins Edomi geladen, und auch die webhook.php ins richtige Verzeichnis geladen.
                            Wenn ich nun mit einem http-requester eine webhook-Post Nachricht schreibe, kommt diese im edomi an, es kommt auch eine Rückmeldung das alles gepasst hat.
                            Ich laufe allerdings in das Problem, dass wenn ich dieselbe Adresse beim Shelly als webhook eingebe

                            "http://192.168.8.53/webhook.php" (der httprequester will keinen port und keine lbs-id)

                            taucht im logfile nichts auf.

                            Gebe ich nun die Adresse "http://192.168.8.53:8068/webhook.php?id=262" ein, so kommt dieselbe Fehlermeldung wie bei tomki im Post Visitor Messages

                            id=262: File: /usr/local/edomi/www/data/liveproject/lbs/EXE19001076.php | Error: 2 | Line: 87 | array_key_exists() expects parameter 2 to be array, null given
                            id=262: File: /usr/local/edomi/www/data/liveproject/lbs/EXE19001076.php | Error: 2 | Line: 89 | array_key_exists() expects parameter 2 to be array, null given


                            Was mir bei dieser Webhook-Geschichte nicht ganz klar ist, und ich auch über Google nach 2 Stunden suchen nicht verstanden habe:
                            wie sieht das mit dem "query string" und dem "post" aus?

                            Da meine Programmierkenntnisse seit 2005 ziemlich eingerostet sind, und ich nicht up-to-date bin stehe ich etwas an.
                            Muss die Adresse "http://192.168.8.53:8068/webhook.php?id=262" nicht um die "Informationen" erweitert werden, welche mitgeschickt werden sollen?

                            Also Beispielsweise: "http://192.168.8.53:8068/webhook.php?id=262&post=Shelly.GetStatus"
                            Damit die Informationen auch beim LBS in Edomi ankommen?
                            Wie sollen sonst die Informationen am Ausgang vom LBS "query string" und "post" ankommen?
                            Wie kriege ich die nötigen Daten in den LBS damit ich dort den String zerlegen kann, bzw. benötige ich nur die
                            folgenden Informationen:

                            There are five events related to the Cover component that can trigger webhooks:
                            • cover.open: Cover has reached fully open position
                            • cover.closed: Cover has reached fully closed position
                            • cover.opening: Cover has begun moving in open direction
                            • cover.closing: Cover has begun moving in close direction
                            • cover.stopped: Cover has stopped moving, but is neither fully open nor fully closed
                            Dafür brauche ich ja nicht den gesamten Status.

                            Ich weiß man sagt "es gibt keine blöden Fragen, nur blöde Antworten" aber ich komme mir nun nach 1 1/2 Tagen suchen wirklich schon blöd vor.

                            Hintergrund der ganzen Spielerei ist einfach eine Rückmeldung vom Shelly "Rolladen fährt hoch" bzw. "Rollladen ist oben" etc.
                            Damit ich in der Visu in Echtzeit den Status anzeigen kann.

                            Ich wäre euch für jede Info bzw. Hilfe dankbar.

                            Lg, und noch ein schönes Wochenende

                            Jürgen

                            Kommentar


                              #15
                              Zitat von jkoller84 Beitrag anzeigen
                              Wenn ich nun mit einem http-requester eine webhook-Post Nachricht schreibe, kommt diese im edomi an, es kommt auch eine Rückmeldung das alles gepasst hat.
                              Wo kommt die Rückmeldung? in EDOMI? oder vom Requester? Letzteres ist klar, denn dann rufst du das webhook.php über den Apache Webserver (Port 80) auf. Du musst aber die im wemhook.php konfigurierten Port verwenden. Ist das 8086 bei dir?

                              Zitat von jkoller84 Beitrag anzeigen
                              Gebe ich nun die Adresse "http://192.168.8.53:8068/webhook.php?id=262" ein
                              Wo gibts du die ein? Im Browser? Das wird nicht funktionieren, da der LBS für HTTP-POST gedacht ist. Für HTTP-GET ist die EDOMI Remote API die richtige Wahl.

                              D.h. zuerst musst du mal klären, ob der Shelly GET oder POST sendet.

                              Bei GET => EDOMI-Remote API
                              Bei POST => webhook.php

                              Zitat von jkoller84 Beitrag anzeigen
                              Wie kriege ich die nötigen Daten in den LBS damit ich dort den String zerlegen kann
                              Das muss ja der Shelly machen, der muss webhook.php auf dem konfigurierten Port aufrufen und per POST die Daten übergeben. Die sollten dann am Ausgang des LBS auftauchen.

                              Kommentar

                              Lädt...
                              X