Zum Inhalt springen

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.

Ein Mapping muss kein Topic abonnieren. Ab Version 0.8.0 kann es seinen Wert auch aus anderen Mappings berechnen, siehe Berechnete Werte. Und es muss nicht jede empfangene Nachricht einzeln in die InfluxDB schreiben, siehe Weniger Schreibzugriffe.

Pflicht ist MAPPING_X_TYPE, dazu MAPPING_X_TOPIC, solange das Mapping seinen Wert nicht berechnet. Dazu kommt das Ziel in der InfluxDB, und dafür gibt es zwei Varianten:

  • Der Normalfall: MAPPING_X_MEASUREMENT und MAPPING_X_FIELD. Dort landet der Wert, ob positiv oder negativ.
  • Die Vorzeichen-Aufteilung: MAPPING_X_MEASUREMENT_POSITIVE, MAPPING_X_MEASUREMENT_NEGATIVE, MAPPING_X_FIELD_POSITIVE und MAPPING_X_FIELD_NEGATIVE. Der Wert landet je nach Vorzeichen in einem von zwei Feldern, etwa Netzbezug und Einspeisung.

Pflicht, solange das Mapping seinen Wert nicht aus anderen Mappings berechnet. Das Topic, das der Collector abonniert. Mehrere Mappings dürfen dasselbe Topic verwenden, etwa um aus einem JSON-Payload mehrere Werte zu gewinnen.

Ein Mapping ohne Topic ist ein berechnetes und bezieht seinen Wert aus einer Formel. Mindestens ein Mapping mit Topic muss es geben, sonst beendet sich der Collector beim Start mit der Meldung „No mappings defined”.

Beispiel
MAPPING_0_TOPIC=senec/0/ENERGY/GUI_INVERTER_POWER

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.

Beispiel
MAPPING_0_TYPE=float

Pflicht, solange das Mapping die Werte nicht nach Vorzeichen aufteilt und nicht nur im Speicher bleibt. Der Name des InfluxDB-Measurements, in das der Wert geschrieben werden soll (unabhängig davon, ob er positiv oder negativ ist).

Beispiel
MAPPING_0_MEASUREMENT=PV

Pflicht, solange das Mapping die Werte nicht nach Vorzeichen aufteilt und nicht nur im Speicher bleibt. Der Name des InfluxDB-Feldes, in das der Wert geschrieben werden soll (unabhängig davon, ob er positiv oder negativ ist).

Beispiel
MAPPING_0_FIELD=inverter_power

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.

Beispiel
MAPPING_1_MEASUREMENT_POSITIVE=PV

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.

Beispiel
MAPPING_1_MEASUREMENT_NEGATIVE=PV

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.

Beispiel
MAPPING_1_FIELD_POSITIVE=grid_import_power

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.

Beispiel
MAPPING_1_FIELD_NEGATIVE=grid_export_power

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.

Beispiel
MAPPING_2_JSON_KEY=radiation_level

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.

Beispiel
MAPPING_3_JSON_PATH=$.ccp[2]

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.

Beispiel
MAPPING_4_JSON_FORMULA=round({reactivity} * {radiation_level}) + 42

Eine Formel, die den zu speichernden Wert berechnet. Verfügbar ab Version 0.5.0. Was sie berechnet, hängt davon ab, ob das Mapping ein Topic abonniert:

  • Mit Topic: Die Formel rechnet mit der empfangenen Nachricht, also mit einem Topic ohne JSON. Der empfangene Wert wird über den Platzhalter {value} referenziert, z.B. round({value} * 1000). Ein anderer Platzhalter ist hier nicht erlaubt. Seit Version 0.8.0 startet der Collector nicht, wenn die Formel den Namen eines anderen Mappings nennt.
  • Ohne Topic: Die Formel rechnet mit den Werten anderer Mappings, die über ihren MAPPING_X_NAME referenziert werden, z.B. {house_power} - {wallbox_power}. Näheres unter Berechnete Werte.

Es gelten dieselben Operationen wie bei JSON_FORMULA, dazu die Vergleiche ==, !=, >, <, >=, <= und die Funktion IF(). Eine Formel, die nur aus einem Vergleich besteht, liefert true oder false und braucht deshalb MAPPING_X_TYPE=boolean.

Bei einem Mapping mit Topic wirkt die Formel nur, wenn weder JSON_KEY noch JSON_PATH noch JSON_FORMULA gesetzt ist. Alle drei haben Vorrang.

Beispiel
MAPPING_4_FORMULA=round({value} * 1000)

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.

Beispiel
MAPPING_0_MIN=5

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.

Beispiel
MAPPING_0_MAX=15000

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.

Beispiel
MAPPING_3_NULL_TO_ZERO=true

Ein Mapping ohne MAPPING_X_TOPIC abonniert nichts, sondern berechnet seinen Wert aus anderen Mappings. Verfügbar ab Version 0.8.0. Es braucht dazu eine MAPPING_X_FORMULA, die mindestens ein anderes Mapping über dessen MAPPING_X_NAME referenziert. Sonst verhält es sich wie jedes andere Mapping: Datentyp, Grenzwerte und Ziel in der InfluxDB gelten unverändert.

Gerechnet wird, sobald eine Nachricht einen der referenzierten Werte ändert. Das Ergebnis schreibt der Collector wie einen empfangenen Messwert. Ein typischer Fall ist die Grundlast, also der Hausverbrauch ohne die großen Verbraucher:

MAPPING_15_MEASUREMENT=Household
MAPPING_15_FIELD=base_load
MAPPING_15_TYPE=integer
MAPPING_15_FORMULA="{house_power} - {wallbox_power} - {heatpump_power}"

Referenziert wird immer über den Namen, nie über die Nummer des Mappings. Die Nummer verschiebt sich, sobald ein Mapping davor dazukommt oder wegfällt, der Name bleibt. Aus demselben Grund spielt die Reihenfolge in der Konfiguration keine Rolle. Der Collector bringt die berechneten Mappings selbst in die Reihenfolge, in der sie sich ausrechnen lassen.

Berechnete Werte lassen sich verketten, ein berechnetes Mapping darf also ein anderes referenzieren. Voraussetzung ist auch dort ein MAPPING_X_NAME. Führt eine Formel auf sich selbst zurück, startet der Collector nicht, ebenso wenig bei einem Namen, den kein Mapping trägt.

Solange ein referenzierter Wert noch nie eingetroffen ist oder sein Höchstalter überschritten hat, wird nicht gerechnet und nichts geschrieben. Das Protokoll nennt dann die fehlende Referenz und den Grund:

Formula for base_load could not be evaluated
(wallbox_power [senec/0/WALLBOX/APPARENT_CHARGING_POWER/0]: last received 145s ago, exceeds MAX_AGE of 300s), ignoring.

Die Warnung erscheint einmal je Situation, nicht bei jeder Nachricht.

Mit MAPPING_X_NULL_TO_ZERO schreibt das Mapping in diesem Fall 0. Diese 0 ist ein echter Wert: Sie landet in der InfluxDB, und jede Formel rechnet mit ihr weiter. Zusammen mit einem Höchstalter entsteht daraus eine falsche Null statt der beabsichtigten Lücke, deshalb passen die beiden nicht zusammen.

Der Name, unter dem die Formel eines anderen Mappings diesen Wert liest, z.B. {wallbox_power}. Verfügbar ab Version 0.8.0. Erlaubt sind Kleinbuchstaben, Ziffern und Unterstriche, wobei das erste Zeichen keine Ziffer sein darf. value ist reserviert, denn so heißt der Platzhalter der empfangenen Nachricht. Jeder Name darf nur einmal vorkommen. Ohne die Variable bleibt der Wert für Formeln unsichtbar.

Nötig ist der Name nur, wenn eine Formel den Wert liest. Er ist außerdem Voraussetzung für MAPPING_X_MAX_AGE und MAPPING_X_SKIP_WRITE. Einen Verstoß gegen diese Regeln meldet der Collector beim Start, und er startet nicht.

