ChirpStack zu Grafana: LoRaWAN-Daten visualisieren

ChirpStack mit Grafana verbinden, über InfluxDB oder TimescaleDB: die InfluxDB-Integration, der Weg über MQTT und Telegraf und eine echte Abfrage.

LoRaWAN
Architektur

Der Datenfluss

Grafana spricht kein LoRaWAN. Es liest aus einer Time-Series-Datenquelle, also besteht die eigentliche Aufgabe darin, ChirpStack-Uplinks erst in InfluxDB oder TimescaleDB zu schreiben. Dieser Guide zeigt die InfluxDB-Integration, eine Alternative über MQTT und Telegraf und eine funktionierende Grafana-Abfrage.

Sensor / Controller

Misst oder steuert vor Ort und sendet LoRaWAN-Uplinks.

LoRaWAN-Gateway

Empfängt die Funkpakete und reicht sie an den Server weiter.

ChirpStack

Network-Server: verwaltet Sessions und decodiert das Payload.

ThingsBoard / Grafana

Dashboards, Alarme, Regeln und Reports.

Warum Grafana eine Datenquelle braucht

Grafana ist eine Dashboard- und Alerting-Schicht. Es betreibt keinen LoRaWAN-Netzwerkserver und empfängt keine Uplinks. Es fragt eine Datenquelle nach Zeitplan ab und zeichnet das Ergebnis. Die Integration besteht also aus zwei Schritten: ChirpStack schreibt decodierte Uplinks in einen Time-Series-Speicher, und Grafana liest aus diesem Speicher.

Es gibt zwei gängige Speicher:

  • InfluxDB ist der kürzeste Weg, weil ChirpStack eine eingebaute InfluxDB-Integration mitbringt. Kein zusätzlicher Code.
  • PostgreSQL mit TimescaleDB passt für Teams, die schon auf PostgreSQL sind und SQL, Joins und relationale Geräte-Metadaten neben den Messwerten wollen.

Dieser Guide konzentriert sich auf den InfluxDB-Weg und zeigt danach die Alternative über MQTT und Telegraf.

Voraussetzung: ein funktionierender Payload-Codec

Die InfluxDB-Integration schreibt die Felder, die sie im decodierten object findet. Hat das Device-Profile keinen Codec, publiziert ChirpStack zwar Metadaten (RSSI, SNR, Frame-Counter), aber keine Messwerte, und deine Panels bleiben leer. Prüfe zuerst den Codec, siehe ChirpStack Payload-Decoder. Ein decodierter Uplink sieht so aus:

{
  "deviceInfo": {
    "applicationName": "cold-chain",
    "deviceProfileName": "EM300-TH",
    "deviceName": "coldroom-01",
    "devEui": "24e124136b502217"
  },
  "object": { "battery": 100, "temperature": 17.3, "humidity": 57.5 },
  "rxInfo": [{ "gatewayId": "24e124fffef54092", "rssi": -51, "snr": 13.8 }]
}

Nur die Schlüssel unter object werden zu InfluxDB-Feldern.

Schritt 1: InfluxDB-Integration aktivieren

In der ChirpStack-Application Integrations öffnen und InfluxDB hinzufügen. ChirpStack unterstützt beide InfluxDB-Versionen:

  • InfluxDB v2: API-Endpoint, Organization, Bucket und ein API-Token.
  • InfluxDB v1: Endpoint, Datenbank, Benutzername und Passwort.

Für ein v2-Setup sehen die Werte so aus:

Version:          InfluxDB v2
API endpoint:     https://influx.example.eu/api/v2/write
Organization:     merkaio
Bucket:           chirpstack
Token:            <write-token-from-influxdb>

Sobald aktiviert, wird jeder decodierte Uplink automatisch geschrieben. ChirpStack speichert die Gerätefelder als Measurements und ergänzt Tags wie die DevEUI und die Application, damit du später in Grafana pro Gerät filtern kannst.

Schritt 2: InfluxDB als Grafana-Datenquelle anlegen

In Grafana zu Connections, Data sources, Add data source, InfluxDB. Für InfluxDB v2 die Abfragesprache auf Flux stellen und die passenden Verbindungsdaten eintragen:

Query language:   Flux
URL:              https://influx.example.eu
Organization:     merkaio
Default bucket:   chirpstack
Token:            <read-token-from-influxdb>

Auf Save & test klicken und bestätigen, dass die Verbindung steht, bevor du Panels baust.

Schritt 3: Dashboard bauen

Ein Panel anlegen und das gewünschte Feld abfragen. Mit Flux nach Measurement und Feld filtern und nach dem Geräte-Tag gruppieren, damit jedes Gerät seine eigene Serie bekommt:

from(bucket: "chirpstack")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r._measurement == "device_frmpayload_data_temperature")
  |> filter(fn: (r) => r._field == "value")
  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
  |> group(columns: ["dev_eui"])

Der genaue Measurement-Name hängt von der Integrationsversion und dem decodierten Feldnamen ab; nutze den Grafana-Query-Inspector oder die InfluxDB-UI, um die echten Namen aus deinen Daten zu lesen. Von hier ergänzt du Panels für Luftfeuchte, Batterie und RSSI auf dieselbe Weise und legst Grafana-Alert-Regeln darüber.

Alternative: MQTT zu Telegraf zu InfluxDB

