Very Short: Seitenquelltext mit ESP8266 parsen

Moin zusammen!

Ich habe gestern das Internet durchforstet, aber keine passende Lösung für mein Problem findet können.

Das Ziel

Ein Gerät im häuslichen WLAN stellt Informationen über den Stromverbrauch eines Gerätes zu Verfügung. Diese Informationen können unter der Adresse

http://192.168.2.115/status/meters

abgefragt werden. Das Ergebnis dieser Seite sieht wie folgt aus:

{"wifi_sta":{"connected":true,"ssid":"Horst 2,4","ip":"192.168.2.115","rssi":-47},"cloud":{"enabled":true,"connected":true},"mqtt":{"connected":false},"time":"10:29","unixtime":1636190951,"serial":397,"has_update":false,"mac":"E8DB84D28E5B","cfg_changed_cnt":0,"actions_stats":{"skipped":0},"relays":[{"ison":true,"has_timer":false,"timer_started":0,"timer_duration":0,"timer_remaining":0,"overpower":false,"source":"input"}],"meters":[{"power":207.52,"overpower":0.00,"is_valid":true,"timestamp":1636194551,"counters":[202.166, 194.122, 184.188],"total":21996}],"inputs":[{"input":0,"event":"","event_cnt":0}],"temperature":31.32,"overtemperature":false,"tmp":{"tC":31.32,"tF":88.38, "is_valid":true},"temperature_status":"Normal","ext_sensors":{},"ext_temperature":{},"ext_humidity":{},"update":{"status":"idle","has_update":false,"new_version":"20210909-145919/v1.11.4-DNSfix-ge6b2f6d","old_version":"20210909-145919/v1.11.4-DNSfix-ge6b2f6d"},"ram_total":50464,"ram_free":37612,"fs_size":233681,"fs_free":149345,"uptime":10004}

Mir geht es lediglich um die Abfrage des Wertes "Power".

Das Problem

Die Vorlagen aus dem Netz fragen von Servern ab und erwarten verschiedenste Angaben für die Funktion des Codes. Leider steht mir nur diese eine Adresse zur Verfügung´, mit welcher das leider nicht so ganz funktionieren mag.

Mit LabView ist die Realisierung der ganzen Sachen kein Problem, aber bei Arduino komme ich leider nicht weiter.

Die Hardware

Genutzt wird ein ESP8266, welcher sich im selben WLAN befindet und dort die Daten weiterverarbeiten soll. Dies ist aber nicht Inhalt dieses Posts

Die Zusammenfassung

Wie bekomme ich den Wert aus dem Quelltext der Seite ausgelesen?

Gruß und vielen Dank aus Recklinghausen
Wu

Das sieht nach JSON aus. Dafür gibt es Libs. Infos z.B hier.

Gruß Tommy

Aufteilen.
War recht einfach - habe ich mal gemacht ohne Vorkenntnisse auf Basis:
https://randomnerdtutorials.com/decoding-and-encoding-json-with-arduino-or-esp8266/
Der funktionierende Ansatz war dann:
https://forum.arduino.cc/t/sonnenaufgang-vom-openweathermap/703560/17?u=my_xy_projekt

@Tommy56
Das geht schon in die richtige Richtung.
Leider beschreiben die Artikel lediglich, wie ein String mit dem Vorgang aufgedröselt wird.

@my_xy_projekt
Auch hierauf war ich bereits gestoßen. Dieser Code ist genau das, was mich eben nicht wirklich weiterbringt. Es geht um die Auslese der Wetterdaten und hier wird, wie ich ja geschrieben habe, mit verschiedenen Serverangaben und API-Sachen gehandhabt.

Noch einmal zur Klarstellung:

Ich habe nur diese eine Adresse und möchte den String auslesen.
Gibt es da keine einfach Funktion, wo man lediglich eine URL vorgibt und sich der Arduino den Seitenquelltext zieht?

DOCH!


#include <ArduinoJson.h>

