MQTT, JSON, Telegraf und InfluxDB

Gast #7251391
Lesenswert?

Hallo,

ich habe bei mir mehrere Sensoren (ESPs mit ESPEasy) die über MQTT Ihre 
Daten an den Broker senden. Mit Hilfe von Telegraf sammel ich diese 
Daten ein und schreibe sie in die InfluxDB.

Als Datenformat habe ich "value" mit Typ "float" konfiguriert.
(Config siehe unten)

Das funktioniert auch alles soweit.

Jetzt zu meinem Problem:
Ich möchte einen weiteren Sensor hinzufügen. Der sendet seine Daten 
allerdings im JSON Format.
Das soll Telegraf auch können, aber irgendwie bekomme ich die 
Konfiguration da nicht hin.


Ich lasse mir alle Daten die ankommen auf der Konsole ausgeben, dort 
kommt aber nur die Fehlermeldung das die JSON Daten nicht als 
"value"/"float" ausgewertet werden können.
1
[inputs.mqtt_consumer] Error in plugin: strconv.ParseFloat: parsing "07:24\",\"timestamp\":\"2022-10-15T06:19:01Z\",\"device\":\"rtlwmbus[00000001]\",\"rssi_dbm\":92}": invalid syntax]


Hat jemand eine Idee was ich falsch mache oder einen Ansatz zum weiteren 
Vorgehen?


MQTT JSON Nachricht die verarbeitet werden soll:
(die Daten werden aktuell an das Topic "test" gesendet und kommen dort 
auch an)
1
{"media":"heat cost allocation","meter":"qcaloric","name":"Bad","id":"88134838","status":"OK","current_consumption_hca":7,"set_date":"2022-05-31","consumption_at_set_date_hca":643,"set_date_1":"2022-05-31","consumption_at_set_date_1_hca":643,"error_date":"2127-15-31","device_date_time":"2022-10-15 07:24","timestamp":"2022-10-15T06:19:01Z","device":"rtlwmbus[00000001]","rssi_dbm":92}


Telegraf Config:
1
[[inputs.mqtt_consumer]]
2
  servers = ["tcp://localhost:1883"]
3
  qos = 0
4
  connection_timeout = "30s"
5
  topics = [
6
    "sensors/#",
7
    "test/#"
8
  ]
9
  persistent_session = false
10
  data_format = "value"
11
  data_type = "float"
12

13
  [[inputs.mqtt_consumer.json_v2]]
14
    data_format = "json_v2"
15
    topics = [ "test/#" ]
16
    [[inputs.mqtt_consumer.json_v2.tag]]
17
      path = "name"
18
    [[inputs.mqtt_consumer.json_v2.field]]
19
      path = "current_consumption_hca"
20
      type = "float"
#7251490
Lesenswert?

Kai schrieb:
>
1
> [inputs.mqtt_consumer] Error in plugin: strconv.ParseFloat: parsing 
2
> "07:24\",\"timestamp\":\"2022-10-15T06:19:01Z\",\"device\":\"rtlwmbus[00000001]\",\"rssi_dbm\":92}": 
3
> invalid syntax]
4
>

Ist da ein Zeilenumbruch vor "07:24"? Vielleicht ist der ja das Problem.

Edit: oh, ach ja... 07:24 ist natürlich auch kein Float, ne.
#7251541
Lesenswert?

Was sucht eigentlich der data_type="float" in der 
inputs.mqtt_consumer-Section?

BTW: Ich habe selten so eine bescheidene Doku wie bei telegraf gesehen. 
Es ist schon toll, dass es viele Beispiele gibt. Aber offensichtlich 
gibt es NUR Beispiele und keine vernünftige Beschreibung der generellen 
Syntax. Das man den ganz Kram nur immer per Trial&Error testen kann, 
machts nicht besser.
Gast #7251963
Lesenswert?

Sebastian schrieb:
> Die JSON-Nachricht scheint irgendwo "unterwegs" in zwei Fragmente
> zerlegt worden zu sein.

Ich habe die Nachricht parallel mit dem mosquitto_client mitgeschrieben, 
da kommt die Nachricht an wie oben geposted (ohne Zeilenumbruch).
Wenn die Nachricht fragmentiert wird dann sollte das an Telegraf liegen.
Leider habe ich keine Ansatz wie ich das prüfen kann.

Georg A. schrieb:
> Was sucht eigentlich der data_type="float" in der
> inputs.mqtt_consumer-Section?

Das ist der "Standardteil" für meine anderen Sensoren und nach meinem 
Verständnis ein Konkretisierung von "data_format = "value"".
Sollte der Teil anders aufgebaut sein?

Das hätte ich auch gleich schon in meinem Ursprungspost deutlicher 
schreiben können: Die Konfiguration vor dem 
"[[inputs.mqtt_consumer.json_v2]]" läuft schon seit längerem ohne 
Probleme.
Um die JSON Daten einlesen zu können habe ich den 
"[[inputs.mqtt_consumer.json_v2]]" und alles folgende neu eingefügt und 
komme seit dem nicht weiter.