Wenn du eine Pipeline für viele Quellen, eigenes Tagging oder Pufferung willst, entkoppelst du die Aufnahme von ChirpStack mit Telegraf. Telegraf abonniert das ChirpStack-MQTT-Event-Topic, parst das JSON und schreibt nach InfluxDB. Eine minimale telegraf.conf:

[[inputs.mqtt_consumer]]
  servers = ["tcp://mqtt.example.eu:1883"]
  topics  = ["application/+/device/+/event/up"]
  data_format = "json_v2"

  [[inputs.mqtt_consumer.json_v2]]
    measurement_name = "chirpstack"
    [[inputs.mqtt_consumer.json_v2.tag]]
      path = "deviceInfo.devEui"
      rename = "dev_eui"
    [[inputs.mqtt_consumer.json_v2.object]]
      path = "object"
      type = "float"

[[outputs.influxdb_v2]]
  urls         = ["https://influx.example.eu"]
  token        = "$INFLUX_TOKEN"
  organization = "merkaio"
  bucket       = "chirpstack"

Achte auf den Region-Prefix: Die ChirpStack-v4-Default-Config stellt der Topic-Struktur die Region voran (z. B. eu868/application/...). Abonniert Telegraf nur application/# und ist der Prefix gesetzt, kommt nichts an. Entweder mit Prefix abonnieren oder den Prefix in der chirpstack.toml entfernen.

PostgreSQL/TimescaleDB statt InfluxDB

ChirpStack hat keine eingebaute PostgreSQL-Integration für Anwendungsdaten, dieser Weg braucht also einen kleinen Consumer: einen MQTT-Subscriber (oder einen Node-RED-artigen Flow), der jeden Uplink in ein TimescaleDB-Hypertable einfügt. Der Gewinn ist reines SQL in Grafana und einfache Joins gegen relationale Geräte-Metadaten. Der Preis ist die zusätzliche Aufnahmekomponente, die du schreiben und betreiben musst.

Stolpersteine aus der Praxis

  • Leere Panels: Fast immer ein fehlender Payload-Codec. Kein decodiertes object heißt keine InfluxDB-Felder.
  • Token-Scope: ChirpStack braucht einen Write-Token, Grafana einen Read-Token. Ein breiter Token für beides funktioniert, ist aber schlechte Hygiene.
  • Measurement-Namen: Sie entstehen aus den Feldnamen und unterscheiden sich leicht zwischen Integrationsversionen. Lies die echten Namen aus deinen Daten, statt zu raten.
  • Retention: Lege frühzeitig eine InfluxDB-Retention-Policy fest. LoRaWAN-Flotten sind pro Nachricht klein, aber unermüdlich, und unbegrenzte Buckets wachsen still.

Den ganzen Stack hosten

ChirpStack, der Time-Series-Speicher und Grafana sind drei bewegliche Teile, dazu die Codecs und Dashboards, die sie nützlich machen. Wir bauen, verdrahten und betreiben den kompletten Stack auf europäischer Infrastruktur als Teil des Grafana Managed Hosting neben dem ChirpStack Hosting, damit du Dashboards bekommst statt eines Backlogs.

Häufige Fragen

Nein. Grafana ist eine Visualisierungsschicht und liest nur aus einer Datenquelle. Du schreibst ChirpStack-Uplinks zuerst in einen Time-Series-Speicher wie InfluxDB oder PostgreSQL mit TimescaleDB und richtest Grafana dann auf diesen Speicher aus.
InfluxDB ist der schnellste Weg, weil ChirpStack eine eingebaute InfluxDB-Integration mitbringt. TimescaleDB passt für Teams, die ohnehin PostgreSQL betreiben und SQL, Joins und relationale Metadaten neben den Zeitreihen wollen.
Ja. Die Integration unterstützt InfluxDB v1 und v2. Für v2 gibst du API-Endpoint, Organization, Bucket und einen Token an; für v1 Datenbank, Benutzername und Passwort.
Die InfluxDB-Integration schreibt nur Felder aus dem decodierten object. Ohne funktionierenden Payload-Codec im Device-Profile gibt es keine numerischen Felder, nur Metadaten, und die meisten Panels bleiben leer.
Wenn du eine Pipeline für viele Quellen, eigenes Tagging oder Pufferung willst. Telegraf abonniert das ChirpStack-MQTT-Topic, parst das JSON und schreibt nach InfluxDB, was die Aufnahme von ChirpStack entkoppelt.
Ja. Wir betreiben den kompletten Stack als Managed Hosting auf europäischer Infrastruktur, inklusive Integration, Datenquelle und fertigen Dashboards. Die Datenhoheit bleibt bei dir.

Sprechen wir über Ihre Infrastruktur. Digital und vor Ort.

Ob IoT-Plattformentwicklung, Hardwareauswahl, Managed Hosting für ChirpStack, ThingsBoard, Grafana oder NetBird VPN, oder Migration von einem Self-Hosted-Setup - wir finden die passende Lösung für Ihren Anwendungsfall. Buchen Sie ein kostenloses 30-Minuten-Gespräch, unverbindlich.

Timo Wevelsiep

Ihr Ansprechpartner

Timo Wevelsiep

Gründer, merkaio

15 Minuten, unverbindlich, direkt mit Timo.

Mit dem Absenden stimmen Sie unserer Datenschutzerklärung zu.

merkaio ist unabhängiger Integrator und nicht mit Milesight affiliiert.