StaticJsonBuffer<2000> jsonBuffer;
char json[] = "{\"wifi_sta\":{\"connected\":true,\"ssid\":\"Horst 2,4\",\"ip\":\"192.168.2.115\",\"rssi\":-47},\"cloud\":{\"enabled\":true,\"connected\":true},\"mqtt\":{\"connected\":false},\"time\":\"10:29\",\"unixtime\":1636190951,\"serial\":397,\"has_update\":false,\"mac\":\"E8DB84D28E5B\",\"cfg_changed_cnt\":0,\"actions_stats\":{\"skipped\":0},\"relays\":[{\"ison\":true,\"has_timer\":false,\"timer_started\":0,\"timer_duration\":0,\"timer_remaining\":0,\"overpower\":false,\"source\":\"input\"}],\"meters\":[{\"power\":207.52,\"overpower\":0.00,\"is_valid\":true,\"timestamp\":1636194551,\"counters\":[202.166, 194.122, 184.188],\"total\":21996}],\"inputs\":[{\"input\":0,\"event\":\"\",\"event_cnt\":0}],\"temperature\":31.32,\"overtemperature\":false,\"tmp\":{\"tC\":31.32,\"tF\":88.38, \"is_valid\":true},\"temperature_status\":\"Normal\",\"ext_sensors\":{},\"ext_temperature\":{},\"ext_humidity\":{},\"update\":{\"status\":\"idle\",\"has_update\":false,\"new_version\":\"20210909-145919/v1.11.4-DNSfix-ge6b2f6d\",\"old_version\":\"20210909-145919/v1.11.4-DNSfix-ge6b2f6d\"},\"ram_total\":50464,\"ram_free\":37612,\"fs_size\":233681,\"fs_free\":149345,\"uptime\":10004}}";



void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  JsonObject &root = jsonBuffer.parseObject(json);
  if (!root.success())
  {
    Serial.println(F("parseObject() failed"));
  }
  float power = root["meters"][0]["power"];
  Serial.println(power);
}

void loop() {}

Du musst verstehen, wie es geht!
Das Ergebnis:

17:50:14.225 -> Start...
17:50:14.225 -> 207.52

@my_xy_projekt

Entweder wir reden aneinander vorbei oder ich verstehe einfach nicht, worauf du hinaus möchtest.

Ich verstehe zwar, wie das ganze in Theorie funktionieren soll.

Aber hierbei zwei Probleme für mich:

  1. Der von Dir gesendete Code entnimmt zwar den gesuchten Wert. Allerdings ist die Frage, wie ich den Seitenquellcode regelmäßig von der genannten URL abgefragt bekomme damit noch nicht beantwortet.

  2. Wenn ich den Code von Dir bei mir einfüge, so treten nur Fehler auf. Habe die entsprechende Bib zwar installiert, aber mit allem, was irgendwie JSON in sich trägt, gibt es nur Probleme.

Ignoriere vielleicht einmal erst Problem 2. Mit geht es eigentlich nur um den Quellcode der Seite. Den Rest bekommt man dann schon sicherlich irgendwie gedängelt.

Das ist doch ganz einfach.
Du hast in Deinem Ausgangspost ein JSON-Paket geliefert.
Dieses Paket habe ich in ein Char-Array geschoben und dann mittels - und hier sage ich es nochmal: der für mich effektivsten - Lib geparst und den Inhalt des Feldes ausgegeben.
Wo hast Du denn DEIN JSON-Paket her?
Verwende das. Anstelle meines CharArray. ODER: Dein JSON-Paket in das CharArray. Es kommt aufs Gleiche raus.
Der Parser ist so einfach zu bedienen, da kann ich Dein Problem nicht nachvollziehen - Bitte beachte, was bei randomnerdtutorials zur Version steht.

Das könnte an einer falschen Version liegen.
Du hälst Dich mit wichtigen Informationen zurück....

@my_xy_projekt

Okay, schieben wir das Thema mit dem Parser erst einmal zur Seite und ich kümmere mich um den Informationsmangel.

Zum Projekt:

Die Leistung unser PV-Anlage soll ausgelesen werden. Dies geschieht über einen Shelly 1PM. Dieser misst als externe Messeinrichtung die aktuelle Leistung des Wechselrichters im Garten. Die Daten werden nun per WLAN in die Shelly-Cloud übertragen und stehen dann zur Verfügung.

Der Shelly hat die erwähnte IP mit
http://192.168.2.115/

Durch den Zusatz "/status/meters" komme ich an den eingangs geposteten JSON-Datenstrang.

Mit dem ESP8266 möchte ich lediglich in regelmäßigen Abständen die Leistung der Anlage abrufen, um in einem späteren Schritt Geräte, in Abhängigkeit der aktuellen Leistung, ein- oder abzuschalten.

Meine Frage ist in erster Linie darauf bezogen, wie ich die Daten von der genannten URL auf den Arduino bekomme. Hierzu habe ich im Netz keine Variante gefunden, die lediglich mit der Adresse funktioniert.

Auf dieser Seite befindet sich dann lediglich das genannte Datenpaket.

Falls Dir noch etwas unklar sein sollte, so schreibe mir bitte genau, welche Info Dir da noch fehlt.

Ich glaube, dass ich mich da vielleicht ein wenig missverständlich ausgedrückt habe, was ich da eigentlich vorhabe.

