openweathermap – Daten lesen und parsen der JSON-Daten

Foren Das NanoESP & Pretzel Board Forum openweathermap – Daten lesen und parsen der JSON-Daten

Schlagwörter: ,

Dieses Thema enthält 1 Antwort und 1 Teilnehmer. Es wurde zuletzt aktualisiert von  Philipp vor 3 Wochen.

Ansicht von 2 Beiträgen - 1 bis 2 (von insgesamt 2)
  • Autor
    Beiträge
  • #2149

    Philipp
    Participant

    Hallo zusammen,

    ich möchte gern von der Seite openweathermap.com meine Wetterdaten abziehen und später in einem Display darstellen.
    Nun ergibt sich folgende Problematik. Ich habe mir die Libs von Hrn. Kainka zu nutze gemacht (Danke schon mal dafür), um die Daten von der Website abzuzeiehen. Dies klappt soweit:

    Serielle Ausgabe:

    WLAN Connected

    AT+CIFSR

    +CIFSR:STAIP,“192.168.XXX.XXX“
    +CIFSR:STAMAC,“18:fe:34:XX:XX:XX“

    OK

    Internet Connection OK
    Ping: 305ms
    CONNECTED TO SERVER
    REQUEST SEND
    {„coord“:{„lon“:9.72,“lat“:53.7},“weather“:[{„id“:802,“main“:“Clouds“,“description“:“scattered clouds“,“icon“:“03d“}],“base“:“stations“,“main“:{„temp“:12,“pressure“:1019,“humidity“:81,“temp_min“:12,“temp_max“:12},“visibility“:10000,“wind“:{„speed“:7.2,“deg“:320},“clouds“:{„all“:40},“dt“:1509097800,“sys“:{„type“:1,“id“:4883,“message“:0.1779,“country“:“DE“,“sunrise“:1509084727,“sunset“:1509119812},“id“:2911298,“name“:“Hamburg“,“cod“:200}CONVERTING DATA
    DISCONNECTED FROM SERVER

    Nun will ja den String ja nicht hoch und runter aus einanderschnibbeln. Sondern schön über die JSON-Lib auslesen.
    Schheinbar verträgt sich http-Request bzw. die WiFi-Verbindung nicht so gut mit dem JSON-Parser.
    Um zu prüfen, ob die Daten richtig sind und um die Buffergröße usw. zu ermitteln habe ich folgendes genutzt:
    JSON-Assistent

    Die Seite gibt einem auch schön den Code wieder, welchen wir zum auslesen der einzelnen Felder benötigen.
    Sobald ich diesen aber nutze, bzw. ab dem Moment (JsonObject& root = jsonBuffer.parseObject(json);) kann das System die Daten nicht mehr aus dem Internetziehen und selbst wenn ich dem Parser die Daten vorgebe, schlägt es fehl.

    Nach dem ich google ein wneig beschäftigt habe, bin ich auch auf folgendes gestoßen:
    why-arduinojson-is-slow aber weitergekommen bin ich damit leider auch nicht, da ich kein Profi in Sachen Programmierung bin.

    Könnt ihr einmal drüber schauen und mit ggf. Verbesserungsvorschläge geben oder sagen woran es liegt? DANKE :)

    (Zeile 118 ist der Parser)

    #include <NanoESP.h>
    // #include <NanoESP_HTTP.h> //NanoESP_HTTP http = NanoESP_HTTP(nanoesp); //http.sendRequest(1, "GET", servername + page);
    #include <ArduinoJson.h>
    #include <SoftwareSerial.h>
    
    #define DEBUG true
    
    #define LED_WLAN 13
    
    #define SSID "SSID meines WLAN"
    #define PASSWORD "Mein super geheimer Key"
    
    #define servername "api.openweathermap.org"
    #define APIKEY  "Mein API-KEY"
    #define CityID "2911298"
    
    NanoESP nanoesp = NanoESP();
    
    //----------------- die NanoESP-Konfiguration vornehmen
    void setup() {
      Serial.begin(19200);
      nanoesp.init();
    
      if (!nanoesp.configWifi(STATION, SSID, PASSWORD)) {
        debug(F("Error: WLAN not Connected\n"));
      }
      else {
        debug(F("WLAN Connected\n"));
        digitalWrite(LED_WLAN, HIGH);
      }
    
      //Print IP in Terminal
      debug(nanoesp.getIp());
    
      //Time for Ping
      int vTime = nanoesp.ping(servername);
    
      if (vTime > 0 ) {
        debug("Internet Connection OK\nPing: " + String(vTime) + "ms");
      }
      else {
        debug(F("Error: Internet Connection"));
      }
    
    }
    
    //----------------- unsere Dauerschleife
    void loop() {
    
      connectServer();
      convertData(readData());
      disconnectServer();
    
      delay(300000);
    
    }
    
    //----------------- Verbinden mit dem openwaethermap-Server und Request senden
    void connectServer() {
      String page = "/data/2.5/weather?id=" + String(CityID) + "&units=metric&APPID=" + String(APIKEY);
      String getRequest = "GET " + page + " HTTP/1.1\r\n" +
                          "Host:" + servername + "\r\n\r\n";
      //"Connection: close\r\n\r\n" ;
      //"Connection: keep-alive\r\n\r\n" ;
    
      if (nanoesp.newConnection(1, "TCP", servername, 80)) {
        debug("CONNECTED TO SERVER");
        if (nanoesp.sendData(1, getRequest)) {
          debug("REQUEST SEND");
        } else {
          debug("BAD REQUEST RESPONSE");
        }
      } else {
        debug("COULD NOT CONNECT TO SERVER");
      }
    }
    
    //----------------- Verbindung mit dem openwaethermap-Server aufheben
    void disconnectServer() {
      if (nanoesp.closeConnection(1)) {
        debug("DISCONNECTED FROM SERVER");
      } else {
        debug("\r\nCOULD NOT DISCONNECT FROM SERVER");
      }
    
    }
    
    //----------------- die angeforderten Daten aus dem NanoESP lesen
    String readData() {
      String data;
      char endOfHeaders[] = "\r\n\r\n";
    
      while (!nanoesp.available()) {}; //warten auf NanoESP
    
      while (nanoesp.available()) {
        if (nanoesp.find(endOfHeaders)) //damit wir nur die JSON-Daten auslesen
        { data = nanoesp.readString();
          Serial.print(data);
        } else {
          debug("COULD NOT READ DATA");
        }
      }
      return data;
    }
    
    //----------------- die Daten aus dem JSON-Format konvertieren
    void convertData(String data) {
      //{"coord":{"lon":9.72,"lat":53.7},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"base":"stations","main":{"temp":13.37,"pressure":1019,"humidity":76,"temp_min":13,"temp_max":14},"visibility":10000,"wind":{"speed":4.6,"deg":280},"clouds":{"all":75},"dt":1509029400,"sys":{"type":1,"id":4883,"message":0.003,"country":"DE","sunrise":1508998236,"sunset":1509033510},"id":2911298,"name":"Hamburg","cod":200}
      debug("CONVERTING DATA");
      const char* json = data.c_str();
      //Serial.println(json);
    
      const size_t bufferSize = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(12) + 390;
      DynamicJsonBuffer jsonBuffer(bufferSize);
    
      //const char* json = "{\"coord\":{\"lon\":9.72,\"lat\":53.7},\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04d\"}],\"base\":\"stations\",\"main\":{\"temp\":13.37,\"pressure\":1019,\"humidity\":76,\"temp_min\":13,\"temp_max\":14},\"visibility\":10000,\"wind\":{\"speed\":4.6,\"deg\":280},\"clouds\":{\"all\":75},\"dt\":1509029400,\"sys\":{\"type\":1,\"id\":4883,\"message\":0.003,\"country\":\"DE\",\"sunrise\":1508998236,\"sunset\":1509033510},\"id\":2911298,\"name\":\"Hamburg\",\"cod\":200}";
     
      JsonObject& root = jsonBuffer.parseObject(json);
    //
    //  const char* name = root["name"]; // "London"
    //
    //  if (!root.success()) {
    //    Serial.println("parseObject() failed");
    //  }
    //  Serial.println(name);
    
    }
    
    //----------------- entsprechend der globalen Vorgabe debuggen wir oder nicht
    void debug(String Msg)
    {
      if (DEBUG)
      {
        Serial.println(Msg);
      }
    }
    #2150

    Philipp
    Participant

    Ich habe am readData() und convertData() noch ein wenig geschraubt, aber trotzdem schlägt das parsing fehl :/
    Die richtigen Daten kommen schon beim JSON-Datenelement an, aber warum es diese nicht versteht gute Frage.

    Ich habe in einem abgespecktem Programm auch ein wenig experimentiert und es kamen tolle Dinge beim parsing rum.
    Alleine ein else-Zweig beim if (!root.success()) { Serial.println(„parseObject() failed“); } führte dazu, dass es nicht mehr ging. :/

    //----------------- die angeforderten Daten aus dem NanoESP lesen
    String readData() {
    
      String data;
      char endOfHeaders[] = "\r\n\r\n";
    
      while (!nanoesp.available()) {}; //warten auf NanoESP
    
      while (nanoesp.available()) {
        if (nanoesp.find(endOfHeaders)) //damit wir nur die JSON-Daten auslesen
        { data = nanoesp.readString();
          //Serial.print(data);
          return data;
        } else {
          debug("COULD NOT READ DATA");
          return "FAILED";
        }
      }
    //----------------- die Daten aus dem JSON-Format konvertieren
    void convertData(String data) {
    
      debug("\r\nCONVERTING DATA");
      const char* json = data.c_str();
      Serial.println(json);
      debug("CONVERTED TO JSON");
    
      const size_t bufferSize = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(12) + 400;
      DynamicJsonBuffer jsonBuffer(bufferSize);
      //StaticJsonBuffer<1024> jsonBuffer;
    
      JsonObject& root = jsonBuffer.parseObject(json);
    
      String location = root["name"];
      float temperature = root["main"]["temp"];
    
      if (!root.success()) { Serial.println("parseObject() failed"); }
      Serial.println("In " + location + " sind es aktuell " + temperature + "°C.");
    
    }
    
Ansicht von 2 Beiträgen - 1 bis 2 (von insgesamt 2)

Du musst angemeldet sein, um auf dieses Thema antworten zu können.