Erschließung der HTTP-Datenexportschnittstelle via Arduino

Einleitung

Bei Anzeige der Daten auf einem e-Paper Display wollen wir ein e-Paper Display mit imkerlichen Daten füttern. Hier soll es darum gehen, wie wir an die Daten über HTTP per Arduino rankommen.

Exzellent! Bei HTTP data export for Arduino findest Du eine Steilvorlage dazu, wie Du an die imkerlichen Daten rankommst, wenn Du Arduino verwendest. Die Code-Beispiele sind daran angelehnt, wie derzeit auch GitHub - G6EJD/ESP32-e-Paper-Weather-Display: An ESP32 and 2.9", 4.2" or 7.5" ePaper Display reads Weather Underground data via their API and then displays the weather die Wetterdaten abholt.

Egal ob mit Arduino oder MicroPython – für eine effizientere Abfrage der Daten sollten wir der Export-Schnittstelle von Kotori noch die Möglichkeit beibringen, nur den letzten/aktuellsten Datensatz auszugeben.

3 Likes

Leider komme ich beim einfügen des Kontori Beispielcodes nicht wirklich weiter.
Die http-Abfrage gibt mir immer ein

Connection failed, error: 04d

aus. Leider bin ich mir nicht sicher, was dieser Fehlercode genau bedeutet.

versucht, habe ich es dem Beispiel entsprechend mit /api-notls/ und mit /api/ aktuell bin ich bei

https://swarm.hiveeyes.org/api/hiveeyes/testdrive/area-38/fipy-workbench-01/data.json?include=weight.0,temperature.0x77.i2c:0,humidity.0x77.i2c:0,temperature.28ff641d8fc3944f.onewire:0,temperature.28ff641d8fdf18c1.onewire:0&from=now-10m

was mir im Browser auch eine recht übersichtliche .json Datei ausgibt.
Die selbe Anfrage mit /api-notls gibt übrigens ein

405 Method Not Allowed 

aus.

Die .json von openweathermap.org schauen übrigens so aus.
weather.json (463 Bytes) forecast.json (14,3 KB)

Hmm, kann die swarm.hiveeyes-API überhaupt unverschlüsselt? Kannst du die Abfrage oben per https nicht nutzen oder was ist da das Problem?

Stimmt, daran hab ich gar nicht gedacht. Hatte mich auf den Fehlercode: 04b fixiert und dabei gar nicht an die Verschlüsselung gedacht.
Werde werde heute Abend versuchen ob ich http get auch mit Verschlüsselung zum laufen bekomme. Wie ich das kenne, wird es wohl nicht reichen hier einfach Port 443 zu wählen oder?

53: http.begin(client, server, 80, uri);

Edit: wie es gehen sollte hab ich schon hier gefunden.

Das passiert nur, wenn man die /api-notls-URL mit https:// anspricht. Per http://swarm.hiveeyes.org/api-notls/ funktioniert es wie gewünscht:

http 'http://swarm.hiveeyes.org/api-notls/hiveeyes/testdrive/area-38/fipy-workbench-01/data.json?include=weight.0,temperature.0x77.i2c:0,humidity.0x77.i2c:0,temperature.28ff641d8fc3944f.onewire:0,temperature.28ff641d8fdf18c1.onewire:0&from=now-1m'
HTTP/1.1 200 OK
Channel-Id: /hiveeyes/testdrive/area-38/fipy-workbench-01
Connection: keep-alive
Content-Disposition: inline; filename=testdrive_area_38_fipy_workbench_01_20200525T133954_20200525T134054.json
Content-Type: application/json; charset=utf-8
Date: Mon, 25 May 2020 13:40:54 GMT
Server: nginx/1.10.3
Target-Address-Scheme: influxdb
Target-Address-Uri: hiveeyes_testdrive
Target-Database: hiveeyes_testdrive
Target-Expression: SELECT * FROM area_38_fipy_workbench_01_sensors WHERE time >= '2020-05-25 13:39:54.260' AND time <= '2020-05-25 13:40:54.268';
Transfer-Encoding: chunked
[
    {
        "humidity.0x77.i2c:0": 49.82338,
        "temperature.0x77.i2c:0": 19.45848,
        "temperature.28ff641d8fc3944f.onewire:0": 16.625,
        "temperature.28ff641d8fdf18c1.onewire:0": 19.5625,
        "time": "2020-05-25T13:39:57.780Z",
        "weight.0": 0.974
    },
    {
        "humidity.0x77.i2c:0": 49.82868,
        "temperature.0x77.i2c:0": 19.46161,
        "temperature.28ff641d8fc3944f.onewire:0": 16.625,
        "temperature.28ff641d8fdf18c1.onewire:0": 19.5625,
        "time": "2020-05-25T13:40:13.070Z",
        "weight.0": 0.977
    },
    {
        "humidity.0x77.i2c:0": 49.84942,
        "temperature.0x77.i2c:0": 19.46036,
        "temperature.28ff641d8fc3944f.onewire:0": 16.5,
        "temperature.28ff641d8fdf18c1.onewire:0": 19.5625,
        "time": "2020-05-25T13:40:28.357Z",
        "weight.0": 0.976
    },
    {
        "humidity.0x77.i2c:0": 49.839,
        "temperature.0x77.i2c:0": 19.45973,
        "temperature.28ff641d8fc3944f.onewire:0": 16.5,
        "temperature.28ff641d8fdf18c1.onewire:0": 19.5625,
        "time": "2020-05-25T13:40:43.641Z",
        "weight.0": 0.975
    }
]
1 Like

Das ist seltsam, hier sollte laut

eigentlich eine bessere Fehlermeldung herauskommen, siehe

Gib doch auch mal zusätzlich den HTTP response status code per Serial.println(httpCode); aus.

Irgendwas ist komisch, wenn ich per Konsole

http 'http://swarm.hiveeyes.org/api-notls/hiveeyes/testdrive/area-38/fipy-workbench-01/data.json?include=weight.0,temperature.0x77.i2c:0,humidity.0x77.i2c:0,temperature.28ff641d8fc3944f.onewire:0,temperature.28ff641d8fdf18c1.onewire:0&from=now-1m'

aufrufe, dann funktioniert es, im browser (akuteller FF) gibt es mit URL-Eingabe in der Adresszeile von

http://swarm.hiveeyes.org/api-notls/hiveeyes/testdrive/area-38/fipy-workbench-01/data.json?include=weight.0,temperature.0x77.i2c:0,humidity.0x77.i2c:0,temperature.28ff641d8fc3944f.onewire:0,temperature.28ff641d8fdf18c1.onewire:0&from=now-1m

einen automatischen redirect zu https (sic!)

https://swarm.hiveeyes.org/api-notls/hiveeyes/testdrive/area-38/fipy-workbench-01/data.json?include=weight.0,temperature.0x77.i2c:0,humidity.0x77.i2c:0,temperature.28ff641d8fc3944f.onewire:0,temperature.28ff641d8fdf18c1.onewire:0&from=now-1m

und damit ein 405

Method Not Allowed

Your browser approached me (at /api-notls/hiveeyes/testdrive/area-38/fipy-workbench-01/data.json?include=weight.0,temperature.0x77.i2c:0,humidity.0x77.i2c:0,temperature.28ff641d8fc3944f.onewire:0,temperature.28ff641d8fdf18c1.onewire:0&from=now-1m) with the method “GET”. I only allow the method HEAD here.

Lustig, Chrome leitet auch zu https um, Chromium und Edge nicht, da passt es! Server-Einstellungen??

Ja, so ist es. Das passiert wegen

$ http https://swarm.hiveeyes.org/ --print h | grep Strict
Strict-Transport-Security: max-age=15768000

und weil sich der Browser das merkt, wenn man die Seite damit bereits einmal per HTTPS besucht hat. Da darf man einfach nicht drauf hereinfallen.

1 Like

P.S.: Ich habe gerade noch das Beispiel hiveeyes_client.h aktualisiert. Da von der Export-Schnittstelle eine Liste von Datensätzen zurückkommt, muss das erste Element adressiert werden:

1 Like

Dieser Fehler ist weg.

Natürlich kommt gleich der Nächste.