Georg A. schrieb:
> BTW: Ich habe selten so eine bescheidene Doku wie bei telegraf gesehen.
> Es ist schon toll, dass es viele Beispiele gibt. Aber offensichtlich
> gibt es NUR Beispiele und keine vernünftige Beschreibung der generellen
> Syntax. Das man den ganz Kram nur immer per Trial&Error testen kann,
> machts nicht besser.

Ja leider, aber "schön" zu hören das es nicht nur mir so geht.
Dummerweise kenne ich auch keine Alternative und bisher lief es auch 
gut.
#7252060
Lesenswert?

Kai schrieb:
> Georg A. schrieb:
>> Was sucht eigentlich der data_type="float" in der
>> inputs.mqtt_consumer-Section?
>
> Das ist der "Standardteil" für meine anderen Sensoren und nach meinem
> Verständnis ein Konkretisierung von "data_format = "value"".
> Sollte der Teil anders aufgebaut sein?

Ich weiss es nicht, fehlt ja eine gescheite Doku ;) Es könnte aber dazu 
führen, dass per Default alles nach float geparst wird und dann bei 
Strings anschlägt.

Ich habe in mqtt_consumer nur das Allernötigste (server, json_v2 und 
topics) und erst in den den json_v2.fields den Namen und den Typ, den 
ich erwarte.
Gast #7253389
Lesenswert?

So, bin heute dazu gekommen etwas weiter rum zu probieren.

Georg A. schrieb:
> Was sucht eigentlich der data_type="float" in der
> inputs.mqtt_consumer-Section?
Habe die einfach mal raus genommen. Wie vermutet kommen dann die 
Tag/Value Paare nicht mehr an.


Georg A. schrieb:
> Ich habe in mqtt_consumer nur das Allernötigste (server, json_v2 und
> topics) und erst in den den json_v2.fields den Namen und den Typ, den
> ich erwarte.
Ich schließe daraus das bei Dir Daten nur im JSON Format ankommen?
Wie sieht da Deine Konfig aus?
Entspricht die diesem hier:
1
[[inputs.mqtt_consumer]]
2
  servers = ["tcp://localhost:1883"]
3
  qos = 0
4
  connection_timeout = "30s"
5
  topics = [
6
    "sensors/#",
7
    "test/#"
8
  ]
9
  persistent_session = false
10
  data_format = "json_v2"
11

12
  [[inputs.mqtt_consumer.json_v2]]
13
    topics = [ "test/#" ]
14
    [[inputs.mqtt_consumer.json_v2.tag]]
15
      path = "name"
16
    [[inputs.mqtt_consumer.json_v2.field]]
17
      path = "current_consumption_hca"
18
      type = "float"
Gast #7253393
Lesenswert?

Nils B. schrieb:
> Mir konnte auch noch niemand verständlich erklären, was genau
> Telegraf
> eigentlich macht, was nicht ein Fünfzeiler in Python auch kann.

Für mich sind es folgende Funktionen:
- Läuft als Deamon
- am MQTT Broker "lauschen" auf neue Nachrichten
- Parsen der Nachrichten (Tag/Value, JSON)
- Einspielen der Daten in die Influx DB

Ich bin leider nicht so fit in Python und beim Googlen sah das Thema 
auch nicht nach "mal eben" aus.
Solltest Du die 5 Zeilen zufällig irgendwo rumliegen haben würde ich 
mich freuen.
#7253522
Lesenswert?

Kai schrieb:
> Ich schließe daraus das bei Dir Daten nur im JSON Format ankommen?

Ja, gibt nur JSON. Das Zeug von tfrec wird in sowas verpackt:
1
Topic sensors/1a97/msg 
2
{"Id":"1a97","Time":"1668545893","Temperature":"+11.3","Humidity":"86","Battery":"0","RSSI":"79"}
Config:
1
[[inputs.mqtt_consumer]]
2
        servers = ["tcp://127.0.0.1:1883"]
3
        topics = ["sensors/#"]
4
        data_format = "json_v2"
5

6
        [[inputs.mqtt_consumer.topic_parsing]]
7
                topic = "sensors/+/msg"
8
                tags = "_/Id/_" 
9

10
        [[inputs.mqtt_consumer.json_v2]]
11
                measurement_name = "sensors"
12
                timestamp_path = "Time"
13
                timestamp_format = "unix"
14
                [[inputs.mqtt_consumer.json_v2.field]]
15
                        path = "Temperature"
16
                        type = "float"
17
                [[inputs.mqtt_consumer.json_v2.field]]
18
                        path = "Humidity"
19
                        type = "float"
20
                [[inputs.mqtt_consumer.json_v2.field]]
21
                        path = "Battery"
22
                        type = "int"
23
                [[inputs.mqtt_consumer.json_v2.field]]
24
                        path = "RSSI"
25
                        type = "int"

