Ausreisser und nicht nachvollziehbare, falsche neue state-Werte beim Versuch, die Ausreißer abzufangen

Hallo,

kurze Vorstellung und Einleitung:
seit etwas mehr als 1 Jahr beschäftige ich mich mit HA. Nachdem das Projekt länger ruhen musste und dann auch noch die DB korrupt war, habe ich im Januar mit einer frischen Instanz nochmal neu angefangen. Bislang nutze ich HA noch wenig für Steuerungen, sondern für die Werteerfassung / Statistiken. Dafür habe ich viele Entitäten in der configuration.yaml angelegt. Im Prinzip funktioniert das auch, aber…

Ich habe sehr häufige Ausreißer - nicht nur bei nachfolgender Entität für den Gesamtertrag PV alt, sondern bei sehr vielen Entitäten, die in der configuration.yaml definiert sind. Manche ergeben sich dadurch, dass neue Entitäten aus anderen berechnet werden, z.B. Gesamtertrag PV aus den Erträgen PV alt und PV neu.
Nachfolgende Entität für den Gesamtertrag PV alt steht nur stellvertretend für das grundsätzliche Problem.

Ausgangslage:
Ein Sensor liefert den Zählerstand für PV alt und hatte am 09.08.2026 um 10:30 Uhr den Wert

sensor.bitshake_smartmeterreader_ertrag_pv_alt = 6866.38

Daraus liefert folgende Entity den tatsächlichen Gesamtwert für PV alt:

# Entität für den Gesamtertrag PV alt

- sensor:
  - name: Gesamtertrag PV alt (mit Langzeitkorrektur)
    unique_id: gesamtertrag_pv_alt
    device_class: Energy
    state_class: total_increasing
    unit_of_measurement: “kWh”
    state: “{{ states(‘sensor.bitshake_smartmeterreader_ertrag_pv_alt’) | float(2)  + 56120.32 | float(2) }}”

Das liefert korrekt

sensor.gesamtertrag_pv_alt = 62986.7

und funktioniert seit längerem auch grundsätzlich. wenn sensor.bitshake_smartmeterreader_ertrag_pv_alt steigt, dann steigt auch sensor.gesamtertrag_pv_alt um denselben Betrag.

Aber: Es entstehen regelmäßig, zu oft, um das bei allen betroffenen Entitäten händisch korrigieren zu können, extreme Ausreißer von mehreren tausend bis zehntausend kWh (meist nach oben, teilweise aber auch negative).

Ansatz um die Ausreißer abzufangen:

# Entität für den Gesamtertrag PV alt

- sensor:
  - name: Gesamtertrag PV alt (mit Langzeitkorrektur)
    unique_id: gesamtertrag_pv_alt
    device_class: Energy
    state_class: total_increasing
    unit_of_measurement: “kWh”
    # neu wegen ständiger Ausreißer
    # nachfolgende Bedingung behält den alten Wert bei, wenn der neue Wert
    # a) kleiner ist als der alte Wert
    # b) mehr als 0,5 größer ist
    state: >
      {% set neuer_wert = states(‘sensor.bitshake_smartmeterreader_ertrag_pv_alt’) | float(2) + 56120.32 | float(2) %}
      {% set alter_wert = states(‘sensor.gesamtertrag_pv_alt’) | float(2) %}
      {% set differenz = neuer_wert - alter_wert %}
      {% if 0 < differenz <= 0.5 %}
        {{neuer_wert}}
      {% else %}
        {{alter_wert}}
      {% endif %}

Das liefert dann nur noch

gesamtertrag_pv_alt = 2.0

Da aber unmittelbar davoch noch

gesamtertrag_pv_alt = 62986.7

war, ist das vollkommen aus der Luft gegriffen und nicht nachvollziehbar. Der Wert von sensor.bitshake_smartmeterreader_ertrag_pv_alt steigt weiterhin völlig korrekt.

Angenommen der neue Wert ist um 10:35 Uhr

sensor.bitshake_smartmeterreader_ertrag_pv_alt = 3866.78

Dann ist

neuer_wert = 6866.78 + 56120.32 = 62987.1

alter_wert 62986.7 (= sensor.gesamtertrag_pv_alt von 10:30 Uhr - was auch so ist, wenn man sich den Wert im Zustandsdiagramm der Entität zu dem Zeitpunkt anschaut)

differenz = 62987.1 - 62986.7 = 0.4

Damit trifft 0 < differenz < 0.5 zu und es muss neuer_wert gesetzt werden, der ja bekanntlich 62987.1 ist. Es wird aber neuer_wert = 2,0 gesetzt ?!?

