Json liefert unregelmässig Wert 0.0

Hi zsamma :slight_smile:

void jsonTemp() {
  http.useHTTP10(true);
  http.begin(wifiClient, "http://192.168.178.197/weather.json");
  http.GET();
  //delay (2000); // DIRTY !!! geht nicht und auch nicht Serial.setTimeout(10000);

  StaticJsonDocument<1024> doc; //DynamicJsonDocument doc(2048);
  deserializeJson(doc, http.getStream());
  float aTemp = doc["channel7"]["temperature"];
  http.end();
  Serial.println(aTemp);
}

Ich habe diese kleine Funktion gebaut nach der Anleitung von der ArduinoJson Entwickler Seite.

Allerdings lieft mir diese in unregelmäßigen Abständen den Wert 0.00 als Temperatur.
Sie wird 1x pro Stunde aufgerufen.

Kann jemand nachvollziehen warum? :crazy_face:

Danke euch und schönes Wochenende :slight_smile:

Offensichtlich gehst du hier davon aus, dass der HTTP Zugriff erfolgreich war.
War er das?

1 Like

Danke dir, Ja das stimmt… :thinking:

Ich ging davon aus, dass es im Heimnetzwerk keine Probleme gibt.

Ich kann ja noch abfragen auf


int httpCode = http.GET();          
    if (httpCode  == 200) { 
            jsonTemp();
      }
 
    else {
      Serial.println("Fehler bei HTTP Anfrage");
    }

Aber was mache ich dann, wenn es fehlschlägt?

1 Sek warten und erneut versuchen?
Oder wie handhabt man das dann am schlauesten?

Auf den unterschiedlichen Verbindungsebenen Fehlercodes auswerten und die Verbindung bei Bedarf erneut aufbauen. Als Beispiel:

Programm
void routerVerbindung()
{
  unsigned long connDauer = 20000;
  unsigned long connTimer = millis();

  if (WiFi.status() != WL_CONNECTED)
  {
    DEBUG_F("Verbindung zum Router ");
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    WiFi.begin(STA_SSID, STA_PASSWORD);
    while (WiFi.status() != WL_CONNECTED && (millis() - connTimer < connDauer)) {
      digitalWrite(LED_BUILTIN, 1);
      delay(250);
      digitalWrite(LED_BUILTIN, 0);
      delay(250);
      DEBUG_F(".");
    }
    if (WiFi.status() == WL_CONNECTED)
    {
      WiFi.setAutoReconnect(true);
      WiFi.persistent(false);  // true = default, bei reboot werden ssid+pass in den Flash geschrieben, killt den freien Speicher!
      DEBUG_L("\nVerbunden mit: " + WiFi.SSID());
      DEBUG_L("Esp32 IP: " + WiFi.localIP().toString() + "\n");
    } else {
      DEBUG_L(" nicht hergestellt");
    }
  }
}
1 Like

Kannst du mal im Fehlerfall das JSON auf der Console ausgeben? Damit kannst du dann feststellen, ob der Fehler beim Versenden auf dem Server passiert oder beim Parsen auf dem Arduino.

Also anstatt

deserializeJson(doc, http.getStream());

die Daten erstmal in eine Variable speichern und wenn du den Fehler feststellst dann ausgeben.

1 Like

Danke euch :slight_smile:

Also das habe ich mal getestet, und der ESP8266 ist immer im Netz erreichbar bis jetzt….

Ich denke, es liegt an dem Request an die Wetterstation, dass da manchmal die Anfrage etwas länger dauert oder sie gar nicht antwortet?

Das ist mir noch unklar, wie Du das genau meinst?

Als Zwischenschritt in eine Variable packen kann ich.
Aber wie frage ich auf den Fehlerfall ab?
Meinst Du, wenn die Temp 0.00 ist dann den Inhalt der Variable ausgeben?

Danke euch allen :slight_smile:

Siehe:

Das möchte ich ganz intensiv bestätigen!

Schon mal die Doku gelesen?

Da gibts einige Möglichkeiten/Wege, um auf Erfolg zu prüfen.

Genau. Nur das du floats nicht mit (aTemp == 0.00) vergleichen kannst. Aber ((aTemp < 0.1) && (aTemp > -0.1)) umgehst du die Rundungsprobleme die float so mit sich bringt.