Hab da noch eine zweite Config für die DS18B20-Meldungen von Tasmota. Da 
habe ich es nicht geschafft, die DS18B20-* Strukturen aus dem JSON, die 
die ID und die Temperatur beinhalten, mit einem Wildcard einzulesen. Es 
wird mit path = "DS18B20-*" zwar ein Wert gelesen, aber immer nur der 
erste. Hmpf.

Rein kommt:
1
tele/tasmota_A02014/SENSOR 
2
{"Time":"2022-11-15T21:59:38",
3
"COUNTER":{"C1":28146,"C2":36963,"C3":38783},
4
"DS18B20-1":{"Id":"0000001F0D50","Temperature":24.7},
5
"DS18B20-2":{"Id":"0000001BBDC8","Temperature":22.7},
6
"DS18B20-3":{"Id":"0000001D1EAA","Temperature":22.9},
7
"DS18B20-4":{"Id":"0000001BAD55","Temperature":22.8},
8
"DS18B20-5":{"Id":"0000001E71AF","Temperature":24.1},
9
"ESP32":{"Temperature":45.6},"TempUnit":"C"}
Config dazu:
1
[[inputs.mqtt_consumer]]
2
        servers = ["tcp://127.0.0.1:1883"]
3
        data_format = "json_v2"
4
        topics = [ "tele/+/SENSOR" ]
5

6
        [[inputs.mqtt_consumer.topic_parsing]]
7
                topic =  "tele/+/SENSOR"
8

9
        [[inputs.mqtt_consumer.json_v2]]
10
                measurement_name = "sensors"
11
                [[inputs.mqtt_consumer.json_v2.object]]
12
                        path =  "DS18B20-1" 
13
                        disable_prepend_keys = true
14
                        included_keys = ["Temperature"]
15
                        tags = ["Id"]
16
                [[inputs.mqtt_consumer.json_v2.object]]
17
                        path =  "DS18B20-2" 
18
                        disable_prepend_keys = true
19
                        included_keys = ["Temperature"]
20
                        tags = ["Id"]
21
                # usw für DS18B20-3,....
Gast #7253992
Lesenswert?

Verstehe ich es richtig das zu zwei Input Blöcke 
([[inputs.mqtt_consumer]]) in deiner Konfig hast?
Einen für die Daten von tfrec und den anderen für DS18?

Das hatte ich bei mir gestern nicht ohne Fehler hinbekommen.
Aber wenn es bei Dir läuft muss ich da wohl noch mal schauen ;)
#7254775
Lesenswert?

Kai schrieb:
> Verstehe ich es richtig das zu zwei Input Blöcke
> ([[inputs.mqtt_consumer]]) in deiner Konfig hast?
> Einen für die Daten von tfrec und den anderen für DS18?

Ja, sind zwei getrennte Files in /etc/telegraf/telegraf.d. Liegt an 
dieser TOML-Syntax, dass mit dem zweiten [[inputs....]] einfach eine 
neue Instanz erzeugt wird:

https://toml.io/en/v1.0.0#array-of-tables
Gast #7259495
Lesenswert?

So, heute hatte ich wieder etwas Zeit und habe mir das angeschaut und 
die Konfiguration auf mehrere Dateien verteilt.

Es scheint jetzt zu laufen :)

Konfig für bisherige Geräte, telegraf-mqtt-input-value.conf:
1
[[inputs.mqtt_consumer]]
2
  servers = ["tcp://localhost:1883"]
3
  qos = 0
4
  connection_timeout = "30s"
5
  topics = [
6
    "sensors/#",
7
  ]
8
  persistent_session = false
9
  data_format = "value"
10
  data_type = "float"

Konfig für neuen Sensor (JSON Datenformat), 
telegraf-mqtt-input-json.conf:
1
[[inputs.mqtt_consumer]]
2
  servers = ["tcp://localhost:1883"]
3
  qos = 0
4
  connection_timeout = "30s"
5
  topics = [
6
    "sensors/+/heating/#",
7
  ]
8
  persistent_session = false
9
  data_format = "json_v2"
10

11
  [[inputs.mqtt_consumer.topic_parsing]]
12
    topic =  "sensors/+/heating/#"
13
   
14
  [[inputs.mqtt_consumer.json_v2]]
15
    [[inputs.mqtt_consumer.json_v2.tag]]
16
      path = "id"
17
    [[inputs.mqtt_consumer.json_v2.tag]]
18
      path = "name"
19
    [[inputs.mqtt_consumer.json_v2.field]]
20
      path = "current_consumption_hca"
21
      type = "float"


Das einzige Problem das ich jetzt noch habe, ist das Topic 
"sensors/+/heating/#" aus der ersten Konfig raus zu filtern.
Dort ist "sensors/#" abonniert, und da es viele unterschiedliche 
untertopics gibt würde ich lieber das eine raus filtern als alle 
aufzuführen.

Der "Metric" Filter mit namedrop scheint bei mqtt input nicht zu 
funktionieren 
(https://docs.influxdata.com/telegraf/v1.21/administration/configuration/)

Hat da jemand eine Idee?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren