Pegelstand von Gewässer auf LCD darstellen

Hallo,

ich habe zwar schon einige kleine Projekt erfolgreich erstellt, würde mich aber noch als Anfänger bezeichnen.

Meine Schwiegermutter lebt in einem Hochwassergebiet und regelmäßig tritt der Bach neben ihrem Haus über die Ufer.
Zur kritischen Zeit verbringt sie viel Zeit vor dem PC (mit Tablet und Smartphone kann ich sie nicht überzeugen) und pürft die Pegelstände:

mobile Seite: Wasserburg / Inn

Um als Schwiegersohn zu punkten, würde ich ihr gerne über einen NodeMCU die Daten aus der Webseite auslesen und auf ein LCD-Disply anzeigen.

Leider verzeifel ich gerade am Auslesen der Webseite. Nachstehend mein Sketch (Anbindung LCD hab ich mal raugenommen):

/*
 * Basic ESP Client example, based on the ESP libraries examples
 */
 
#include <ESP8266WiFi.h>
 
const char* ssid     = "XXX";
const char* password = "XXX";
const char* host = "m.hnd.bayern.de";
 
void setup() {
  Serial.begin(115200);
  delay(10);
 
  // We start by connecting to a WiFi network
 
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();
}
 
void loop() {
  Serial.print("connecting to ");
  Serial.println(host);
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }
   
  // We now create a URI for the request
  String url = "/pegel.php?pgnr=18003004";
   
  Serial.print("Requesting URL: ");
  Serial.println(url);
   
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  // start waiting for the response             
  unsigned long lasttime = millis();
  while (!client.available() && millis() - lasttime < 1000) {delay(1);}   // wait max 1s for data
  // Read all the lines of the reply from server and print them to Serial
  //while(client.available()){
    //char readchar = client.read();
    //Serial.print(readchar);
  //}
  
  while (client.available()) {
  String line = client.readStringUntil('\n');
  if (line.indexOf("<p>Wasserstand [cm]: <b>") >= 0) { // Searchstring exists?
    Serial.println();
    Serial.print(line);
  }
}
  Serial.println();
  Serial.println("closing connection");
  delay(5000);
}

als Ergebnis kommt:

Connecting to XXX
....
WiFi connected
IP address: 
192.168.43.98

connecting to m.hnd.bayern.de
Requesting URL: /pegel.php?pgnr=18003004

closing connection

Ich habe auzch schon mal ein Versuch über die "Text Finder library " gemacht... ähnlich erfolglos :confused:

Vielleicht habt ihr eine Idee?!
Vielen Dank!

Warum so kompliziert? Kleines Tablet mit einem Kiosk-Browser immer aktiv laufen lassen. Ganz ohne Frikelei. Und wenn mal Bayern die Seite aktualisiert, sieht deine Schwiegermu immer noch das passende.

Wenn eine schöne rote Warnleuchte gefragt ist, dann würde ich glatt mal anfragen,ob es ein dokumentiertes API gibt.

noiasca:
Wenn eine schöne rote Warnleuchte gefragt ist, dann würde ich glatt mal anfragen,ob es ein dokumentiertes API gibt.

Wen interessiert ein API, wenn da nix von „Cloud“, Facebook oder Twitter drinsteht?

Gruß

Gregor

Lass Dir doch erst mal alles an Serial ausgeben, was da so ankommt.

Hast Du Dir den Quelltext der Tabelle mal angeschaut? Die Tabellenzeilen werden alle in einer einzigen Zeile übertragen, da ist Lesen bis \n suboptimal.

Ich würde da eher abschnittsweise einlesen.

<tr  class="row"><td >04.06.2018 03:00</td><td  class="center"><span style="color:green">245 - 305</span></td></tr> // green = Vorhersage
<tr  class="row"><td >02.06.2018 19:00</td><td  class="center"><span style="color:blue">317</span></td></tr> // blue = Wert

Gruß Tommy

@Tommy
psi13 liest aber,laut seinem Sketch, die mobile Version der Seite ein, da gibt es keine Tabelle.

Dort ist diese Zeile entscheidend:

