ralphi: Fehlermeldung bei file_get_contents - String auslesen.

Hi all,
ich hab mir einen Solarmonitor mit einem Arduino & Wlan-Modul (ESP8266) zusammengebastelt.
der ESP8266 fungiert als ‘pseudo’ Server und gibt wenn man ihn anspricht einen Json-String raus.

{"I_Sol":"0.00","I_Bat":"9.99","I_Load":"1.51","U_Sol":"0.00","U_Bat":"13.54"
,"P_Sol":"0.00","P_Bat":"135.23","P_Load":"20.50"}

Mit dem Browser bekomme ich den String angezeigt!

Allerdings mit php:
- $data = file_get_contents
- $data = file
- open // $data = fgets
bekomme ich

PHP Warning:  file_get_contents(http://192.168.123.35/): failed to open stream: HTTP request failed! {"I_Sol":"0.13","I_Bat":"1.48","I_Load":"1.07","U_Sol":"0.00","U_Bat":"13.35","P_Sol":"0.00","P_Bat":"19.75","P_Load":"14.34"} in ..

in der Var $data nix - das Json steht allerdings im Terminal ??

Mit curl ,

$ch = curl_init('http://192.168.123.35');
$data = curl_exec($ch);
if (!curl_errno($ch) ) { // logger
    echo "Schuppen Sol:\n"; // Solar
    echo "data: " . $data ."\n"; 
} 
curl_close($ch);

bekomm ich zwar keine Fehlermeldung - allerdings das selbe wie oben -> In der Shell steht das Json, in der var nicht !?
Kann mir Jemand helfen.

Viele Grüße aus LA
ralphi

--
"Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
  1. Hi,

    {"I_Sol":"0.00","I_Bat":"9.99","I_Load":"1.51","U_Sol":"0.00","U_Bat":"13.54"
    ,"P_Sol":"0.00","P_Bat":"135.23","P_Load":"20.50"}

    Mit dem Browser bekomme ich den String angezeigt!

    PHP Warning:  file_get_contents(http://192.168.123.35/): failed to open stream: HTTP request failed! {"I_Sol":"0.13","I_Bat":"1.48","I_Load":"1.07","U_Sol":"0.00","U_Bat":"13.35","P_Sol":"0.00","P_Bat":"19.75","P_Load":"14.34"} in ..
    

    Welchen Content-Type schickt der Server zu diesem JSON?

    cu,
    Andreas a/k/a MudGuard

  2. Tach!

    PHP Warning: file_get_contents(http://192.168.123.35/): failed to open stream: HTTP request failed!

    Was steht in der Variable $http_response_header nach dem Request? Du hast erstmal ein Problem beim Abfragen der Ressource. Dass sich in dem Fall kein gescheites Ergebnis in deinen Variablen anfindet, ist nur eine Folge davon.

    $ch = curl_init('http://192.168.123.35');
    $data = curl_exec($ch);
    if (!curl_errno($ch) ) { // logger
        echo "Schuppen Sol:\n"; // Solar
        echo "data: " . $data ."\n"; 
    } 
    curl_close($ch);
    

    bekomm ich zwar keine Fehlermeldung - allerdings das selbe wie oben -> In der Shell steht das Json, in der var nicht !?

    Dann ist wohl nicht der Fall !curl_errno() sondern curl_errno() eingetreten.

    curl_exec() liefert auch kein Ergebnis, wenn nicht CURLOPT_RETURNTRANSFER gesetzt wurde. Siehe verlinkte Dokumentation. Und var_dump() ist nach wie vor das bessere Mittel, sich über die tatsächlichen Inhalte zu informieren, als ein einfaches echo - gerade im Fehlerfall.

    Dein eigentliches Problem wird sicherlich auch nicht weggehen, wenn du noch andere HTTP-Request-Arten probierst. Unter Umständen wirst du wohl den Kabelhai (Wireshark) bemühen müssen.

    dedlfix.

    1. Hi,
      Jupp - das isses :-)
      So klappts

      $ch = curl_init('http://192.168.123.35');
      	curl_setopt($ch, CURLOPT_HEADER, 0);
      	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      	$data = curl_exec($ch);
      	if (!curl_errno($ch) ) { // logger
      		echo "Sol:\n"; // Solar
      		echo "data: " . $data ."\n"; 
      	} // logger
      	curl_close($ch);
      

      Viele Grüße aus LA
      ralphi

      --
      "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
      1. Tach!

        Jupp - das isses :-)

        Schön, dass es sich lösen ließ. Aber das war jedenfalls nicht der Grund, warum file_get_contents() fehlgeschlagen ist. Das muss prinzipiell auch zum Funktionieren gebracht werden können, wenn die eigentliche Ursache erkannt und beseitigt worden ist.

        dedlfix.

  3. Hallo,

    ich hab mir einen Solarmonitor mit einem Arduino & Wlan-Modul (ESP8266) zusammengebastelt.
    der ESP8266 fungiert als ‘pseudo’ Server und gibt wenn man ihn anspricht einen Json-String raus.

    was heißt "pseudo"? Ist er ein Server oder ist er keiner? Und versteht bzw. spricht er korrektes HTTP?

    Mit dem Browser bekomme ich den String angezeigt!

    Schon mal gut. Aber Browser sind allgemein recht fehlertolerant. Gut möglich, dass der großzügig über irgendeinen Formfehler hinwegsieht, der andere, pingelige HTTP-Clients aus dem Tritt bringt. Welche Response-Header sendet denn dein Controller?

    Allerdings mit php:
    - $data = file_get_contents
    - $data = file
    - open // $data = fgets
    bekomme ich

    Bitte, zum (n+1). Mal: Beschreibe genau, was du tust! Wie sieht dein Test-Code aus?

    PHP Warning:  file_get_contents(http://192.168.123.35/): failed to open stream: HTTP request failed! {"I_Sol":"0.13","I_Bat":"1.48","I_Load":"1.07","U_Sol":"0.00","U_Bat":"13.35","P_Sol":"0.00","P_Bat":"19.75","P_Load":"14.34"} in ..
    

    in der Var $data nix -

    Klar, wenn der Request fehlschlägt, kommen auch keine Daten.

    das Json steht allerdings im Terminal ??

    Und, wie es aussieht, als Teil der Fehlermeldung. Sehr eigenartig.

    $ch = curl_init('http://192.168.123.35');
    $data = curl_exec($ch);
    if (!curl_errno($ch) ) { // logger
        echo "Schuppen Sol:\n"; // Solar
        echo "data: " . $data ."\n"; 
    } 
    curl_close($ch);
    

    Ich kenne mich mit der curl-Extension nicht aus - aber ist es Absicht, dass bei der URL der abschließende Slash / fehlt? Gewöhnliche Browser ergänzen den stillschweigend, aber macht curl das auch?

    bekomm ich zwar keine Fehlermeldung - allerdings das selbe wie oben -> In der Shell steht das Json, in der var nicht !?
    Kann mir Jemand helfen.

    Ja, vielleicht. Mit komplettem Code und möglichst einem HTTP-Mitschnitt.

    So long,
     Martin

    --
    Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
    - Douglas Adams, The Hitchhiker's Guide To The Galaxy
    1. Hi Martin,

      was heißt "pseudo"? Ist er ein Server oder ist er keiner? Und versteht bzw. spricht er korrektes HTTP?

      Er hört auf einem Port und läßt 4 Verbindungen zu.

      Schon mal gut. Aber Browser sind allgemein recht fehlertolerant. Gut möglich, dass der großzügig über irgendeinen Formfehler hinwegsieht, der andere, pingelige HTTP-Clients aus dem Tritt bringt. Welche Response-Header sendet denn dein Controller?

      Das liegt an mir - in dem Fall keinen - Ich kann doch auch Textfiles einlesen !?

      Bitte, zum (n+1). Mal: Beschreibe genau, was du tust! Wie sieht dein Test-Code aus?

      Nun - beim ESP / µC ->

        sendData("AT+CWMODE=1\r\n",1000,DEBUG); // configure as client
        sendData("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
        sendData("AT+CIPSERVER=1,80\r\n",3000,DEBUG); // turn on server on port 80
      } // loop
      void serialEvent() {  // seriell interrupt
        // serveranfrage **
        while(Serial.available()) {
            lcd.setCursor(0, 3);
            lcd.print("Datenanfrage"); 
          if(Serial.find("+IPD,"))    {  // ID auslesen
           delay(1000);
            int connectionId = Serial.read()-48; // subtract 48 because the read() function returns 
            String cipSend = "AT+CIPSEND=";
           cipSend += connectionId;
           cipSend += ",";
           cipSend += json_txt.length();
           cipSend += "\r\n";
       
           sendData(cipSend,1000,DEBUG);
           sendData(json_txt,1000,DEBUG);
         lcd.setCursor(0, 3);
           lcd.print(cipSend);
            
           String closeCommand = "AT+CIPCLOSE="; 
           closeCommand+=connectionId; // append connection id
           closeCommand += "\r\n";
           sendData(closeCommand,3000,DEBUG);
           delay(1000);
          } // wenn ID
        } // daten in
      }// ende interrupt
      

      Also Länge des Strings + Conn-ID
      und dann das Json
      Im json_txt steht der Textstring.

      Viele Grüße aus LA
      ralphi

      --
      "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
      1. Hallo,

        Welche Response-Header sendet denn dein Controller?

        Das liegt an mir - in dem Fall keinen

        keinen?? Nicht mal einen Status? Denn der muss mindestens sein. Kein Wunder, dass deine Nutzdaten in der PHP-Fehlermeldung auftauchen! Der HTTP-Client von PHP versucht verzweifelt, die Daten als HTTP-Header auszuwerten.

        Ich kann doch auch Textfiles einlesen !?

        Natürlich. Aber trotzdem sinnvolle HTTP-Header senden. Mindestens der Status ist AFAIK erforderlich.

        So long,
         Martin

        --
        Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
        - Douglas Adams, The Hitchhiker's Guide To The Galaxy
        1. Hi,
          danke für die Info, ich werd ja künftig noch etwas mit dem ESP machen :-)

          Das mit der Solarbox war eh ne Schnappsidee. Kastl Ich hätte wissen müssen, das die Solarlader kein gleiches Massepotential haben.
          Bildbeschreibung

          Dh. das Solarminus ist negativ zur Akkumasse und damit ohne zusätzlichen ADC und Optokoppler nicht messbar.

          PS: Kann es sein, dass Bildeinfügen nicht geht? Viele Grüße aus LA
          ralphi

          --
          "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
          1. Hi all,

            Bilder hinzufügen is nich :-(
            Hier die Links:
            http://www.bilder-upload.eu/show.php?file=d1db1e-1465315408.jpg
            http://www.bilder-upload.eu/show.php?file=f13c07-1465316123.jpg

            Viele Grüße aus LA
            ralphi

            --
            "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
            1. Hallo ralphi,

              Bilder hinzufügen is nich :-(

              Bilder hinzufügen is.

              Hier die Links:
              http://www.bilder-upload.eu/show.php?file=d1db1e-1465315408.jpg
              http://www.bilder-upload.eu/show.php?file=f13c07-1465316123.jpg

              Hier die Bilder:

              Bildbeschreibung

              Bildbeschreibung

              Bis demnächst
              Matthias

              --
              Dieses Forum nutzt Markdown. Im Wiki erhalten Sie Hilfe bei der Formatierung Ihrer Beiträge.
          2. Hallo,

            Das mit der Solarbox war eh ne Schnappsidee. Kastl Ich hätte wissen müssen, das die Solarlader kein gleiches Massepotential haben.

            häh? Du redest von einem neuen Problem, das hier noch nicht angesprochen wurde?

            PS: Kann es sein, dass Bildeinfügen nicht geht?

            Nein. Aber du hast kein Bild eingefügt, sondern ein komplettes HTML-Dokument, das neben viel anderem Gedöns unter anderm ein Bild referenziert. Das ist so nicht vorgesehen.

            So long,
             Martin

            --
            Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
            - Douglas Adams, The Hitchhiker's Guide To The Galaxy
      2. Nimm mal ein Programm wie wget und rufe damit eine funktionierende Webseite ab.

        Ich habe das mal gemacht:

        wget -d --delete-after http://www.google.de

        Das liefert u.a. den Response-Header:

        HTTP/1.1 200 OK
        Date: Wed, 08 Jun 2016 00:22:19 GMT
        Expires: -1
        Cache-Control: private, max-age=0
        Content-Type: text/html; charset=ISO-8859-1
        

        Das dürften dann auch so ziemlich die Mindestangaben sein, die Du auch senden lassen musst. Natürlich an Deine Zwecke angepasst.

        Nach dem Header folgt eine Leerzeile (Zeilenende ist "\n\r") und dann der "Payload", also die Webseite bzw. hier das Text in json-Format.

        1. Moin,

          HTTP/1.1 200 OK
          Date: Wed, 08 Jun 2016 00:22:19 GMT
          Expires: -1
          Cache-Control: private, max-age=0
          Content-Type: text/html; charset=ISO-8859-1
          

          Das dürften dann auch so ziemlich die Mindestangaben sein, die Du auch senden lassen musst.

          nein, absolut notwendig ist von den genannten nur der Status, also die erste Zeile; der Rest ist Luxus. Den Content-Type würde ich noch als "dringend zu empfehlen" einstufen.

          Nach dem Header folgt eine Leerzeile (Zeilenende ist "\n\r")

          Normalerweise genau andersrum: \r\n

          So long,
           Martin

          --
          Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
          - Douglas Adams, The Hitchhiker's Guide To The Galaxy
          1. Moin,

            HTTP/1.1 200 OK
            Date: Wed, 08 Jun 2016 00:22:19 GMT
            Expires: -1
            Cache-Control: private, max-age=0
            Content-Type: text/html; charset=ISO-8859-1
            

            Das dürften dann auch so ziemlich die Mindestangaben sein, die Du auch senden lassen musst.

            nein, absolut notwendig ist von den genannten nur der Status, also die erste Zeile; der Rest ist Luxus. Den Content-Type würde ich noch als "dringend zu empfehlen" einstufen.

            Nun ja. Ich hatte schon an die Funktion gedacht. Weiß der Hohle welcher Browser sonst denkt er könnte das cachen oder als Film darbieten.

            Nach dem Header folgt eine Leerzeile (Zeilenende ist "\n\r") Normalerweise genau andersrum: \r\n

            Richtig. Mein Fehler.

            So long,

            So short.

            1. Hi all,

              jup - funktioniert - danke :-)

              Viele Grüße aus LA
              ralphi

              --
              "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
    2. Tach!

      $ch = curl_init('http://192.168.123.35');

      Ich kenne mich mit der curl-Extension nicht aus - aber ist es Absicht, dass bei der URL der abschließende Slash / fehlt? Gewöhnliche Browser ergänzen den stillschweigend, aber macht curl das auch?

      Weder Curl noch Browser brauchen nach dem Domainnamen oder IP-Adresse einen / (wenn kein Pfad angegeben ist). Die URL kann nicht 1:1 genommen werden, sondern muss in jedem Fall zerlegt werden, um die verschiedenen Informationen für den eigentlichen Request und den Verbindungsaufbau entnehmen zu können.

      • http muss umgesetzt werden in die zugehörige Portnummer
      • :// muss ignoriert werden (zumindest für HTTP)
      • Ein Domainname müsste in eine IP-Adresse aufgelöst werden und wird außerdem zum Bilden des Host-Headers herangezogen. Ist hier nicht der Fall.
      • Die IP-Adresse wird für den Verbindungsaufbau benötigt und nicht für den eigentlichen Request (sprich, die Nutzlast aus Sicht von TCP)
      • Die erste Zeile des HTTP-Requests sieht in dem Fall so aus: GET / HTTP/1.x
        Ein Weglassen des ersten / ergibt ungültige Syntax. HTTP-Clients müssen in jedem Fall bei nicht vorhandenem Pfad selbständig den / substituieren.

      Die Sachlage ist anders, wenn der / Teil eines ansonsten nicht leeren Pfads ist. Da muss klar angegeben werden, ob das Verzeichnis gemeint ist (mit /) oder ein Dokument im Elternverzeichnis (ohne /), sonst gibt es Folgefehler beim Auflösen relativer Links. Meist wird Webserver beim Fehlen des / und wenn ein gleichnamiges Verzeichnis gefunden werden kann, den Client zur Adresse mit angehängtem / weiterleiten. Wenn man sich diesen Redirekt sparen möchte, sollte man solche Adressen gleich mit abschließendem / angeben. Aber wie gesagt, bei leerem Pfad muss der Browser selbständig den / verwenden.

      dedlfix.