"Wert fällt auf 0 Problem" Gefilterter Energiesensor für IR-Lesekopf in Home Assistant

Moin zusammen,

wie ich gesehen habe stehe oder stand ich mit dem Problem, dass der Stromleser.one über MQTT in Home Assistant ab und an mal einen Zählerstand von “0” ausgibt nicht allein. Eine echte Lösung dafür habe ich hier nicht gesehen und deshalb wollte ich euch dafür einmal meinen Weg vorstellen.

Ich habe mir von der KI eine kleine Anleitung dazu schreiben lassen um es dem einen oder anderen vielleicht einfacher zu machen die Lösung nachzuvollziehen. Was ich gemacht habe ist folgendes: beide Entitäten für die Zählerstände (Exportierte und Importierte Energie) Laufen bei mir über einen Template-Sensor. Dieser akzeptiert keine Werte die kleiner sind als der Wert den der Sensor selbst hat. Somit werden alle fiktiven negativen Meldungen vom Stromleser.one ignoriert und nur ein steigender Zahlenwert wird übernommen. Diesen Template-Sensor verwende ich inzwischen seit ca. 3 Monaten ohne Probleme. Ich hoffe ich kann dem einen oder anderen damit Helfen. Vielleicht wird das Problem auch bald gefixt und damit wäre meine Lösung überflüssig.

# Gefilterter Energiesensor für IR-Lesekopf in Home Assistant

## Problem

IR-Leseköpfe am Stromzähler liefern gelegentlich fehlerhafte Werte – am häufigsten einen kurzzeitigen Rücksprung auf `0`. Da der HA-interne Energiesensor mit `state_class: total_increasing` konfiguriert ist, interpretiert Home Assistant diesen Rücksprung als echten Zählerstand. Der anschließende Sprung zurück auf den korrekten Wert erzeugt dann einen riesigen, fiktiven Verbrauchswert, der die Energie-Statistik dauerhaft zerstört.

Ein nativer HA-Mechanismus zum Filtern solcher Rücksprünge existiert nicht. Dieses Template löst das Problem.

## Voraussetzungen

- Home Assistant mit einem IR-Lesekopf-Sensor (z. B. über MQTT, ESPHome, SML-Protokoll)

- Der Quellsensor liefert den absoluten Zählerstand in **kWh**

- Zugriff auf `configuration.yaml` oder ein eingebundenes `templates.yaml`

## Funktionsweise

Der gefilterte Sensor merkt sich immer den **letzten bekannten guten Wert** in seinem eigenen State (`this.state`). Bei jeder Aktualisierung des Quellsensors wird geprüft:

- Ist der neue Wert **größer als 0**? (schließt den häufigen `0`-Fehler aus)

- Ist der neue Wert **größer oder gleich dem letzten guten Wert**? (schließt alle anderen Rücksprünge aus)

Nur wenn **beide Bedingungen** erfüllt sind, wird der neue Wert übernommen. Andernfalls bleibt der Sensor beim letzten guten Wert stehen.

Quellsensor: 100 kWh → 101 kWh → 0 kWh → 101.5 kWh → 102 kWh
Gefilterter
Sensor: 100 kWh → 101 kWh → 101 kWh → 101.5 kWh → 102 kWh

0 wurde verworfen,
101 kWh bleibt stehen

## Konfiguration

### Schritt 1: Quellsensor-ID herausfinden

In Home Assistant unter **Einstellungen → Geräte & Dienste → Entitäten** den IR-Lesekopf-Sensor suchen und die **Entitäts-ID** notieren (z. B. `sensor.mein_stromzaehler_1_8_0`).

### Schritt 2: Template-Sensor einfügen

Den folgenden Code in die `configuration.yaml` (oder eine eingebundene `templates.yaml`) einfügen. Die beiden markierten Platzhalter müssen angepasst werden:

template:

sensor:

name: „Stromzähler (Gefiltert)“

# ─────────────────────────────────────────────────────────────────

# ANPASSEN: Einen eindeutigen Bezeichner ohne Leerzeichen wählen.

# Dieser wird zur internen Entitäts-ID: sensor.<unique_id>

# Beispiel: stromzaehler_1_8_0_gefiltert

# ─────────────────────────────────────────────────────────────────

unique_id: DEINE_UNIQUE_ID_HIER

unit_of_measurement: „kWh“

device_class: energy

# total_increasing: HA erwartet einen nie fallenden Wert.

# Genau das stellt dieser Filter sicher.

state_class: total_increasing

icon: mdi:counter

state: >

{# ── Neuen Rohwert vom Quellsensor holen ──────────────────────

 ANPASSEN: sensor.DEIN_QUELLSENSOR durch die eigene Entitäts-ID

 ersetzen (siehe Schritt 1 der Anleitung).


 float(-1): Falls der Quellsensor "unknown" oder "unavailable"

 liefert, wird -1 zurückgegeben. -1 ist kleiner als jeder echte

 Zählerwert und wird durch die Filterbedingung unten sicher

 abgefangen. #}

{% set neu = states(‚sensor.DEIN_QUELLSENSOR‘) | float(-1) %}

{# ── Letzten bekannten guten Wert aus eigenem State holen ──────

 this.state enthält den zuletzt gespeicherten Wert dieses Sensors.

 | default(0) greift, wenn this.state None/undefined ist.

 | float(0) wandelt den State-String in eine Zahl um und liefert

 0 als Fallback, falls this.state "unknown" enthält. #}

{% set alt = this.state | default(0) | float(0) %}

{# Logik: Nur aktualisieren, wenn neuer Wert gültig UND größer/gleich dem alten ist #}

{# neu >= alt  → schließt Rücksprünge auf niedrigere Werte aus    #}

{# neu > 0     → schließt den häufigen 0-Fehler des IR-Kopfes aus #}

{% if neu >= alt and neu > 0 %}

{{ neu }}

{# Fallback: Filterbedingung nicht erfüllt → letzten guten Wert einfrieren.

 Der Sensor gibt alt zurück, anstatt den fehlerhaften Wert zu übernehmen. #}

{% else %}

{{ alt }}

{% endif %}

# Verfügbarkeit: Der Sensor bleibt verfügbar, auch wenn die Quelle kurz weg ist.

# Verfügbar, sobald ENTWEDER der Quellsensor einen lesbaren Wert liefert

# ODER dieser Sensor selbst noch einen gültigen State hat.

# Hinweis: Da der gefilterte Sensor immer den letzten guten Wert hält,

# ist er meist auch dann verfügbar, wenn der IR-Kopf kurz offline ist.

# Wer Ausfälle im Dashboard sehen möchte, kann diese Zeile entfernen.

availability: >

  {{ states('sensor.DEIN_QUELLSENSOR') not in \\\['unknown', 'unavailable', 'none'\\\]

  or this.state not in \\\['unknown', 'unavailable', 'none'\\\] }}

# Verfügbarkeit: Der Sensor bleibt verfügbar, auch wenn die Quelle kurz weg ist.

# Verfügbar, sobald ENTWEDER der Quellsensor einen lesbaren Wert liefert

# ODER dieser Sensor selbst noch einen gültigen State hat.

# Hinweis: Da der gefilterte Sensor immer den letzten guten Wert hält,

# ist er meist auch dann verfügbar, wenn der IR-Kopf kurz offline ist.

# Wer Ausfälle im Dashboard sehen möchte, kann diese Zeile entfernen.

availability: >

  {{ states('sensor.DEIN_QUELLSENSOR') not in \\\['unknown', 'unavailable', 'none'\\\]

  or this.state not in \\\['unknown', 'unavailable', 'none'\\\] }}

``
`

### Schritt 3: HA-Konfiguration neu laden

In Home Assistant unter **Entwicklerwerkzeuge → YAML → Template-Entitäten neu laden** (oder HA komplett neu starten).

### Schritt 4: Im Energiedashboard eintragen

Unter **Einstellungen → Energie** den neuen gefilterten Sensor (`sensor.<unique_id>`) als Netzstromverbrauch eintragen – anstelle des Quellsensors.

## Bekannte Einschränkungen

| Situation | Verhalten |

| Langer Ausfall des IR-Kopfes | Der Sensor friert beim letzten guten Wert ein und bleibt verfügbar. Das ist beabsichtigt. |

| Echter Zählerreset / Zählertausch | Den neuen Startwert manuell setzen oder den Sensor kurz deaktivieren und neu einrichten. |

## Vollständiges Beispiel (ausgefüllt)

template:
  - sensor:
      - name: "Stromzähler (Gefiltert)"
        unique_id: stromzaehler_1_8_0_gefiltert
        unit_of_measurement: "kWh"
        device_class: energy
        state_class: total_increasing
        icon: mdi:counter
        state: >
          {% set neu = states('sensor.mein_ir_lesekopf_1_8_0') | float(-1) %}
          {% set alt = this.state | default(0) | float(0) %}
          {% if neu >= alt and neu > 0 %}
            {{ neu }}
          {% else %}
            {{ alt }}
          {% endif %}
        availability: >
          {{ states('sensor.mein_ir_lesekopf_1_8_0') not in ['unknown', 'unavailable', 'none']
          or this.state not in ['unknown', 'unavailable', 'none'] }}