<div id="title">Pegel</div><div id="rightbutton" class="zweiter_button"><a href="pegel.php?pgnr=18001508"><img alt="Vorheriger" title="Vorheriger" src="images/up.png" /></a></div><div id="rightbutton" class="dritter_button"><a href="pegel.php?pgnr=18004007"><img alt="Nächster" title="Nächster" src="images/down.png" /></a></div></div><div id="content"><ul class="pageitem"><li class="textbox"><span class="header">Wasserburg
Inn</span><div id='box' style='max-width:440px'><img style='width:100%;height:200px;' name="dia" src="include/minigraphik.php?pgnr=18003004&art=w&breite=300&hoehe=200&days=4&ms=420:500:550:600:::700&vhs=a&trend=&roh=1&showTrend=0"></div><p>Letzter Wert: <b>03.06.18, 16:45<span class="small"> Uhr</span></b></p><p class="in"><img src="images/ms0.png">Meldestufe: <b>0</b></p><p>Wasserstand [cm]: <b>303</b>
Abfluss [m³/s]: <b>637</b></p></li><li class="textbox" id="rot"><p>Pegelgroßanzeige derzeit wegen Reparatur außer Betrieb.</p></li><li class="textbox"><p class="in"><img src="images/ms1.png">Meldestufe 1:&nbsp;&nbsp;&nbsp;420 cm</p><p class="in"><img src="images/ms2.png">Meldestufe 2:&nbsp;&nbsp;&nbsp;500 cm</p><p class="in"><img src="images/ms3.png">Meldestufe 3:&nbsp;&nbsp;&nbsp;550 cm</p><p class="in"><img src="images/ms4.png">Meldestufe 4:&nbsp;&nbsp;&nbsp;600 cm</p><p class="in"><img src="images/black.png">IÜG: HQ<sub>100</sub>:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;700 cm</p></li></ul></div><div id="bottombar">

Ist auch die einzige der 3 Seiten (Diagramm, Tabelle, mobile Version), in der der Suchstring "

Wasserstand [cm]: " enthalten ist.

Dann muss er eben danach suchen. Der Rest der Aussagen bleibt bestehen.
Es kommt viel mehr, als er vermutet.

Gruß Tommy

Hallo,

ich habe leider im Moment keinen ESP mehr mit dem ich das mal probieren könnte. Ist also alle nur Vermutung .

Du willst Dir ja bereits den Inhalt jeder Zeile anzeigen lassen, aber da kommt nichts. Anscheinend klappt da was anderes aber nicht. ich vermute mal die gewünschte Seite wird nicht erreicht. Irgendwas stimmt mit dem Aufruf der Seite mit "GET" nicht.

// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");

und das nachfolgende :

while (client.available())

trifft nicht zu

Setze Dir doch den String mit dem Get erst mal in eine String zusammen und lass dir den auch noch mal anzeigen. ich vermute da liget das Problem.

Heinz

Nachtrag

mir fällt gerade auf es geht um eine HTTPS seite , geht das überhaupt ?

Dann muss er den HTTPS-Client nehmen. Hier ein Beispiel.

Gruß Tommy

Hallo,

das Beispie ist ja interessant, sollte also eigentlich gehen , und wo bekommt man ein Zertifikat her

Tommy56:
Dann muss er den HTTPS-Client nehmen. Hier ein Beispiel.

Gruß Tommy

Danke für eure Hinweise und Gedanken.

Tablet mit App wäre ne Idee, aber erstens wäre mir der Strombedarf im Dauerbetrieb zu hoch, und Zweitens wo wäre der Bastel-Spass :wink:

Ich setz mal den Beispiel-Sketch von Tommy entsprechend um und schreib dann nochmals...

Rentner:
Hallo,

das Beispie ist ja interessant, sollte also eigentlich gehen , und wo bekommt man ein Zertifikat her

Das steht im Code als Kommentar.

Gruß Tommy

Rentner:
Hallo,

das Beispie ist ja interessant, sollte also eigentlich gehen , und wo bekommt man ein Zertifikat her

Hallo ,

ich antworte mir mal selber :slight_smile:

Firefox

Seite mit Brauser aufrufen / rechte Maus / Seiteninformationen / Sicherheit / Zertifikat anzeigen .

sorry : erst denken dann schreiben ist manchmal besser

Gruß Heinz

Tommy56:
Das steht im Code als Kommentar.

Gruß Tommy

@Tommy

ich denke es geht aber um das Zertifiikat der Seite die man abrufen will , ?? Aber wie das genau abläuft weiss ich auch nicht.

