AI-on-the-edge liest meinen mechanischen Wasserzähler zuverlässig per Kamera aus – meistens. Einzelne OCR-Fehlablesungen wie 288 → 0 → 121 → 288 haben mir allerdings die Langzeitstatistik in Home Assistant zerlegt. Deshalb sitzt jetzt ein Plausibilitätsfilter zwischen Rohdaten und Energy Dashboard.
Die Ausgangslage
AI-on-the-edge liefert bei mir zwei Werte:
sensor.watermeter_main_value
sensor.watermeter_sub_value
Der Main-Wert enthält die ganzen Kubikmeter, der Sub-Wert die drei Nachkommastellen. Aus 288 und 732 wird damit 288,732 m³.
Warum ein einfacher Filter nicht reicht
Der Sub-Wert läuft regulär von 000 bis 999. Ein Rücksprung des Sub-Werts ist daher beim Überlauf völlig korrekt:
288.998
288.999
289.000
289.001
Gefiltert werden muss deshalb der zusammengesetzte Gesamtzählerstand – mit zusätzlichen Plausibilitätsregeln.
Die Regeln
- Der Gesamtzähler darf niemals rückwärts laufen.
- Der Main-Wert darf nicht kleiner werden und maximal um 2 m³ springen.
- Der Sub-Wert muss zwischen 000 und 999 liegen.
- Der Überlauf 999 → 000 bleibt erlaubt.
- Pro Messung werden maximal 0,100 m³ bzw. 100 Liter zusätzlicher Verbrauch akzeptiert.
- Ungültige Messungen werden verworfen; der letzte gültige Wert bleibt stehen.
Home Assistant Package
Die Logik liegt nicht in meiner großen configuration.yaml, sondern in einem eigenen Package:
/homeassistant/packages/watermeter.yaml
Packages werden einmalig eingebunden:
homeassistant:
packages: !include_dir_named packages
Rohwert zusammensetzen
template:
- sensor:
- name: "Watermeter Raw Total"
unique_id: watermeter_raw_total
unit_of_measurement: "m³"
device_class: water
state_class: total_increasing
icon: mdi:water
state: >
{% set main = states('sensor.watermeter_main_value') | int(none) %}
{% set sub = states('sensor.watermeter_sub_value') | int(none) %}
{% if main is not none and sub is not none and 0 <= sub <= 999 %}
{{ (main + (sub / 1000)) | round(3) }}
{% else %}
{{ none }}
{% endif %}
Bereinigten Sensor erzeugen
- trigger:
- platform: homeassistant
event: start
- platform: state
entity_id:
- sensor.watermeter_main_value
- sensor.watermeter_sub_value
- platform: time_pattern
minutes: "/5"
sensor:
- name: "Watermeter Clean"
unique_id: watermeter_clean
unit_of_measurement: "m³"
device_class: water
state_class: total_increasing
icon: mdi:water-check
state: >
{% set main = states('sensor.watermeter_main_value') | int(none) %}
{% set sub = states('sensor.watermeter_sub_value') | int(none) %}
{% set old = this.state | float(none) %}
{% if main is none or sub is none %}
{{ old }}
{% elif sub < 0 or sub > 999 %}
{{ old }}
{% else %}
{% set new = main + (sub / 1000) %}
{% if old is none or old <= 0 %}
{{ new | round(3) }}
{% else %}
{% set old_main = old | int %}
{% set delta = new - old %}
{% if main >= old_main
and main <= old_main + 2
and delta >= 0
and delta <= 0.100 %}
{{ new | round(3) }}
{% else %}
{{ old }}
{% endif %}
{% endif %}
{% endif %}
Was passiert bei einem Ausreißer?
| AI-on-the-edge RAW | Watermeter Clean | Bewertung |
|---|---|---|
| 288.732 | 288.732 | ✓ gültig |
| 288.735 | 288.735 | ✓ +3 Liter |
| 121.500 | 288.735 | ✗ Rücksprung |
| 0.000 | 288.735 | ✗ Rücksprung |
| 288.740 | 288.740 | ✓ wieder plausibel |
Energy Dashboard
Im Energy Dashboard verwende ich ab der Umstellung ausschließlich sensor.watermeter_clean als Wasserverbrauch. Einen separaten Durchflusssensor brauche ich nicht. Die von AI-on-the-edge gelieferten Rate-Werte können bei einer OCR-Fehlablesung ebenfalls extreme Werte erzeugen.
Fazit
Die Kamera darf sich weiterhin einmal verlesen. Entscheidend ist, dass eine einzelne Fehlmessung nicht mehr ungeprüft in der Langzeitstatistik landet. AI-on-the-edge liefert die Rohdaten, Home Assistant prüft deren Plausibilität und Watermeter Clean wird zur vertrauenswürdigen Quelle für Dashboard und Statistik.