if(doc["channel7"]["temperature"].isNull()) Serial.println("Parse Error!");

Wie verhält sich das ganze wenn "channel7" schon nicht existiert?

Nochmal eine Zwischenfrage. Ich lasse mir nun alle 2 Minuten mal den httpCode ausgeben, wenn ungleich 200 (hätte ich auch vorher schon drauf kommen können :innocent: )

11:34:32.516 -> 6.80
11:36:34.432 -> 6.80
11:38:36.210 -> -1 FEHLER! httpCode NICHT OK!
11:40:34.381 -> 6.80
11:42:36.244 -> -1 FEHLER! httpCode NICHT OK!
11:44:36.232 -> -1 FEHLER! httpCode NICHT OK!
11:46:36.550 -> -11 FEHLER! httpCode NICHT OK!
11:48:36.256 -> -1 FEHLER! httpCode NICHT OK!
11:50:31.415 -> 6.80
11:52:36.264 -> -1 FEHLER! httpCode NICHT OK!
11:54:36.264 -> -1 FEHLER! httpCode NICHT OK!
11:56:36.273 -> -1 FEHLER! httpCode NICHT OK!
11:58:36.279 -> -1 FEHLER! httpCode NICHT OK!
12:00:31.472 -> 7.00
12:02:36.296 -> -1 FEHLER! httpCode NICHT OK!

Den Code lese ich in ein INT.
Aber -1 ? Oder -11?

Was sagt mir das? Sagt euch das etwas? :thinking:

Warum lässt Du Dir nicht den HTTP-Code ausgeben?

Gruß Tommy

Ich könnte schwören, ich hätte geschrieben:

:joy: :wink:

Und wie ist dieser im Fehlerfall? Oder ist das geheim?

Gruß Tommy

Hm ich dachte das wäre klar :slightly_smiling_face:

Das sind keine http-Fehlercodes.
Was gibt

int httpCode = http.GET();

zurück?

Ich habe die Funktion nun mal umgebaut und gebe nur den HTTP Code aus:

void jsonTemp() {
  static unsigned long vorherigeMillis {0};
  if (millis() - vorherigeMillis >= INTERVALL) {
    digitalWrite(LED_BUILTIN, 1);
    http.useHTTP10(true);
    http.begin(wifiClient, "http://192.168.178.197/weather.json");
    int httpCode = http.GET();
    Serial.print(F("httpCode: "));
    Serial.println(httpCode);
    http.end();
    digitalWrite(LED_BUILTIN, 0);
    vorherigeMillis += INTERVALL;
  }
}

Ausgabe:

16:58:52.052 -> httpCode: 200
16:59:04.773 -> httpCode: 200
16:59:11.851 -> httpCode: 200
16:59:26.783 -> httpCode: -1
16:59:36.773 -> httpCode: -1
16:59:46.774 -> httpCode: -1
16:59:56.770 -> httpCode: -1
17:00:04.864 -> httpCode: 200
17:00:14.587 -> httpCode: 200
17:00:24.707 -> httpCode: 200
17:00:36.774 -> httpCode: -1
17:00:46.764 -> httpCode: -1
17:00:56.760 -> httpCode: -1
17:01:06.760 -> httpCode: -1
17:01:14.587 -> httpCode: 200
17:01:21.842 -> httpCode: 200
17:01:36.789 -> httpCode: -1
17:01:41.819 -> httpCode: 200
17:01:56.763 -> httpCode: -1
17:02:06.778 -> httpCode: -1
17:02:16.791 -> httpCode: -1
17:02:21.864 -> httpCode: 200

http.useHTTP10(true); habe ich auch schon mal auskommentiert, aber das ändert nichts...

Das liegt wohl an meiner Wetterstation oder?

Bei den -1 gibt das interne connect() HTTPC_ERROR_CONNECTION_FAILED zurück, er erreicht also den Server überhaupt nicht. Die -11 ist HTTPC_ERROR_READ_TIMEOUT für den ESP8266.
Beim ESP32 ist die -1 HTTPC_ERROR_CONNECTION_REFUSED.

Dein Webserver hat wohl einen weg.

Gruß Tommy

1 Like

Es sagt:

Parse Error!

Ja, das hoffe ich doch. Aber darf ich das machen oder greife ich da auf Speicher zu der mir nicht gehört? Hab da in der Doku nichts zu gefunden.