Du hast es ja oben drüber schon genau beschrieben, wie man an den Fingerprint kommt.

Gruß Tommy

also ich hab den Beispiel-Sketch mal umgeschrieben

/*
    HTTP over TLS (HTTPS) example sketch
    This example demonstrates how to use
    WiFiClientSecure class to access HTTPS API.
    We fetch and display the status of
    esp8266/Arduino project continuous integration
    build.
    Limitations:
      only RSA certificates
      no support of Perfect Forward Secrecy (PFS)
      TLSv1.2 is supported since version 2.4.0-rc1
    Created by Ivan Grokhotkov, 2015.
    This example is in public domain.
*/

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

const char* ssid = "test";
const char* password = "lego1234";

const char* host = "m.hnd.bayern.de";
const int httpsPort = 443;

// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char* fingerprint = "6B 85 D3 12 8E A2 7B A7 CF 8E CD 8C BB 76 85 35 CA 80 EE 1A";

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.print("connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Use WiFiClientSecure class to create TLS connection
  WiFiClientSecure client;
  Serial.print("connecting to ");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }

  if (client.verify(fingerprint, host)) {
    Serial.println("certificate matches");
  } else {
    Serial.println("certificate doesn't match");
  }

  String url = "/pegel.php?pgnr=18003004";
  Serial.print("requesting URL: ");
  Serial.println(url);

  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "User-Agent: BuildFailureDetectorESP8266\r\n" +
               "Connection: close\r\n\r\n");

  Serial.println("request sent");
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
  }
  String line = client.readStringUntil('\n');
  if (line.startsWith("{\"state\":\"success\"")) {
    Serial.println("esp8266/Arduino CI successfull!");
  } else {
    Serial.println("esp8266/Arduino CI has failed");
  }
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.println("==========");
  Serial.println("closing connection");
}

void loop() {
}

Aber augenscheinlich klappt die Verbindung dennoch nicht

connecting to test
.......
WiFi connected
IP address: 
192.168.43.98
connecting to m.hnd.bayern.de
connection failed

Hab jetzt auch Freund Google genutz und nach anderen "https request" Sketches durchsucht.... aber auf die Schnelle keine Lösung...

Ich teste weiter...

Ich hab jetzt diverse Versuche hinter mir...

Augenscheinlich verhindert die Webseite den Zugriff.
z.B. ist auch ein Zugriff via PowerPoint Webviewer unmöglich

Über die Webseite https://www.pegel-alarm.de/pegel-details/18003004-wasserburg-inn/ funktioniert die Anzeige

// Pegel 
      String url = "/pegel-details/18003004-wasserburg-inn/";
      Serial.print("requesting URL: ");
      Serial.println(url);
    
      
      // This will send the request to the server
      client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                   "Host: " + host + "\r\n" +
                   "User-Agent: BuildFailureDetectorESP8266\r\n" +
                   "Connection: close\r\n\r\n");
        unsigned long timeout = millis();
        while (client.available() == 0) {
          if (millis() - timeout > 5000) {
            Serial.println(">>> Client Timeout !");
            client.stop();
            return;
        }
      }
      
      while (client.available()) {
        String line = client.readStringUntil('\n');
        if (line.indexOf("<h2>Wasserstand") >= 0) { // Searchstring exists?
          Serial.println();
         // Serial.println(line);
          int Pegel_vonPos = line.indexOf("Aktueller Wert: "); 
          int Pegel_bisPos = line.indexOf(" Uhr

");
          Serial.print("Wasserstand / Pegel ");
          Serial.print(line.substring(Pegel_vonPos, Pegel_bisPos));
          Serial.println(" Uhr");
      
        }
      }

Danke an alle für die Hilfe und die Tipps!!! 8)

Wen es interessiert, das Projekt ist fertig.

Bauteile:

  • NodeMCU Lua Lolin V3 Module ESP8266 ESP-12E
  • LCD-Display (20 Zeichen in 4 Zeilen) mit I2C Anschluss
  • KY-006 Buzzer Passiv
  • KY-011 2-Farben - Rot+Grün- 5mm LED Modul
  • Holzbox
  • diverse Kabel und Schrauben

hochwasser.ino (18.3 KB)

Danke für die Rückmeldung!

Zusammen mit einem Foto der Holzbox könntest Du Dein Projekt im Sammelthema vorstellen.