Abonnieren von Topics mit dem MQTT-Collector
Der MQTT-Collector kann Nachrichten von verschiedenen (beliebig vielen) Topics abonnieren, verarbeiten und dann in die InfluxDB schreiben. Dazu dienen Zuordnungen („Mappings”). Jedes Mapping legt drei Dinge fest:
- Wo kommt der Wert her, also welches Topic muss abonniert werden?
- Welche Verarbeitung ist notwendig (Vorzeichen-Behandlung, Datentyp-Konvertierung, JSON-Extraktion, Formelbildung)?
- Wohin in der InfluxDB soll der ermittelte Wert geschrieben werden (Measurement und Field)?
Jedes Mapping wird durch mehrere Umgebungsvariablen definiert, die mit dem Präfix MAPPING_X_ beginnen. X ist eine Zahl, und alle Variablen mit derselben Zahl gehören zum selben Mapping. Die Nummerierung beginnt bei 0 und läuft lückenlos weiter.
Verfügbare Umgebungsvariablen je Mapping
Abschnitt betitelt „Verfügbare Umgebungsvariablen je Mapping“Pflicht sind nur MAPPING_X_TOPIC und MAPPING_X_TYPE. Dazu kommt das Ziel in der InfluxDB, und dafür gibt es zwei Varianten:
- Der Normalfall:
MAPPING_X_MEASUREMENTundMAPPING_X_FIELD. Dort landet der Wert, ob positiv oder negativ. - Die Vorzeichen-Aufteilung:
MAPPING_X_MEASUREMENT_POSITIVE,MAPPING_X_MEASUREMENT_NEGATIVE,MAPPING_X_FIELD_POSITIVEundMAPPING_X_FIELD_NEGATIVE. Der Wert landet je nach Vorzeichen in einem von zwei Feldern, etwa Netzbezug und Einspeisung.
MAPPING_X_TOPIC
Abschnitt betitelt „MAPPING_X_TOPIC“Das Topic, das der Collector abonniert. Mehrere Mappings dürfen dasselbe Topic verwenden, etwa um aus einem JSON-Payload mehrere Werte zu gewinnen.
MAPPING_0_TOPIC=senec/0/ENERGY/GUI_INVERTER_POWERMAPPING_X_TYPE
Abschnitt betitelt „MAPPING_X_TYPE“Der Datentyp des Feldes. Erlaubt sind integer, float, string und boolean. Jeder andere Wert lässt den Collector beim Start abbrechen.
Bei boolean gelten true, ok, yes, on und 1 als wahr, unabhängig von Groß- und Kleinschreibung. Jeder andere Wert wird zu false.
MAPPING_0_TYPE=floatMAPPING_X_MEASUREMENT
Abschnitt betitelt „MAPPING_X_MEASUREMENT“Pflicht, solange das Mapping die Werte nicht nach Vorzeichen aufteilt. Der Name des InfluxDB-Measurements, in das der Wert geschrieben werden soll (unabhängig davon, ob er positiv oder negativ ist).
MAPPING_0_MEASUREMENT=PVMAPPING_X_FIELD
Abschnitt betitelt „MAPPING_X_FIELD“Pflicht, solange das Mapping die Werte nicht nach Vorzeichen aufteilt. Der Name des InfluxDB-Feldes, in das der Wert geschrieben werden soll (unabhängig davon, ob er positiv oder negativ ist).
MAPPING_0_FIELD=inverter_powerMAPPING_X_MEASUREMENT_POSITIVE
Abschnitt betitelt „MAPPING_X_MEASUREMENT_POSITIVE“Pflicht, sobald das Mapping die Werte nach Vorzeichen aufteilt. Name des InfluxDB-Measurements, in das der Wert geschrieben werden soll, wenn er positiv ist. Andernfalls (also wenn er negativ oder 0 ist) wird 0 geschrieben.
MAPPING_1_MEASUREMENT_POSITIVE=PVMAPPING_X_MEASUREMENT_NEGATIVE
Abschnitt betitelt „MAPPING_X_MEASUREMENT_NEGATIVE“Pflicht, sobald das Mapping die Werte nach Vorzeichen aufteilt. Der Name des InfluxDB-Measurements, in das der (absolute) Wert geschrieben werden soll, wenn er negativ ist. Andernfalls (also wenn er positiv oder 0 ist) wird 0 geschrieben.
MAPPING_1_MEASUREMENT_NEGATIVE=PVMAPPING_X_FIELD_POSITIVE
Abschnitt betitelt „MAPPING_X_FIELD_POSITIVE“Pflicht, sobald das Mapping die Werte nach Vorzeichen aufteilt. Name des InfluxDB-Feldes, in das der Wert geschrieben werden soll, wenn er positiv ist. Andernfalls (also wenn er negativ oder 0 ist) wird 0 geschrieben.
MAPPING_1_FIELD_POSITIVE=grid_import_powerMAPPING_X_FIELD_NEGATIVE
Abschnitt betitelt „MAPPING_X_FIELD_NEGATIVE“Pflicht, sobald das Mapping die Werte nach Vorzeichen aufteilt. Der Name des InfluxDB-Feldes, in das der (absolute) Wert geschrieben werden soll, wenn er negativ ist. Andernfalls (also wenn er positiv oder 0 ist) wird 0 geschrieben.
MAPPING_1_FIELD_NEGATIVE=grid_export_powerMAPPING_X_JSON_KEY
Abschnitt betitelt „MAPPING_X_JSON_KEY“Der Schlüssel, aus dem der Wert extrahiert wird, falls das Topic einen JSON-Payload enthält (mit nicht verschachtelten Key/Value-Paaren). Ein Schlüssel ist immer ein String, z.B. inverter_power. Ohne die Variable verarbeitet der Collector den Payload als nackten Wert.
MAPPING_2_JSON_KEY=radiation_levelMAPPING_X_JSON_PATH
Abschnitt betitelt „MAPPING_X_JSON_PATH“Der JSONPath, mit dem der Wert extrahiert wird, falls das Topic einen komplexen (z.B. verschachtelten) JSON-Payload enthält. Ein JSONPath beginnt immer mit $., z.B. $.example.foo.bar[2].
Sind JSON_PATH und JSON_KEY gleichzeitig gesetzt, gewinnt JSON_PATH. Der Collector meldet das nicht, deshalb gehört immer nur eines von beiden ins Mapping.
MAPPING_3_JSON_PATH=$.ccp[2]MAPPING_X_JSON_FORMULA
Abschnitt betitelt „MAPPING_X_JSON_FORMULA“Eine Formel, die aus einem JSON-Payload den zu speichernden Messwert berechnet. Sie darf einige mathematische Operationen enthalten, z.B. round({radiation_level} * 1.5).
Die geschweiften Klammern {} dienen dazu, Werte aus dem JSON-Payload zu referenzieren. Es können dabei einfache Schlüssel oder JSONPath verwendet werden. Die Formel wirkt nur, wenn weder JSON_KEY noch JSON_PATH gesetzt ist. Diese beiden haben Vorrang.
MAPPING_4_JSON_FORMULA=round({reactivity} * {radiation_level}) + 42MAPPING_X_FORMULA
Abschnitt betitelt „MAPPING_X_FORMULA“Eine Formel für Topics ohne JSON, also mit nacktem Wert. Verfügbar ab Version 0.5.0. Der empfangene Wert wird über den Platzhalter {value} referenziert, z.B. round({value} * 1000). Es gelten dieselben Operationen wie bei JSON_FORMULA.
Die Formel wirkt nur, wenn weder JSON_KEY noch JSON_PATH noch JSON_FORMULA gesetzt ist. Alle drei haben Vorrang.
MAPPING_4_FORMULA=round({value} * 1000)MAPPING_X_MIN
Abschnitt betitelt „MAPPING_X_MIN“Unterer Grenzwert für Messwerte, verfügbar ab Version 0.3.0. Wird ein Wert unterhalb dieses Grenzwerts empfangen, wird er ignoriert und nicht in die InfluxDB geschrieben. Damit lassen sich Ausreißer ausfiltern, die sonst die Statistik verfälschen. Ohne die Variable gibt es keine untere Grenze.
Der Grenzwert greift erst nach JSON-Extraktion und Formel, also auf dem Wert, der tatsächlich gespeichert würde.
MAPPING_0_MIN=5MAPPING_X_MAX
Abschnitt betitelt „MAPPING_X_MAX“Oberer Grenzwert für Messwerte, verfügbar ab Version 0.3.0. Wird ein Wert oberhalb dieses Grenzwerts empfangen, wird er ignoriert und nicht in die InfluxDB geschrieben. Ohne die Variable gibt es keine obere Grenze.
Beide Grenzwerte wirken nur bei den Typen float und integer. Bei string und boolean bleiben sie ohne Effekt.
MAPPING_0_MAX=15000MAPPING_X_NULL_TO_ZERO
Abschnitt betitelt „MAPPING_X_NULL_TO_ZERO“Wandelt einen Messwert von NULL in die Zahl 0 um und schreibt ihn nach InfluxDB. Verfügbar ab Version 0.7.0. Erlaubt sind true und false, jeder andere Wert lässt den Collector beim Start abbrechen. Standardwert ist false.
Bei false wird ein Messwert von NULL ignoriert, also nicht nach InfluxDB geschrieben. Das gilt auch, wenn zwar ein Payload ankommt, der konfigurierte JSON-Schlüssel darin aber fehlt.
MAPPING_3_NULL_TO_ZERO=trueBeispiele
Abschnitt betitelt „Beispiele“1. Einfaches Mapping
Abschnitt betitelt „1. Einfaches Mapping“Topic wird abonniert, der erhaltene Wert wird unverändert als Fließkommazahl in die InfluxDB geschrieben:
MAPPING_0_TOPIC=senec/0/ENERGY/GUI_INVERTER_POWERMAPPING_0_MEASUREMENT=PVMAPPING_0_FIELD=inverter_powerMAPPING_0_TYPE=float2. Mapping mit Vorzeichen-Behandlung
Abschnitt betitelt „2. Mapping mit Vorzeichen-Behandlung“Wenn die Werte des Topics positiv oder negativ sein können, erfolgt hier eine Aufteilung. Positive Werte werden in grid_import_power geschrieben, negative Werte in grid_export_power.
MAPPING_1_TOPIC=senec/0/ENERGY/GUI_GRID_POWMAPPING_1_MEASUREMENT_POSITIVE=PVMAPPING_1_MEASUREMENT_NEGATIVE=PVMAPPING_1_FIELD_POSITIVE=grid_import_powerMAPPING_1_FIELD_NEGATIVE=grid_export_powerMAPPING_1_TYPE=float- Falls der empfangene Wert positiv ist (z.B.
1000):grid_import_powerwird auf1000gesetzt,grid_export_powerauf0. - Falls der empfangene Wert negativ ist (z.B.
-500):grid_import_powerwird auf0gesetzt,grid_export_powerauf500. - Falls der empfangene Wert
0ist:grid_import_powerundgrid_export_powerwerden beide auf0gesetzt.
3. Mapping mit einfachem JSON-Payload
Abschnitt betitelt „3. Mapping mit einfachem JSON-Payload“Verwendung von JSON_KEY:
MAPPING_2_TOPIC=my/little/nuclear/plantMAPPING_2_JSON_KEY=radiation_levelMAPPING_2_MEASUREMENT=nuclear_power_plantMAPPING_2_FIELD=radiation_levelMAPPING_2_TYPE=floatAus einem JSON von beispielsweise {"radiation_level": 90.5, "reactivity": 0.7} resultiert der Wert 90.5.
4. Mapping mit komplexem JSON-Payload
Abschnitt betitelt „4. Mapping mit komplexem JSON-Payload“Verwendung von JSON_PATH:
MAPPING_3_TOPIC=go-e/ATTRMAPPING_3_JSON_PATH=$.ccp[2]MAPPING_3_MEASUREMENT=WALLBOXMAPPING_3_FIELD=powerMAPPING_3_TYPE=floatMAPPING_3_NULL_TO_ZERO=trueDies extrahiert den Wert aus einem Payload wie {"ccp": [1,2,42,3]}. Im Beispiel liefert das den Wert an Position 2 (drittes Element) des Arrays ccp, also 42.
Sollte der Wert null sein (z.B. bei {"ccp": [1,2,null,3]}), wird er als 0 geschrieben.
5. Mapping mit Formel
Abschnitt betitelt „5. Mapping mit Formel“Es gibt zwei Möglichkeiten, eine Formel zu verwenden:
a) Bei JSON-Payload
Abschnitt betitelt „a) Bei JSON-Payload“MAPPING_4_TOPIC=my/little/nuclear/plantMAPPING_4_JSON_FORMULA="round({reactivity} * {radiation_level}) + 42"MAPPING_4_MEASUREMENT=nuclear_power_plantMAPPING_4_FIELD=danger_levelMAPPING_4_TYPE=floatAus einem JSON von z.B. {"radiation_level": 90.5, "reactivity": 0.7} entsteht danger_level mit round(0.7 * 90.5) + 42, also 105.
b) Bei String-Payload
Abschnitt betitelt „b) Bei String-Payload“MAPPING_4_TOPIC=my/little/nuclear/plant/powerInKwHMAPPING_4_FORMULA="round({value} * 1000)"MAPPING_4_MEASUREMENT=nuclear_power_plantMAPPING_4_FIELD=powerMAPPING_4_TYPE=integerIm Gegensatz zum JSON-Fall wird hier der Wert über {value} referenziert und die Variable heißt MAPPING_X_FORMULA.
Aus einem Payload von z.B. 42.5 entsteht power mit round(42.5 * 1000), also 42500.
6. Mapping mit Grenzwerten
Abschnitt betitelt „6. Mapping mit Grenzwerten“MAPPING_0_TOPIC=senec/0/ENERGY/GUI_INVERTER_POWERMAPPING_0_MEASUREMENT=PVMAPPING_0_FIELD=inverter_powerMAPPING_0_TYPE=floatMAPPING_0_MIN=5MAPPING_0_MAX=15000Werte unter 5 oder über 15000 werden ignoriert und nicht in die InfluxDB geschrieben.