serializeJson() failed: InvalidInput

konnte diesen flott aber mit:

http.useHTTP10(true);

wegbekommen.

jetzt bekomme ich zwar keine Fehlermeldung, aber auch leider keine Werte.
Habe es wie in der common.h bei WxForecast versucht.


bool decode_data(WiFiClient& json) {
 
  // Allocate the JsonDocument
  DynamicJsonDocument doc(35 * 1024);

  // Deserialize the JSON document.
  DeserializationError error = deserializeJson(doc, json);

  // Test if parsing succeeds.
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return false;
  }

  // Convert to JsonObject.
  JsonObject root = doc.as<JsonObject>();
  Serial.println(" Decoding hiveeyes data");
  // Decode data.
  JsonArray list                  = root["list"];
  for (byte r = 0; r < max_readings; r++) {
    Serial.println("\nPeriod-" + String(r) + "--------------");
    hive_data[r].time                   = list[r]["time"];
    hive_data[r].temperature_outside    = list[r]["temperature.0x77.i2c:0"];
    hive_data[r].humidity_outside       = list[r]["humidity.0x77.i2c:0"];
    hive_data[r].temperature_inside_1   = list[r]["temperature.28ff641d8fc3944f.onewire:0"];
    hive_data[r].temperature_inside_2   = list[r]["temperature.28ff641d8fdf18c1.onewire:0"];
    hive_data[r].weight                 = list[r]["weight.0"];
    Serial.println("time: "+String(hive_data[r].time));
    Serial.println("temperature_outside: "+String(hive_data[r].temperature_outside));
    Serial.println("humidity_outside: "+String(hive_data[r].humidity_outside));
    Serial.println("temperature_inside_1: "+String(hive_data[r].temperature_inside_1));
    Serial.println("temperature_inside_2 "+String(hive_data[r].temperature_inside_2));
    Serial.println("weight: "+String(hive_data[r].weight));
  }                             
  return true;
}

Ausgabe über Seriellen Monitor=

Connection to sever: swarm.hiveeyes.org/api-notls/hiveeyes/testdrive/area-38/fipy-workbench-01/data.json?
Connection to Hiveeyes OK 
Decoding hiveeyes data...

Period-0--------------
time: 0.00
temperature_outside: 0.00
humidity_outside: 0.00
temperature_inside_1: 0.00
temperature_inside_2 0.00
weight: 0.00

Period-1--------------
time: 0.00
temperature_outside: 0.00
humidity_outside: 0.00
temperature_inside_1: 0.00
temperature_inside_2 0.00
weight: 0.00

Period-2--------------
time: 0.00
temperature_outside: 0.00
humidity_outside: 0.00
temperature_inside_1: 0.00
temperature_inside_2 0.00
weight: 0.00

Period-3--------------
time: 0.00
temperature_outside: 0.00
humidity_outside: 0.00
temperature_inside_1: 0.00
temperature_inside_2 0.00
weight: 0.00
...

Werde ich nachher auch nochmal probieren.
Eine Liste zu erhalten ist aber sicher auch nicht verkehrt, um Graphen oder Alarme zu generieren.

Jetzt aber erstmal die Kid´s ins Bett bringen.

2 Likes

Mit dem vorliegenden Code passt das nicht:

Es gibt kein Element “list”. root ist direkt die Liste. Also entweder:

JsonArray list = root;

oder

JsonArray list = root.as<JsonArray>();

oder eben (nicht getestet) wie bei:

1 Like

Hat leider beides nicht funktioniert, gab bereits beim kompilieren Fehlermeldungen.
hab es jetzt aber doch irgendwie hin bekommen, die Daten zu bekommen.

Ich muß aber die Schleife noch abbrechen, wenn keine Daten mehr kommen.
und den Time String noch in eine echte Zeit umbauen.

