Feinstaubsensor-Daten direkt an Kotori schicken

Mein Feinstaubsensor soll pünktlich zum großen Feinstaub-“Fest” an Silvester auf den Balkon, bisher war er nur indoor – übrigens auch interessant, was man so drinnen an Feinstaub zusammen bekommt.

Gestern habe ich ihn bei luftdaten.info angemeldet, aber das kann einige Zeit dauern, bis er auf der Karte erscheint. Kann ich dennoch schon jetzt auf die Daten zugreifen / diese in Grafana einbinden? Ich habe ja die Sensor-ID, bringt das was? Oder muss ich warten bis der Sensor offiziell eingetragen ist?

Kann ich alternativ Daten direkt an Kotori schicken. der luftdaten.info-Sensor erlaubt es über http(s) JSON zu schicken. Kann das Kotori schon annehmen?

Wenn man die defailt-Software des Feinstaubsensor verwendet, kann man seine Daten an madavi.de senden. Sie sind dann über https://www.madavi.de/sensor/csvfiles.php?sensor=esp8266-[sensor-id] als CSV abrufbar. Die Spaltenbeschreibung gibt es unter Beschreibung Datenformat · opendata-stuttgart/meta Wiki · GitHub. “SDS_P1” ist z.B. der PM10-Wert. Alle anderen Wertebezeichnungen sind damit selbsterklären.

Ich habe die Daten um Silvester 2018 herum einmal exportiert und bei uns / Grafana wieder importiert:

https://swarm.hiveeyes.org/grafana/d/I3izGO8iz/hiveeyes-open-hive-feinstaub?orgId=2&from=1546232400000&to=1546344000000

Hi Clemens,

Einleitung

die für die Madavi Schnittstelle notwendige Sensor ID kommt leider aus einer anderen Domäne als die der Live API von luftdaten.info, von der die Daten über die Luftdatenpumpe bezogen werden können.

Madavi Sensor ID

Nehmen wir mal als Beispiel die Madavi Sensor ID “10042531”:
https://www.madavi.de/sensor/csvfiles.php?sensor=esp8266-10042531

luftdaten.info Sensor ID

Die Sensor IDs der Live API sehen so in der Art aus:

# Display metadata for given sensors in JSON format
luftdatenpumpe stations --sensor=657,2130 --reverse-geocode

Per Abfrage der höchsten Sensor ID bekommt man heraus, dass die höchste Sensor ID aus dieser Domäne 19744 beträgt.

$ http 'https://api.luftdaten.info/static/v1/data.json' | jq 'max_by(.sensor.id) | .sensor.id'
19744

Die höchste Location ID ist wiederum:

$ http 'https://api.luftdaten.info/static/v1/data.json' | jq 'max_by(.location.id) | .location.id'
10029

Fehlende Konkordanz?

Leider finde ich in den CSV Dateien unter https://www.madavi.de/sensor/csvfiles.php?sensor=esp8266-10042531 keinen Verweis auf die Sensor-ID von luftdaten.info. Diese CSV Dateien sind auch anders strukturiert als die unter archive.luftdaten.info. Letztere können ebenfalls durch die Luftdatenpumpe verarbeitet werden, erstere erhalten leider keinerlei Informationen über location.id oder station.id. Im Vergleich:

Viele Grüße,
Andreas.

1 Like

Kannst Du Deinen Sensor vielleicht schon irgendwo hier auf der Karte identifizieren?
http://opendata-stuttgart.github.io/feinstaub-map/#13/52.4754/13.3470

https://www.madavi.de/sensor/graph.php?sensor=esp8266-[sensor-id]-sds011 sagt immer noch, dass der Sensor nicht bei luftdaten.info eingetragen ist. :-(

Dann ist das ja plausibel, das Dein Gerät in diesem Netzwerk noch keine entsprechenden Identifizierer besitzt. Und nun? Mehr Geduld aufbringen oder Supportanfrage stellen?

Hier übrigens auch noch ein interessanter Vermerk zur Nomenklatur:

[…] kann der Sensor nach ca. 10 Minuten auf den folgenden Seiten ‚getestet‘ werden. Gesucht werden muss auf diesen Seiten nach der ChipID (im Bespiel oben die 13597771).

Sensor Community

Das was wir als Madavi Sensor ID bezeichnet haben, heißt also in Wahrheit ChipID, wenn ich das richtig interpretiere. Eine Location ID sowie eine Sensor ID bekommen die Geräte demzufolge erst innerhalb der Datenbank des luftdaten.info Netzwerks.