Folgender Test
state: >
{% set neuer_wert = states(‘sensor.bitshake_smartmeterreader_ertrag_pv_alt’) | float(2) + 56120.32 | float(2) %}
{% set alter_wert = states(‘sensor.gesamtertrag_pv_alt’) | float(2) + 10000 %}
{% set differenz = neuer_wert - alter_wert %}
{% if 0 < differenz <= 0.5 %}
{{neuer_wert}}
{% else %}
{{alter_wert}}
{% endif %}

liefert

gesamtertrag_pv_alt auf 20.002,0

Die Addition von 10000 zu sensor.gesamtertrag_pv_alt wird also verdoppelt - wie auch immer sich das erklären soll.

Für mich bleibt aktuell eigentlich nur ein Schluss:
Homeasistant kann nicht rechnen bzw. nicht mit if else Bedingungen umgehen, obwohl derartige Skripte für state zahlreich zu finden sind.

Aber vielleicht gibt’s ja auch eine Erklärung für das Phänomen und eine Anpassung für state, die das macht, was gebraucht wird: neuen Wert nur schreiben, wenn dieser
a) größer ist als der bisherige Wert
b) nicht mehr als 0.5 größer ist als der alte Wert
ansonsten alten Wert beibehalten.

(Beitrag vom Verfasser gelöscht)

guter Ansatz, zumindest für den Bitshake. Aber was muss ich dort ins Skript eintragen?
Edit: zu schnell quergelesen… dann suche ich mal :smiley:

Das kenne ich natürlich. Aber wenn man täglich bei 20+ Entitäten x-Ausreißer korrigieren muss, kann man bei dieser Umsetzung der Statistik-Korrektur beim Besten Willen nicht von einfach reden.

Einfach würde bedeuten, dass ich nicht für jeden Ausreißer erneut auf das Icon rechts klicken, dann auf Ausreißer klicken, dann einen Wert anklicken, diesen Ändern, speichern und dann alle Schritte von vorn machen muss, sondern Symbol → Ausreißer → Auswahlkästchen, welche Werte → Wert ändern → speichern.

Dazu kommt die Tatsache, dass ein auf 0 gesetzter Ausreißer in den meisten Fällen erst mal neue Ausreißer erzeugt, oft dann genau ein Minuswert in derselben Größe. Um 10 Ausreißer aus einer Entität zu nullen, macht man die beschriebenen Schritte mindestens 20 mal. Diese Art der Fehlerkorrektur ist Zeitvernichtung und irgendwie fail by design - habe ich noch nirgendwo anders so umständlich und wenig erfolgsversprechend erlebt. Aber das ist OT und soll den HA auch nicht schlecht machen. Insgesamt ist der im Vergleich zu den ganzen Closed-Source und Walled-Garden Hersteller-Cloud-Lösungen einfach nur genial.

Ich habe jetzt hier im Forum und über die Suchmaschine meines Vertrauens zu Tasmota Bitshake Skript und Senden von 0 Werten gesucht und viele Threads angeschaut. Dabei habe ich drölfmillionen Varianten von if elif else Bedingungen für states gefunden, um das abzufangen, aber keinen einzigen Hinweis auf eine Änderung im Tasmota-Skript, die das Problem an der Wurzel verhindert.

Jetzt stellt sich die Frage, was du davon hast, Leute das Rad ewig neu suchen zu lassen, wenn du die Lösung kennst :man_shrugging:

1 „Gefällt mir“

Wozu rechnest du mit PV alt rum ?

Total increasing addiert die Werte doch selber ?

Also mal ehrlich. Ein Forum, in dem man so arrogant und selbstgefällig empfangen wird wie dieses, habe ich selten erlebt :man_shrugging:

Aber ich erklär’s dir gerne: Hier gibt’s halt 2 getrennte PV Anlagen, eine alte und eine neue, dementsprechend gibt’s halt auch PV alt und PV neu und PV gesamt. Und btw addiert total increasing halt auch keine historischen Werte von der Zeit vor HA. Und BTW 2 trägt das alles ohnehin überhaupt nichts zur Problemlösung bei.

Aber offensichtlich ist man hier lieber unter sich und stößt neue Leute vor dem Kopf, statt mit sinnvollen Antworten zu helfen :man_shrugging:

2 „Gefällt mir“

Es sind nicht alle so. Nur die anderen schreiben weniger. Viel weniger.:cold_sweat:

1 „Gefällt mir“

Vielen Dank für die wichtige Info. Wahrscheinlich haben die 2 einfach den ganzen Tag nix besseres zu tun, als andere Leute dumm anzumachen, statt die aufgewandte Zeit in die Hilfe zur Problemlösung zu investieren :man_shrugging:

Das war eine Frage warum du das so machst insbesondere da du da zumindest in der Formel mit festen Werten arbeitest.
Da wir hier nicht wissen warum du was so machst muss man nachfragen.

Dann kann man eventuell eine alternative Lösung vorschlagen oder Evt erkennen ob da ein Problem liegt.

https://community.simon42.com/t/stromzaehler-spitzen-abfangen-bitte-code-pruefen/72040/6

1 „Gefällt mir“

Ok, verstehe ich. Das “verrate ich dir nicht” und dem “rechnest du mit PV alt RUM” empfand ich jedenfalls nicht gerade als Willkommensein. Egal.

Ich führe hier seit dem das Haus steht Calc Statistiken, aus denen sich dann z.B. eben auch ergibt, wie viel kWh unsere alte PV Anlage (deshalb in HA PV alt) insgesamt erzeugt hat. Damit mir HA nicht nur den Zählerstand des Bishake Smartmeterreader anzeigt, sondern eben den tatsächlichen Gesamtwert, habe ich einen Helfer definiert, der zum Wert der Entität des Bishsake den Wert bis zu dessen Inbetriebnahme dazu addiert ( das sind die + 56120.32).

Der Bitshake hat einen Zählerstand von jetzt ~ 6870 kWh, die Anlage hat aber ~ 62990 kWh produziert, was ich durch den Helfer eben dann auch so in HA angezeigt bekomme. BTW habe ich auch für jeden letzten Tag des Monats den Zählerstand in diesen Helfer per csv-Import eingetragen, so dass ich solche Statistiken auch weiter zurück als die Laufzeit des HA erhalte:

Bis zu den August-Updates hatte ich solche Ausreißer immer nur, wenn ich die configuration.yaml neu eingelesen habe. Das war vertretbar. Nun habe ich diese eben mehrmals täglich, und viele davon wirken sich auf weitere Entitäten aus. Ein Ausreißer für PV alt ergibt automatisch auch einen für PV gesamt usw. usf.
Das ist ohne automatisches Herausfiltern der Ausreißer nicht mehr handelbar. Meinem Programmierverständnis und zahlreicher solcher Code-Beispiele hier und anderswo zu Folge müsste das mein if else für den State lösen, führt aber wie im Einganspost erläutert dazu, dass der State von den knapp 63000 kWh auf 2 kWh sinkt.

Sehr gut hier zu sehen, als ich das wie oben konfiguriert hatte (linker Teil des Ausschnitts), wieder auf die ursprüngliche Variante für state geändert (Sprung nach oben), wieder wie oben konfiguriert (Sprung nach unten) und wieder zurück (Sprung nach oben) konfiguriert habe:

Das hatte ich vor meinem Post schon gesehen, führt aber zum selben Ergebnis wie meine und jede andere bislang getestete Variante von if (elif) else, die eigentlich so wie meine bisherige einfach Variante

state: “{{ states(‘sensor.bitshake_smartmeterreader_ertrag_pv_alt’) | float(2) + 56120.32 | float(2) }}”

als Wert dann knapp 63000 kWh liefern müsste und eben nicht nur noch 2 kWh.

Hast du das mal im Template Editor geprüft was du dort für Ergebnisse bekommst ?

Ausreißer hast du normalerweise wenn du einen Nullwert bzw. Not avaible bekommst.

Das muss abgefangen werden

Du könntest einen Sensor im gui erstellen und dort auf avaible prüfen.

Wenn du einen Verbrauchszähler für PV Alt erstellst kannst du den alten Wert da setzen und ihn dann von da ab zählen lassen.

utility_meter.calibrate

Was ist der Template Editor?

Richtig. Deswegen habe ich das nochmal überarbeitet:

 state: >
   {% set neuer_wert = states(‘sensor.bitshake_smartmeterreader_ertrag_pv_alt’) | float(2) + 56120.32 | float(2) %}
   {% set alter_wert = states(‘sensor.gesamtertrag_pv_alt’) | float(2) %}
   {% set differenz = neuer_wert - alter_wert %}
   {% if states(‘sensor.bitshake_smartmeterreader_ertrag_pv_alt’) == ‘unavailable’ or states(‘sensor.bitshake_smartmeterreader_ertrag_pv_alt’) == 0 or differenz <= 0 %}
     {{ alter_wert }}
   {% elif 0 < differenz <= 0.5 %}
     {{ neuer_wert }}
   {% else %}
     {{ alter_wert }}
   {% endif %}