Beispiel
MAPPING_1_NAME=wallbox_power

Höchstalter des Werts in Sekunden, eine ganze Zahl größer als 0. Verfügbar ab Version 0.8.0. Ist der zuletzt empfangene Wert älter, gilt er in Formeln als unbekannt. Ohne die Variable altert er nie. Die Variable setzt MAPPING_X_NAME voraus, sonst startet der Collector nicht.

Das Höchstalter betrifft nur die Verwendung in Formeln, nicht das Schreiben des Werts selbst. Fällt ein Sensor aus, wird das berechnete Mapping nicht mehr geschrieben. In der Auswertung entsteht eine sichtbare Lücke statt einer Zahl aus veralteten Daten. Über eine Kette vererbt sich das: Ein berechneter Wert ist so alt wie der älteste Wert, aus dem er entstanden ist. Die Mappings dazwischen brauchen deshalb kein eigenes Höchstalter.

Beispiel
MAPPING_1_MAX_AGE=300

Hält den Wert nur im Speicher, statt ihn in die InfluxDB zu schreiben. Verfügbar ab Version 0.8.0. Erlaubt sind true und false, jeder andere Wert lässt den Collector beim Start abbrechen. Standardwert ist false.

Bei true steht der Wert weiterhin den Formeln und dem Höchstalter zur Verfügung, bekommt aber kein eigenes Measurement und Field. Das passt, wenn nur das Rechenergebnis in der Datenbank landen soll. MAPPING_X_NAME ist dann Pflicht, denn ohne Namen könnte keine Formel den Wert lesen. Zusammen mit MAPPING_X_DEDUP=true oder MAPPING_X_AGGREGATE_INTERVAL bricht der Collector ab, denn die beiden steuern ein Schreiben, das hier nicht stattfindet.

Beispiel
MAPPING_1_SKIP_WRITE=true

Im Normalfall schreibt der Collector jede empfangene Nachricht in die InfluxDB. Bei einem Topic, das mehrmals pro Sekunde sendet, entstehen dabei mehr Datenpunkte, als eine Auswertung braucht. Zwei Variablen ab Version 0.8.0 verringern die Zahl der Schreibzugriffe: MAPPING_X_AGGREGATE_INTERVAL mittelt die Werte eines Zeitfensters, MAPPING_X_DEDUP schreibt nur Änderungen.

Beide reagieren ausschließlich auf eintreffende Nachrichten. Bleibt der Sender stumm, schreibt der Collector weder einen Mittelwert noch ein Lebenszeichen, und die Lücke bleibt sichtbar.

Auf die Berechnung wirkt beides nicht. Eine Formel und das Höchstalter sehen weiterhin jeden einzelnen empfangenen Wert, auch wenn er nie in der InfluxDB landet.

Beide Variablen lassen sich kombinieren. Der Collector mittelt zuerst und vergleicht danach, MAPPING_X_DEDUP sieht also die Mittelwerte und nicht die einzelnen Nachrichten.

Länge des Zeitfensters in Sekunden, über das der Collector die empfangenen Werte mittelt, eine ganze Zahl größer als 0. Verfügbar ab Version 0.8.0. Geschrieben wird dann nur der Mittelwert. Ohne die Variable landet jeder empfangene Wert einzeln in der InfluxDB. Erlaubt ist sie nur bei MAPPING_X_TYPE=integer oder float, denn nur Zahlen lassen sich mitteln.

Das Fenster beginnt mit dem ersten Wert und startet nach jedem Schreibvorgang neu. Geschrieben wird also im Abstand des Intervalls, solange Werte eintreffen, und nicht nach der Uhr. Bei einer Aufteilung nach Vorzeichen mittelt der Collector vor der Aufteilung, damit die beiden Felder zusammenpassen.

Beispiel
MAPPING_5_AGGREGATE_INTERVAL=60

Schreibt einen Wert nur, wenn er sich vom zuletzt geschriebenen unterscheidet. Verfügbar ab Version 0.8.0. Erlaubt sind true und false, jeder andere Wert lässt den Collector beim Start abbrechen. Standardwert ist false.

Eine Änderung geht sofort in die InfluxDB. Ein wiederholter Wert wird zurückgehalten und erst nach MAPPING_X_HEARTBEAT_INTERVAL Sekunden erneut geschrieben, damit sich „unverändert” von „Sender ausgefallen” unterscheiden lässt. Das gilt auch für eine wiederholte 0, denn bei den meisten Sensoren ist das ein normaler Zustand. Jedes Feld wird für sich betrachtet, bei einer Aufteilung nach Vorzeichen halten sich die beiden Felder also nicht gegenseitig auf.

Wie viel das spart, hängt vom Sensor ab. Ein Zustand oder ein Gerät im Leerlauf wiederholt sich exakt. Ein Messwert, der um einen Wert herum rauscht, tut das nicht. Dort lässt MAPPING_X_TYPE=integer das Rauschen wegfallen, während float fast jeden Wert durchlässt. Der Datentyp gehört allerdings festgelegt, bevor das Feld seinen ersten Wert bekommt: InfluxDB behält den Typ eines Feldes bei und lehnt einen anderen später ab.

Beispiel
MAPPING_6_DEDUP=true

Abstand in Sekunden, in dem ein unveränderter Wert trotz MAPPING_X_DEDUP erneut geschrieben wird, eine ganze Zahl größer als 0. Verfügbar ab Version 0.8.0. Standardwert ist 60. Die Variable setzt MAPPING_X_DEDUP=true voraus, sonst startet der Collector nicht.

Zusammen mit MAPPING_X_AGGREGATE_INTERVAL muss das Lebenszeichen länger sein als das Mittelungsfenster, denn es kann nur gemeinsam mit einem Mittelwert hinausgehen. Ist es kürzer oder gleich lang, wird jeder Mittelwert geschrieben und die Entdopplung bleibt wirkungslos. Der Collector warnt beim Start und läuft weiter. Sinnvoll ist ein Vielfaches des Mittelungsfensters, denn zwischen zwei Mittelwerten liegt das Fenster plus der Abstand zweier Nachrichten.

Beispiel
MAPPING_6_HEARTBEAT_INTERVAL=300

Topic wird abonniert, der erhaltene Wert wird unverändert als Fließkommazahl in die InfluxDB geschrieben:

MAPPING_0_TOPIC=senec/0/ENERGY/GUI_INVERTER_POWER
MAPPING_0_MEASUREMENT=PV
MAPPING_0_FIELD=inverter_power
MAPPING_0_TYPE=float

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_POW
MAPPING_1_MEASUREMENT_POSITIVE=PV
MAPPING_1_MEASUREMENT_NEGATIVE=PV
MAPPING_1_FIELD_POSITIVE=grid_import_power
MAPPING_1_FIELD_NEGATIVE=grid_export_power
MAPPING_1_TYPE=float
  • Falls der empfangene Wert positiv ist (z.B. 1000): grid_import_power wird auf 1000 gesetzt, grid_export_power auf 0.
  • Falls der empfangene Wert negativ ist (z.B. -500): grid_import_power wird auf 0 gesetzt, grid_export_power auf 500.
  • Falls der empfangene Wert 0 ist: grid_import_power und grid_export_power werden beide auf 0 gesetzt.

Verwendung von JSON_KEY:

MAPPING_2_TOPIC=my/little/nuclear/plant
MAPPING_2_JSON_KEY=radiation_level
MAPPING_2_MEASUREMENT=nuclear_power_plant
MAPPING_2_FIELD=radiation_level
MAPPING_2_TYPE=float

Aus einem JSON von beispielsweise {"radiation_level": 90.5, "reactivity": 0.7} resultiert der Wert 90.5.

Verwendung von JSON_PATH:

MAPPING_3_TOPIC=go-e/ATTR
MAPPING_3_JSON_PATH=$.ccp[2]
MAPPING_3_MEASUREMENT=WALLBOX
MAPPING_3_FIELD=power
MAPPING_3_TYPE=float
MAPPING_3_NULL_TO_ZERO=true