Danke der Nachfrage, das fände ich ebenfalls interessant. Dazu sollten wir folgendes herausfinden:
a) Ist die Zielurl, an die vermutlich ein HTTP POST Request abgesetzt wird, frei konfigurierbar?
b) Wie sieht ein typischer Payload im JSON Format aus, wie es der Meßknoten (vermutlich) absenden würde?

Der Quelltext der airrohr-firmware.ino könnte auf diese Fragen Antworten liefern.

Ja, wird glaube ich aus dem ESP generiert, daher ChipID, ist aber quasi der Identifier bei Madavi. Wobei “Sensor” auch irreführend sein kann, weil ja das komplette “air rohr” als Sensor bezeichnet wird.

Das ist auch in der Tat die chip id des ESP32:

String esp_chipid = String(ESP.getChipId());

sensors-software/airrohr-firmware/airrohr-firmware.ino at master · opendata-stuttgart/sensors-software · GitHub


ESP.getChipId() im Espressif SDK

In der Dokumentation findet sich:

ESP.getChipId() returns the ESP8266 chip ID as a 32-bit integer.

Libraries » ESP-specific APIs

Hier findet sich auch noch etwas dazu:

So ist es, s.o.

Ja, in der Dokumentation wird dieser Identifizierer aber korrekt als ChipID benannt. Sensor IDs (aka. sensor_id) gibt es dann im luftdaten.info Netzwerk.

Pro Meßknoten (aka. location_id bzw. station_id) meist sogar mehrere, wie hier am Beispiel zu sehen:

$ luftdatenpumpe readings --station=9506

Ergebnis:

[
    {
        "station": {
            "station_id": 9506,
            "sensor_id": 18754,
            "sensor_type": "SDS011",
            "position": {
                "latitude": 47.664,
                "longitude": 9.166,
                "altitude": 401.4,
                "country": "DE",
                "geohash": "u0qx0sfqzm8f"
            }
        },
        "data": {
            "time": "2019-01-04T19:26:11Z",
            "P1": 10.1,
            "P2": 7.03
        }
    },
    {
        "station": {
            "station_id": 9506,
            "sensor_id": 18755,
            "sensor_type": "DHT22",
            "position": {
                "latitude": 47.664,
                "longitude": 9.166,
                "altitude": 401.4,
                "country": "DE",
                "geohash": "u0qx0sfqzm8f"
            }
        },
        "data": {
            "time": "2019-01-04T19:26:12Z",
            "humidity": 75.4,
            "temperature": 3.9
        }
    }
]

Ja!

## Sending to madavi.de: 
Start connecting to api-rrd.madavi.de
Requesting URL: /data.php
120xxxxx
{"software_version": "NRZ-2018-123B", "sensordatavalues":[{"value_type":"SDS_P1","value":"9.23"},{"value_type":"SDS_P2","value":"6.70"},{"value_type":"BME280_temperature","value":"4.58"},{"value_type":"BME280_humidity","value":"70.99"},{"value_type":"BME280_pressure","value":"102467.53"},{"value_type":"samples","value":"312108"},{"value_type":"min_micro","value":"81"},{"value_type":"max_micro","value":"244084"},{"value_type":"signal","value":"-64"}]}

closing connection
1 Like

Sehr schön, danke! Nun wäre die Frage, ob derselbe Payload verschickt wird, falls man “An eigene API senden” auswählt.

Davon gehe ich aus, unter “An eigene API senden” APIs · opendata-stuttgart/meta Wiki · GitHub wird zu diesem PHP decode-code verlinkt:

Exzellent, danke! Ich gehe davon aus, dass SSL/TLS nicht möglich sein wird?

Trage doch einfach einmal folgende Adresse ein:

http://swarm.hiveeyes.org/api-notls/hiveeyes/testdrive/luftdaten.info/test-01/data

bzw. folgendermaßen auf die Felder verteilt:

Server: swarm.hiveeyes.org
Pfad:   /api-notls/hiveeyes/testdrive/luftdaten.info/test-01/data
Port:   80

Es wird zwar vermutlich noch nicht funktionieren, aber vielleicht demnächst. Merci schon im Voraus!

Bei API Luftdaten.info und API Madavi.de auf der config-Seite ist HTTPS möglich. Für die “eigene API” geht das nicht, bzw. gibt es keinen Konfigurationspunkt in der GUI.

Config habe ich geändert, sendet momentan alle 240 Sekunden

An eigene API senden: 1
Server: swarm.hiveeyes.org
Pfad: /api-notls/hiveeyes/testdrive/luftdaten.info/test-01/data
Port: 80

Sehr schön, vielen Dank. Hier gerade live aufgefangen:

root@elbanco:~# ngrep -Wbyline -d lo host localhost and port 24642
interface: lo (127.0.0.0/255.0.0.0)
filter: (ip or ip6) and ( host localhost and port 24642 )

Anfrage

T 127.0.0.1:54488 -> 127.0.0.1:24642 [AP]
POST /api/hiveeyes/testdrive/luftdaten.info/test-01/data HTTP/1.0.
Host: swarm.hiveeyes.org.
Connection: close.
Content-Length: 479.
Content-Type: application/json.
X-PIN: 0.
X-Sensor: esp8266-12041741.
.
{"esp8266id": "12041741", "software_version": "NRZ-2018-123B", "sensordatavalues":[{"value_type":"SDS_P1","value":"9.20"},{"value_type":"SDS_P2","value":"6.30"},{"value_type":"BME280_temperature","value":"4.39"},{"value_type":"BME280_humidity","value":"72.34"},{"value_type":"BME280_pressure","value":"102467.77"},{"value_type":"samples","value":"3105949"},{"value_type":"min_micro","value":"73"},{"value_type":"max_micro","value":"33159"},{"value_type":"signal","value":"-66"}]}

Antwort

T 127.0.0.1:24642 -> 127.0.0.1:54488 [AP]
HTTP/1.0 200 OK.
Date: Sun, 06 Jan 2019 22:56:37 GMT.
Channel-Id: /hiveeyes/testdrive/luftdaten.info/test-01.
Content-Type: application/json.
Server: TwistedWeb/17.1.0.
.
[
    {
        "message": "Received #1 readings",
        "type": "info"
    }
]

"Received #1 readings" stimmt hier natürlich noch nicht!

Eine entsprechendes Signal erhält man auch im Log und über den Fehlerkanal:

umwelt/testdrive/luftdaten.info/test-01/error.json {
    "timestamp": "2019-01-09T02:27:06+00:00",
    "message": "400: {\"error\":\"unable to parse 'luftdaten_info_test_01_sensors esp8266id=12041741.0,sensordatavalues=[{u'value_type': u'SDS_P1', u'value': u'0.40'}, {u'value_type': u'SDS_P2', u'value': u'0.30'}, {u'value_type': u'BME280_temperature', u'value': u'3.93'}, {u'value_type': u'BME280_humidity', u'value': u'86.77'}, {u'value_type': u'BME280_pressure', u'value': u'99608.41'}, {u'value_type': u'samples', u'value': u'2987203'}, {u'value_type': u'min_micro', u'value': u'78'}, {u'value_type': u'max_micro', u'value': u'26377'}, {u'value_type': u'signal', u'value': u'-68'}],software_version=\\\"NRZ-2018-123B\\\"': invalid boolean\"}\n",
    "type": "<class 'influxdb.exceptions.InfluxDBClientError'>",
    "description": "Error processing MQTT message \"{\"esp8266id\": 12041741.0, \"sensordatavalues\": [{\"value_type\": \"SDS_P1\", \"value\": \"0.40\"}, {\"value_type\": \"SDS_P2\", \"value\": \"0.30\"}, {\"value_type\": \"BME280_temperature\", \"value\": \"3.93\"}, {\"value_type\": \"BME280_humidity\", \"value\": \"86.77\"}, {\"value_type\": \"BME280_pressure\", \"value\": \"99608.41\"}, {\"value_type\": \"samples\", \"value\": \"2987203\"}, {\"value_type\": \"min_micro\", \"value\": \"78\"}, {\"value_type\": \"max_micro\", \"value\": \"26377\"}, {\"value_type\": \"signal\", \"value\": \"-68\"}], \"software_version\": \"NRZ-2018-123B\"}\" from topic \"umwelt/testdrive/luftdaten.info/test-01/data.json\"."
}
1 Like

Das könnte u.U. doch klappen, indem man "Port: 443" einträgt:

Versuche doch einmal folgende Adresse:

Server: weather.hiveeyes.org
Pfad:   /api/umwelt/testdrive/luftdaten.info/test-01/data
Port:   443

Danke!

1 Like

done

An eigene API senden: 1
Server: weather.hiveeyes.org
Pfad: /api/umwelt/testdrive/luftdaten.info/test-01/data
Port: 443

Klappt auch. Danke!

1 Like

Hatte vor ein paar Tagen dann – neben der Sensor-Anmeldung über das Formular auf der Website – nochmal eine Mail geschickt, mit der Bitte meinen Sensor nachzutragen, ist aber immer noch nicht erfolgt, sagt der Link oben.