bool decode_data(WiFiClient& json) {

  // Allocate the JsonDocument
  DynamicJsonDocument doc(35 * 1024);
  // Deserialize the JSON document.
  DeserializationError error = deserializeJson(doc, json);
  // Test if parsing succeeds.
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return false;
  }
  // Convert to JsonObject.
  // Decode data.
 
  for (byte r = 0; r < max_readings; r++) {
    JsonObject root = doc[r]
    Serial.println("\nPeriod-" + String(r) + "--------------");
   
    hive_data[r].time                   = root["time"].as<char*>();
    hive_data[r].temperature_outside    = root["temperature.0x77.i2c:0"];
    hive_data[r].humidity_outside       = root["humidity.0x77.i2c:0"];
    hive_data[r].temperature_inside_1   = root["temperature.28ff641d8fc3944f.onewire:0"];
    hive_data[r].temperature_inside_2   = root["temperature.28ff641d8fdf18c1.onewire:0"];
    hive_data[r].weight                 = root["weight.0"];

    Serial.println("time: "+hive_data[r].time);
    Serial.println("temperature_outside: "+String(hive_data[r].temperature_outside));
    Serial.println("humidity_outside: "+String(hive_data[r].humidity_outside));
    Serial.println("temperature_inside_1: "+String(hive_data[r].temperature_inside_1));
    Serial.println("temperature_inside_2 "+String(hive_data[r].temperature_inside_2));
    Serial.println("weight: "+String(hive_data[r].weight));
  }                             
  return true;
}

Ausgabe:

Period-1--------------
time: 2020-05-20T00:00:25.627Z
temperature_outside: 18.88
humidity_outside: 44.89
temperature_inside_1: 15.88
temperature_inside_2 18.62
weight: 0.99

Period-2--------------
time: 2020-05-20T00:00:40.919Z
temperature_outside: 18.89
humidity_outside: 44.86
temperature_inside_1: 15.88
temperature_inside_2 18.62
weight: 0.99

Period-3--------------
time: 2020-05-20T00:00:56.232Z
temperature_outside: 18.89
humidity_outside: 44.88
temperature_inside_1: 15.75
temperature_inside_2 18.62
weight: 0.99

Period-4--------------
time: 2020-05-20T00:01:11.490Z
temperature_outside: 18.88
humidity_outside: 44.88
temperature_inside_1: 15.75
temperature_inside_2 18.62
weight: 0.99

Period-5--------------
time: 2020-05-20T00:01:26.786Z
temperature_outside: 18.88
humidity_outside: 44.89
temperature_inside_1: 15.75
temperature_inside_2 18.62
weight: 0.99

Period-6--------------
time: 2020-05-20T00:01:42.070Z
temperature_outside: 18.87
humidity_outside: 44.88
temperature_inside_1: 15.75
temperature_inside_2 18.62
weight: 1.00

Period-7--------------
time: 2020-05-20T00:01:57.383Z
temperature_outside: 18.88
humidity_outside: 44.89
temperature_inside_1: 15.75
temperature_inside_2 18.62
weight: 0.99

Period-8--------------
time: 2020-05-20T00:02:12.651Z
temperature_outside: 18.88
humidity_outside: 44.91
temperature_inside_1: 15.75
temperature_inside_2 18.62
weight: 0.99

Period-9--------------
time: 2020-05-20T00:02:27.942Z
temperature_outside: 18.88
humidity_outside: 44.91
temperature_inside_1: 15.75
temperature_inside_2 18.62
weight: 0.99

Period-10--------------
time: 2020-05-20T00:02:43.235Z
temperature_outside: 18.88
humidity_outside: 44.90
temperature_inside_1: 15.75
temperature_inside_2 18.62
weight: 0.99

Period-11--------------
time: 2020-05-20T00:02:58.515Z
temperature_outside: 18.87
humidity_outside: 44.91
temperature_inside_1: 15.75
temperature_inside_2 18.62
weight: 0.99

Period-12--------------

temperature_outside: 0.00
humidity_outside: 0.00
temperature_inside_1: 0.00
temperature_inside_2 0.00
weight: 0.00
...
1 Like

Hab es leider auch noch nicht geschafft zu testen, allerdings müsste JsonObject first = doc[0]; auf den ersten übertragenen und somit ältesten Datensatz vom Array verweisen.
Gibt es so etwas wie JsonObject first = doc[last];

1 Like

3 posts were merged into an existing topic: Anzeige der Daten auf einem e-Paper Display