!WIE!
Ich muss nicht wissen, was Du da an Hardware hast etc.
Zeige doch bitte einfach den Code auf den man aufsetzen kann, wenn Du das selbst nicht umgesetzt bekommst und Hilfe erwartest.
Bitte Passwörter und ähnliches maskieren.

@my_xy_projekt

Ok, dann ist die Frage verstanden.

Um es kurz zu machen: Bis auf die WLAN-Verbindung ist da noch nicht viel gelaufen. Ich finde keine Code, auf den ich selbst aufsetzen kann. In der Regel suche ich die Sachen im Netz und modifiziere diese dann für meine Anwendungen. Leider ist es bei dieser Sache nur so, dass ich halt keinen entsprechenden Code als Beispiel finden kann.

Suche ich bei Google nach "Source text website read out arduino", so finde ich keine einzige Methode, die für mich passen würde. Darin liegt das Problem für mich begraben.

Wie bist Du denn an das JSON-Paket gekommen?

@my_xy_projekt

Im Shelly Forum bin ich auf die Erweiterung der URL aufmerksam geworden
Also wie beschrieben: Durch die Ergänzung der URL kommt man an das Datenpaket

Durch die Aktualisierung der entsprechenden Seite kommt man dann an die frischen Daten!

Ich bin dann raus.
Ich fühle mich verarscht.
Den Weg wie Du an jeden einzenlen Datenpunkt kommst, habe ich Dir gezeigt.
Vielleicht will ja @Tommy56 hier weiter machen.
Tommy:

Schade drum.

In den Get-Request eben nix mit ? einsetzen, sondern die URL /status/meters für das JSON-Paket.
Mangels Shelly konnte ich es nicht ausprobieren.

Das scheint der TO ja zu machen - er zeigt nur nicht das was er auswertet :hot_face:

Da der TO anscheinend nur vorgekaute Lösungen haben will, habe ich auch keine Lust mehr.
Er hat alles bekommen, was er braucht. Da sind auch Beispiele dabei, die genau das zeigen, was er tun will, z.B. bei der Lib. Etwas eigenes Denken kann man schon verlangen.

Gruß Tommy

1 Like

Ich habe ja sonst ein dickes Fell.
Dann war ich nicht empfindlich.
Danke.

Manchmal nach meiner Meinung zu dick :wink:

Gruß Tommy

Ich habe nur einen ESP32, daher könnte es kleine Abweichungen geben.

Meine Aktivitäten beziehen sich auf die Seiten von Fips, beispielsweise auf Esp8266 Html Form als Arduino Tab. Eventuell hilfreich meine Anleitung: Einführung zu fipsok.de.

In setup etabliere ich ein Ereignis, das sich bei mir auf "licht.html", bei Dir wohl auf " /status/meters". Das Parsen erfolgt über die Argumente:

  server.on("/licht.html", []() {
    anzeigeOLED(String("uri " + server.uri()).c_str());
    anzeigeOLED(String("args " + String(server.args())).c_str());
    
      for (uint8_t i = 0; i < server.args(); i++) {
      anzeigeOLED(String(server.argName(i) + ": " + server.arg(i)).c_str());
      }
   }

Meine HTML-Datei überträgt 23 Argumente, hier die OLED-Anzeige auf den Anfang gekürzt:

grafik

In einer Funktion hole ich mir die Werte in Variablen FA_*:

void arg_Farbe() {
  if (server.hasArg("FA_Farbe")) {
    FA_Farbe = server.arg("FA_Farbe").toInt();
    anzeigeOLED(String("Wert_Farbe: " + String(FA_Farbe)).c_str());
  }
  if (server.hasArg("FA_Saettigung")) {
    FA_Saettigung = server.arg("FA_Saettigung").toInt();
    anzeigeOLED(String("Wert_Saettigung: " + String(FA_Saettigung)).c_str());
  }
  if (server.hasArg("FA_Helligkeit")) {
    FA_Helligkeit = server.arg("FA_Helligkeit").toInt();
    anzeigeOLED(String("Wert_Helligkeit: " + String(FA_Helligkeit)).c_str());
  }
}

Das sind dann die Zahlenwerte:

grafik

Hier kann man den Aufbau der JSON-Daten erkennen, die meine HTML-Datei schickt:

String json_Farbe() {
  return (String) +
         "\"FA_Farbe\":\"" + FA_Farbe + "\","
         "\"FA_Saettigung\":\"" + FA_Saettigung + "\","
         "\"FA_Helligkeit\":\"" + FA_Helligkeit + "\""
         ;
}

Der Esp8266 Http Client als Arduino Tab zeigt Dir, wie man eine URL abfragt. Das ist beim ESP8266 etwas anders als beim ESP32, daher passen da meine Beispiele nicht.

Viel Erfolg!