Dies 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.

Es gibt zwei Möglichkeiten, eine Formel zu verwenden:

MAPPING_4_TOPIC=my/little/nuclear/plant
MAPPING_4_JSON_FORMULA="round({reactivity} * {radiation_level}) + 42"
MAPPING_4_MEASUREMENT=nuclear_power_plant
MAPPING_4_FIELD=danger_level
MAPPING_4_TYPE=float

Aus einem JSON von z.B. {"radiation_level": 90.5, "reactivity": 0.7} entsteht danger_level mit round(0.7 * 90.5) + 42, also 105.

MAPPING_4_TOPIC=my/little/nuclear/plant/powerInKwH
MAPPING_4_FORMULA="round({value} * 1000)"
MAPPING_4_MEASUREMENT=nuclear_power_plant
MAPPING_4_FIELD=power
MAPPING_4_TYPE=integer

Im 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.

MAPPING_0_TOPIC=senec/0/ENERGY/GUI_INVERTER_POWER
MAPPING_0_MEASUREMENT=PV
MAPPING_0_FIELD=inverter_power
MAPPING_0_TYPE=float
MAPPING_0_MIN=5
MAPPING_0_MAX=15000

Werte unter 5 oder über 15000 werden ignoriert und nicht in die InfluxDB geschrieben.

Zwei Mappings tragen einen Namen, ein drittes rechnet damit. Es hat kein Topic:

MAPPING_0_TOPIC=senec/0/ENERGY/GUI_HOUSE_POW
MAPPING_0_MEASUREMENT=PV
MAPPING_0_FIELD=house_power
MAPPING_0_TYPE=integer
MAPPING_0_NAME=house_power
MAPPING_1_TOPIC=senec/0/WALLBOX/APPARENT_CHARGING_POWER/0
MAPPING_1_MEASUREMENT=PV
MAPPING_1_FIELD=wallbox_power
MAPPING_1_TYPE=integer
MAPPING_1_NAME=wallbox_power
MAPPING_1_MAX_AGE=300
MAPPING_2_MEASUREMENT=Household
MAPPING_2_FIELD=base_load
MAPPING_2_TYPE=integer
MAPPING_2_FORMULA="{house_power} - {wallbox_power}"

Sobald einer der beiden Werte eintrifft, berechnet der Collector base_load neu und schreibt ihn. Meldet sich die Wallbox länger als 300 Sekunden nicht, bleibt base_load ungeschrieben, und im Dashboard entsteht eine Lücke.

Soll nur die Grundlast in der InfluxDB landen, bekommen die beiden Quell-Mappings ein MAPPING_X_SKIP_WRITE=true. Ihre Werte bleiben dann im Speicher, und MAPPING_X_MEASUREMENT und MAPPING_X_FIELD entfallen dort.

Ein Topic sendet mehrmals pro Sekunde. Statt jeder einzelnen Nachricht landet einmal pro Minute deren Mittelwert in der InfluxDB:

MAPPING_5_TOPIC=my/fast-changing/power
MAPPING_5_MEASUREMENT=METER
MAPPING_5_FIELD=power
MAPPING_5_TYPE=float
MAPPING_5_AGGREGATE_INTERVAL=60

Ein Leck-Sensor meldet im Sekundentakt denselben Zustand. In die InfluxDB soll aber nur die Änderung, dazu alle 300 Sekunden ein Lebenszeichen:

MAPPING_6_TOPIC=my/leak-sensor/state
MAPPING_6_MEASUREMENT=Leak
MAPPING_6_FIELD=detected
MAPPING_6_TYPE=boolean
MAPPING_6_DEDUP=true
MAPPING_6_HEARTBEAT_INTERVAL=300

Wechselt der Wert von false auf true, steht er sofort in der InfluxDB. Bleibt er gleich, überspringt ihn der Collector und schreibt ihn erst nach 300 Sekunden wieder. An dieser Wiederholung ist in der Auswertung zu erkennen, dass der Sensor noch sendet und nicht ausgefallen ist.