Das führt aber wieder zum Zustandswert 2, obwohl direkt beim Einlesen der neuen Config der Zustand von sensor.gesamtertrag_pv_alt den Wert von ~ 63000 hatte und dieser ja gesetzt werden müsste :man_shrugging:

Das sollte doch nun auch

if states(‘sensor.bitshake_smartmeterreader_ertrag_pv_alt’) == ‘unavailable’ machen…

Das mit den Verbrauchszählern habe ich auch schon gelesen. Aber es kann ja nicht sein, dass man alle paar Monate wieder alle Statistiken verliert. Zumal ich zahlreiche Berechnungen habe, die auf Entitäten wie der hier genannten basieren. Das müsste ich alles ebenfalls neu machen. Die wirklichen Probleme mit Ausreißern haben auch erst mit den August-Updates angefangen, siehe Probleme mit Home Assistant Update ab Version 2026.8.* (aktuell 2026.8.1) + Video 🎉 von @simon42 - #113 von crazy-to-bike

Der Ist unter Entwicklerwerkzeuge bzw. Tools und dann Template.

Da kannst direkt testen was was bewirkt.

Der Verbrauchssensor verliert keine Statistiken

1 „Gefällt mir“

Ich verwende hier einen Helfer - Filter.


Hier mal Test genannt (Bei Dir wie Du den Sensor dann nennen willst) mit dem Sensor meines Stromzählers.
Parameter beim Bestätigen dann:
Fenstergröße 7
Radius 3
Genauigkeit 3

Mit Diesem Sensor arbeite ich dann weiter. Seitdem nie wieder einen Außreiser bei meinen Stromverbrauch

1 „Gefällt mir“

Das habe ich mir auch schon angeschaut und vielleicht ist das tatsächlich die einzige Option, wenn die if elif else Bedingungen, die man ja zuhauf als Vorschlag findet, warum auch immer nicht wirklich funktionieren. Ich würde allerdings trotzdem gerne herausfinden und verstehen, warum die Bedingungen nicht zu dem Ergebnis führen, zu dem sie führen müssten.

OT:
Grundsätzlich stelle ich mir, da du das Anlegen des Helfers grafisch zeigst, die Frage, ob man bei HA nicht (inzwischen) alles grafisch machen sollte/müsste, da zumindest die jüngeren Updates etliches wie z.B. die https Konfiguration aus der configuration.yaml entfernt und in das UI integriert haben. Irgendwie habe ich den Eindruck, die Entwickler wollen weg von den Konfigurationsdateien, auch wenn mir persönlich letztere lieber sind, weil ich da schneller und besser sehe und verstehe, was Sache ist. Das ist weniger Blackbox.
Allerdings kann man einen in der configuration,yaml angelegten Helfer imho nicht einfach in einen grafischen überführen und ihn auch nicht grafisch bearbeiten. Wobei, wenn man wüsste, wo und wie die grafischen Helfer gespeichert werden…

Hast du den Code schon im Template Editor getestet ? da siehst du die Live Werte

Deine 2 kommt daher das ein sensor einen nicht numerischen Wert hat, du hast bei float als default 2 angegeben daher wird das gesetzt wenn die Umwandlung fehlschlägt.

Nein, ich habe erst diese

Erkenntnis (siehe Regelmäßig Ausreißer (Wert statt Differenz) bei Tasmota Energie - #8 von MacAndreas) “verarbeitet”. Das mit dem Template Editor teste ich jetzt.

Du musst den Sensor finden der den Fehler verursacht, wahrscheinlich hat der zwischendrin einen unavaible Wert.

Bei deinem Code weiter oben hast du nur unavaible für einen Sensor abgefangen daher vermute ich das es der sensor.gesamtertrag_pv_alt ist.

{% set alter_wert = states('sensor.gesamtertrag_pv_alt') %}
{% set neuer_wert = (states('sensor.bitshake_smartmeterreader_ertrag_pv_alt') | float(2) + 56120.32) %}
{% set differenz = (neuer_wert - alter_wert) %}  
{% if 0 < differenz <= 0.5 %}
  {{ neuer_wert }}
{% else %}
  {{ alter_wert }}
{% endif %}

und

{% set alter_wert = states('sensor.gesamtertrag_pv_alt') %}
{% set neuer_wert = (states('sensor.bitshake_smartmeterreader_ertrag_pv_alt') | float(2) + 56120.32 | float(2)) %}
{% set differenz = (neuer_wert - alter_wert) %}  
{% if 0 < differenz <= 0.5 %}
  {{ neuer_wert }}
{% else %}
  {{ alter_wert }}
{% endif %}

liefert beides

TypeError: can only concatenate str (not “float”) to str