Deluxe Automatiserung für Rasenmäherroboter

Hi,

ich bekomme es einfach nicht hin. Das Problem ist, dass ich einfach nur das nachmache was mir Oern geschrieben hat. Bei mir hakt es an einfachsten Übertragungen. Mir fehlt es grundsätzlich am Wissen.

Mein Sensor heißt

859_Sonoff_SNZB-02WD_Garten

Die Entität für die Temperatur heißt

sensor.859_sonoff_snzb_02wd_garten_temperature

Ich bekomme den Code in den Entwickleroptionen schon nicht hin, um die Temperatur anzeigen zu lassen.

Das was du aus dem Forecast ausgelesen hast:

{{ states.weather.forecast_home.attributes.temperature }}
{{state_attr(‘weather.forecast_home’, ‘temperature’)}}
{{ states.weather.forecast_home.attributes.temperature | float > 0}}

Muss angepasst werden. Ich hab es jetzt zigmal versucht, immer wieder eine Nacht drüber geschlafen:

Ergebnis:

{{ states(‘sensor.859_sonoff_snzb_02wd_garten_temperature’) }}
{{state_attr(‘859_sonoff_snzb_02wd_garten_temperature’, ‘temperature’)}}

Zeile 1 liefert die Temperatur

Zeite 2 liefert: none. Hier stimmt was nicht

Was muss ich da machen?

Eine Entität hat immer genau einen State. Zusätzlich zu dem State kann die Entität auch noch Attribute haben. Bei diesem Sensor ist die Temperatur kein Attribut, wie Du auf dem folgenden Screenshot sehen kannst, es ist der State des Sensors. Das erkennt man u.a. auch an der device_class: temperature. :wink:

Wenn Du mit state_attr(‘…’, ‘…’) ein Attribut abfragst, dass nicht existiert, bekommst Du als Rückgabewert none zurück. Das ist bei Deinem Sensor der Fall. Ein Attribut namens Temperature gibt es nicht, also bekommst Du none zurück. Die erste Zeile, die Du genannt hast, ist hier die korrekte:

{{states('sensor.859_sonoff_snzb_02wd_garten_temperature')}}

Bei dem weather.forcecast_home hingegen ist die Temperatur ein Attribut:

Abfragen kannst / musst Du es also so:

{{ states.weather.forecast_home.attributes.temperature }}
{{ state_attr('weather.forecast_home', 'temperature')}}

An dieser Stelle funktioniert beides, anzuraten wäre aber die zweite Version mit {{ state_attr(..)}}, weil bei dieser Art Abfrage HA immer etwas zurückgibt - und wenn es nur none ist! Bei der ersten Variante kann es passieren, dass HA Dir eine Fehlermeldung um die Ohren haut:

Und wie bekomme ich jetzt bei meinem Sensor ohne Attribut die zweite Zeile erstellt?

Hintergrund war, dass mir ohne Werte nicht alles zerschießt.

Sagst Du vielleicht noch eben an in welchem der vielen YAML-Codes welche Zeile Du meinst? :thinking:

Dann kriegen wir das hin. :wink:

Ich bin noch in den Entwicklerwerkeugen in Template.

{{ states.weather.forecast_home.attributes.temperature }}
{{state_attr('weather.forecast_home', 'temperature')}}
{{ states.weather.forecast_home.attributes.temperature | float > 0}}

{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature') }}
{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature')|float(0) }}

Die Zeilen geben aus:

10.9
10.9
True

17.8
17.8

Beim Sonoff bekomme ich die zweite Zeile nicht aus dem Forecast Beispiel abgeleitet.

Du meinst die mittlere der oberen drei Zeilen:

{{ states.weather.forecast_home.attributes.temperature }}
{{state_attr('weather.forecast_home', 'temperature')}}
{{ states.weather.forecast_home.attributes.temperature | float > 0}}

{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature') }}
{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature')|float(0) }}

Die kannst Du von dem Sonoff auch nicht bekommen. Weil bei dem Sensor die Temperatur kein Attribut ist. Bei diesem Sensor ist die Temperatur der state.

Es gibt Entitäten. Jede Entität hat einen state. Der state kann ein Zustand wie on oder off sein, z.B. bei einem Schalter. Oder ein state von 0% bis 100%, z.B. für eine Batterie. Oder eine (beliebige) Zahl, z.B. eine Temperatur. Wie bei Deinem Sensor. Da ist der state eine Zahl.

Wenn eine Entität mehrere Werte liefern kann, dann ist einer davon der state. Da eine Entität aber nur genau einen state haben kann, müssen die anderen als Attribut bereitgestellt werden.

Nehmen wir nochmal die Lampe. Bei der Lampe ist die interessanteste Information, ob sie ein- oder ausgeschaltet ist. Deshalb ist diese Information der state. Der State kann on oder off sein. Die Leuchtstärke und Lichtfarbe können nun, weil der state ja bereits belegt ist, nur noch als Attribut bereitgestellt werden.

Der interessanteste Wert (D)eines Temperatursensor ist … ? Natürlich die Temperatur. Deshalb ist der state die Temperatur! Du kannst ihn dir ja mal unter

Entwicklerwerkzeuge → Zustände

angucken. Wenn der Sensor noch weitere Werte erfassen kann, z.B. die Luftfeuchtigkeit, dann werden diese als Attribut bereitgestellt. Weil der state … ? … richtig! … bereits von der Temperatur belegt ist. :wink:

Du kannst die Anfrage

{{state_attr('sensor.859_sonoff_snzb_02wd_garten_temperature', 'ATTRIBUT')}}

jederzeit nutzen - um damit ein Attribut abzufragen. Wenn Du unter

Entwicklerwerkzeuge → Zustände

guckst, dann ist der erste Eintrag rechts vom Sensor der state. Und rechts daneben findest Du die Attribute(wenn es denn welche gibt).

Außer in der Companion App. Da werden die Attribute nicht angezeigt. :thinking: :man_shrugging:

Aaah, langsam verstehe ich es.

Die Sonoff Hardware hat also mehrere Sensoren, die jeweile einen state liefern:

temperature_units

battery

humidity

voltage

und…

temperature

Beim weather.forecast_home waren das zig Attribute.

Soweit habe ich es kapiert.

Beim weather.forecast_home hast du in den Entwickleroptionen/Template noch eien zweite Zeile Code rein geapckt. Da habe ich gefragt warum. Deine nachvollziehbare Antwort war:

Das sind beides Strings! Mit der ersten Zeile greifst du - sozusagen - direkt in den Sensor rein und holst da den Wert ab. Wenn der Sensor diesen Wert gar nicht hat, weil er ihn generell nicht hat oder Du Dich vielleicht nur verschrieben hast, dann gibt es einen Fehler:

Bildschirmfoto 2025-09-30 um 17.15.25

Bildschirmfoto 2025-09-30 um 17.15.252496×406 49.8 KB

Mit der zweiten Zeile sagst Du Home Assistant “Hey, frag mal den Sensor nach dem Wert und gib ihn mir”. Das macht HA dann. Weil HA das managed bekommst Du aber immer etwas zurück. Entweder den Wert, none (wenn der Sensor den Wert gar nicht hat) oder unknown / unavailiable (wenn es den Wert zwar generell gibt, er aber gerade unbekannt oder nicht verfügbar ist)

Was mache ich jetzt mit dem Sensor von Sonoff? Gibt der mit

{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature') }}

oder

{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature')|float(0) }}

auch immer etwas zurück?

Mein Plan ist aktuell:

Sicherstellen, dass immer was zurück kommt.

Helfer 1, der die Temperaturwerte stündlich addiert

Helfer 2, der (wenn etwas in Helfer 1 geschrieben wird) die Anzahl der Werte addiert

Am Ende des Tages teile ich dann den Wert aus Helfer 1 durch den Wert aus Helfer 2 und habe meine Durchschnittstemperatur.

So, da bin ich wieder. Ich bin dann mal im Urlaub. Zwar nur auf Balkonien, dafür hab ich jetzt Zeit einen ganzen Karton voller Zeug zu installieren und in HA reinzufrickeln, das sich während meiner Abwesenheit hier so angesammelt hat. :blush:

Fast richtig. :laughing:

battery, humidity und voltage sind Entitäten. Das Gerät (also das Sonoff SNZB-02WD) ermittelt mit Sensoren den entsprechenden Wert und schreibt ihn in den state der Entität. Soweit ist es korrekt, ja.

Bei weather.forecast_home gibt es für diese Werte keine separaten Entitäten. Dort werden diese Werte als Attribut bereitgestellt. Soweit auch korrekt.

Ich nehme an, Du wolltest beim Sonoff außerdemtemperature hinzufügen, hast aber aus Versehen temperature_units erwischt? Für temperature stimmt das eben gesagte ebenfalls.

temperature_units ist eine Entität, die nicht (ob direkt oder indirekt) von der Hardware abhängt, z.B. einem Sensor. Diese Entität kannst Du setzen. Damit kannst Du festlegen, welche Einheit auf dem Display angezeigt werden soll. :smiling_face_with_sunglasses:

Das erkennt man z.B. an der domain, der die Entität angehört.

Falls Du da mehr zu wissen möchtest, schreib kurz Bescheid. :wink:

Für die Version in der ersten Zeile bekommst Du immer etwas zurück, ja. states(…) ist eine Funktion von HA. Die versucht den state der angegebenen Entität auszulesen. Kann der state nicht gelesen werden, dann gibt HA Dir unknown oder unavailable zurück. Falls es einen state gibt, bekommst Du den Wert des state geliefert. D.h. die Fehlerprüfung, Wertermittlung und alles andere, was dazu gehört, übernimmt HA für Dich.

Die erste Zeile gibt Dir den state der Entität 859_sonoff_snzb_02wd_garten_temperature als Text (String) zurück. Mit einem Text kann man natürlich nicht rechnen. Versuchst Du es trotzdem, bekommst Du einen Fehler:

Bildschirmfoto 2025-10-15 um 18.10.40

Bildschirmfoto 2025-10-15 um 18.10.46

Es gibt einen TypeError, weil HA zu einem Text (string / str) keine Ganzzahl (integer / int) addieren kann. Damit HA mit der Temperatur tatsächlich rechnen kann, muss man den Text in eine Zahl umwandeln. Dann funktioniert das:

Bildschirmfoto 2025-10-15 um 18.23.49

Das macht das | float. Das | float bedeutet: nimm das links von dem senkrechten Strich und mach eine Kommazahl daraus. Zu dem Ergebnis dieser Umrechnung addieren wir dann mit + 1 noch eins. Mal gucken. Ja, passt:

Bildschirmfoto 2025-10-15 um 18.13.28

Und wenn das Ergebnis der Umrechnung mit | float keine Kommazahl ergibt? Mal gucken, was passiert, wenn wir eine Entität angeben, die es gar nicht gibt:

Das quittiert HA mit einer Fehlermeldung:

Bildschirmfoto 2025-10-15 um 18.32.42

Wie erwarte meckert HA. HA sagt uns sogar, was nicht passt:

ValueError: Template error: float got invalid input ‘unknown’ when rendering template ‘{{ states(‘sensor.sonoff’) | float}}’ but no default was specified

HA hat nachgeguckt, die Entität sensor.sonoff nicht gefunden und gibt deshalb den Text unknown (unbekannt) zurück. Das ist auch richtig so. unknown ist nun offensichtlich keine Zahl, deshalb kann HA diesen Text nicht in eine Kommazahl umwandeln. Deshalb beendet HA die Abarbeitung und meldet einen Fehler. Bei dem Fehlertext gibt es aber noch einen interessanten Teil weiter hinten:

ValueError: Template error: float got invalid input ‘unknown’ when rendering template ‘{{ states(‘sensor.sonoff’) | float}}’ but no default was specified

Man kann einen Default-Wert (Standard-Wert) angeben. Genau das macht die (0) hinter float. Wenn HA versucht den Text in eine Kommazahl umzuwandeln, das aber nicht funktioniert, dann wird stattdessen der Default-Wert übergeben. Damit verhindert man, dass z.B. eine Automation, die irgendetwas berechnen soll, plötzlich mittendrin mit einem Fehler stehenbleibt, weil die Entität z.B. gerade nicht erreichbar ist. Dann ist ihr state nämlich‘unavailable', was? … genau! … nicht in eine Kommazahl umgewandelt werden kann.

Abschließend nochmal die Kurzfassung
(Achtung! Ich hab extra Leerzeichen eingefügt, damit man es besser erkennt!)

Frage HA nach dem state ...

{{ states( ‘sensor.859_sonoff_snzb_02wd_garten_temperature’ ) | float(0) }}

… dieser Entität:

{{ states(‘ sensor.859_sonoff_snzb_02wd_garten_temperature ’) | float(0) }}

Das Ergebnis der Abfrage links vom |

{{ states(‘sensor.859_sonoff_snzb_02wd_garten_temperature’) | float(0) }}

Wandel in eine Kommazahl um

{{ states(‘sensor.859_sonoff_snzb_02wd_garten_temperature’) | float (0) }}

Wenn dabei keine gültige Kommazahl herauskommt, dann gibt stattdessen den Default-Wert zurück

{{ states(‘sensor.859_sonoff_snzb_02wd_garten_temperature’) | float (0) }}

Wenn Du diesen Ausdruck jetzt verwendest, um irgendwo einen Text anzeigen zu lassen, z.B. im Template, dann kann das passieren:

Die Aussentemperatur ist {{ states('sensor.859_sonoff_snzb_02wd_garten_temperature') | float(0) }} °C

Bildschirmfoto 2025-10-15 um 19.06.26

Moment, die Temperatur ist doch falsch! So kalt ist es noch gar nicht. Stimmt, aber die Ausgabe ist korrekt und logisch, weil die Entität mit diesem Namen in meinem HA nicht existiert. Es ist der Name Deiner Entität. Das ist nicht die Temperatur, das ist der Default-Wert 0. Aber immerhin ist das Template sauber durchgelaufen und hat mir keine Fehlermeldung um die Ohren gehauen. :wink:

Sowas kann man natürlich auch abfragen und entsprechend drauf reagieren, das kommt aber etwas später dran, denke ich. :laughing:

Danke sehr. Ich habe jetzt das Gefühl, dass ich Fortschritte erziele.

Ich habe jetzt:

  1. Helfer “input_number.859_tagestemperatur_summe_jede_stunde” erstellt
  2. Automatisierung, die den Helfer aus 2. jede volle Stunde um den aktuellen Temperaturwert von draußen erhöht, wenn die Temperatur >0 ist. Hier ist noch ein Fehler drin, weil für die GTS nur die positiven Tagesdurchschnittswerte relevant sind. Bei der Tagesdurchschnittstemperatur sind negative Werte in Ordnung. Ich weiß, wie man das löscht, brauche es aber noch für 4.
  3. Helfer “input_number.859_werte_summe_jede_stunde” erstellt.
  4. Automatisierung, die den Helfer aus 3. jede volle Stunde um 1 erhöht. Ich bin nicht sicher, ob hier auch um 1 erhöht wird, wenn bei 1. udn 2. kein Wert kommt (z.B: weil der Sensor defekt ist).

Home Assistant zählt bisher jede Stunde die Temperatur hoch und erhöht auch den Zähler.

Unter Template/Entwicklungsoptionen habe ich den Durchschnittswert gebildet:

{{ states('input_number.859_tagestemperatur_summe_jede_stunde')|float(0)}}
{{ states('input_number.859_werte_summe_jede_stunde')|float(0)}}

{{ states('input_number.859_tagestemperatur_summe_jede_stunde')|float(0)/states('input_number.859_werte_summe_jede_stunde')|float(0)}}

Ich sehe hier:

Summe der Temperaturen

Anzahl der Werte

Durchschnittstemperatur

Ich brauche jetzt weitere Helfer/Automatisierungen:

  1. der die Tagesdurchschnittswerte summiert (nach 23:00:00 Uhr)
  2. der den Tagestemperaturzähler kurz nach der Summierung auf 0 setzt
  3. der die Anzahl der Werte kurz nach der Summierung auf 0 setzt
  4. der am 31.12 die Summe der Tagesdurchschnittswerte auf 0 setzt.

Ich bin da aber jetzt dank Oern sehr optimistisch.

So, ich bin jetzt hoffentlich soweit, dass das System die positiven Tagesdurchschnittstemperaturen gewichtet aufaddiert.

Dazu habe ich vier Helfer erstellt:

Helfer 1

859_Tagestemperatur_Summe_jede_Stunde

Zahlenwert-Eingabe

input_number.859_tagestemperatur_summe_jede_stunde

summiert von 0:00:00 bis 23:00:00 Uhr jede volle Stunde die Temperatur auf, wird um 23:10:00 Uhr auf null zurück gesetzt

Helfer 2

859_Werte_Summe_jede_Stunde

Zahlenwert-Eingabe

input_number.859_werte_summe_jede_stunde

summiert von 0:00:00 bis 23:00:00 Uhr jede h die Anzahl der Werte auf, wird um 23:10:00 Uhr auf null zurück gesetzt

Helfer 3

859_Tagesdurchschnittstemperatur

Template

number.859_tagesdurchschnittstemperatur

Rechnet aus Helfer 1 und 2 die Tagesdurchschnittstemperatur aus (Helfer 1/Helfer 2), wird um 23:10:00 Uhr auf null zurück gesetzt

Helfer 4

859_Summe_Tagesdurchschnittstemperaturen_groesser_null

Zahlenwert-Eingabe

input_number.859_summe_tagesdurchschnittstemperaturen_groesser_null

summiert vom 01. Januar bis 31. Dezember jeden Tag um 23:05:00 Uhr die positiven Tagesdurchschnittstemperaturen (Helfer 3) auf, wird am 31. Dezember um 23:10:00 Uhr auf null zurück gesetzt

Automatisierung 1

859 Temperatur jede Stunde addieren

Summiert von 0:00:00 bis 23:00:00 Uhr jede volle Stunde die Temperatur auf

alias: 859 Temperatur jede Stunde addieren
description: ""
triggers:
  - trigger: time_pattern
    hours: "*"
    minutes: "0"
    seconds: "0"
conditions:
  - condition: template
    value_template: "{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature')|float(0)>0}}"
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_tagestemperatur_summe_jede_stunde
    data:
      value: >-
        {{ states('input_number.859_tagestemperatur_summe_jede_stunde') | float
        + states('sensor.859_sonoff_snzb_02wd_garten_temperature') | float }}
mode: single

Automatisierung 2

859 Anzahl Werte jede Stunde addieren

Summiert von 0:00:00 bis 23:00:00 Uhr jede volle Stunde die Anzahl der Werte auf

alias: 859 Anzahl Werte jede Stunde addieren
description: ""
triggers:
  - trigger: time_pattern
    hours: "*"
    minutes: "0"
    seconds: "0"
conditions:
  - condition: template
    value_template: "{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature')|float(0)>0}}"
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_werte_summe_jede_stunde
    data:
      value: "{{ states('input_number.859_werte_summe_jede_stunde') | float + 1 }}"
mode: single

Automatisierung 3

859 Temperatur jede Stunde addieren zuruecksetzen

Setzt täglich um 23:10:00 den Helfer 1 auf 0 zurück

alias 859 Temperatur jede Stunde addieren zuruecksetzen
description 
triggers
  - trigger time
    at 231000
conditions []
actions
  - action input_number.set_value
    target
      entity_id input_number.859_tagestemperatur_summe_jede_stunde
    data
      value -
        {{ states('input_number.859_tagestemperatur_summe_jede_stunde')float 
        0 }}
mode single

Automatisierung 4

859 Anzahl Werte jede Stunde addieren zuruecksetzen

Setzt täglich um 23:10:00 den Helfer 2 auf 0 zurück

alias: 859 Anzahl Werte jede Stunde addieren zuruecksetzen
description: ""
triggers:
  - trigger: time
    at: "23:10:00"
conditions: []
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_tagestemperatur_summe_jede_stunde
    data:
      value: "{{ states('input_number.859_werte_summe_jede_stunde')|float * 0 }}"
mode: single

Automatisierung 5

859 Tagesdurchschnittstemperatur groesser null jeden Tag addieren

Summiert täglich jeden Tag um 23:05:00 Uhr den Wert von Helfer 3 (wenn positiv) auf den Wert von Helfer 4, Januarwerte werden mit 0,5, Februarwerte mit 0,75 gewichtet

Bitte hier mal schauen, ob da was auffällt. Danke!

alias: 859 Tagesdurchschnittstemperaturen groesser null jeden Tag addieren
description: ""
triggers:
  - trigger: time
    at: "23:05:00"
conditions:
  - condition: template
    value_template: "{{ states('number.859_tagesdurchschnittstemperatur')|float(0)>0}}"
actions:
  - if:
      - condition: template
        value_template: "{{ now().month == 1 }}"
    then:
      - action: input_number.set_value
        target:
          entity_id: input_number.859_summe_tagesdurchschnittstemperaturen_groesser_null
        data:
          value: >-
            {{
            (states('input_number.859_summe_tagesdurchschnittstemperaturen_groesser_null')|float
            *0.5) + states('number.859_tagesdurchschnittstemperatur') | float}}
  - if:
      - condition: template
        value_template: "{{ now().month == 2 }}"
    then:
      - action: input_number.set_value
        target:
          entity_id: input_number.859_summe_tagesdurchschnittstemperaturen_groesser_null
        data:
          value: >-
            {{
            (states('input_number.859_summe_tagesdurchschnittstemperaturen_groesser_null')|float
            *0.75) + states('number.859_tagesdurchschnittstemperatur') | float}}
  - if:
      - condition: template
        value_template: "{{ now().month in [3, 4, 5, 6, 7, 8, 9, 10, 11, 12] }}"
    then:
      - action: input_number.set_value
        target:
          entity_id: input_number.859_summe_tagesdurchschnittstemperaturen_groesser_null
        data:
          value: >-
            {{
            (states('input_number.859_summe_tagesdurchschnittstemperaturen_groesser_null')|float
            *1.0) + states('number.859_tagesdurchschnittstemperatur') | float}}
mode: single

Ich hoffe, dass Automatisierung 5 funktioniert. Diese if then Sachen habe ich noch nicht oft gemacht, die Monatsbedingung musste ich googlen.

Die Rechnung habe ich vorher im Template getestet. Das funktioniert.

Was fehlt jetzt noch?

Helfer 5

859_GTS_erreicht

Schalter

input_boolean.859_gts_erreicht

Schalter, der als Bedingung für den späteren Mähvorgang dient.

Automatisierung 6, die den Helfer 5 auf ein schaltet, wenn Helfer 4 > 160 ist

Automatisierung 7, die Helfer 4 am 31.12.2025 um 23:10:00 auf 0 zurück.

Automatisierung 8, die den Helfer 4 am 31.12.2025 um 23:10:00 auf aus schaltet.

Wenn das erledigt ist, ist die GTS Bedingung vollständig.

Ich muss danach noch zwei Dinge machen:

A) das tägliche Rasenwachstum bzw. das Rasenwachstum seit dem letzte Mähen berechnen. Das müsste einfahc sein, wenn Automatisierung 5 mit der Monatsbedingung klappt.

B) die Automatisierung für den Mähroboter erstellen, der fährt, wenn:

  • GTS erreicht
  • Mindestwachstum seit letzem Mähen erreicht
  • Abschluss des Mähvorgangs vor Sonnenuntergang
  • kein zu erwartender Regen
  • entsprechende Zeit seit letztem Regen vergangen

Ich habe leider ein Problem in de Automatisierung, die stündlich die Werte aufaddiert.

Code:

alias: 859 Temperatur jede Stunde addieren
description: ""
triggers:
  - trigger: time_pattern
    hours: "*"
    minutes: "0"
    seconds: "0"
conditions: []
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_tagestemperatur_summe_jede_stunde
    data:
      value: >-
        {{ states('input_number.859_tagestemperatur_summe_jede_stunde') | float
        + states('sensor.859_sonoff_snzb_02wd_garten_temperature') | float }}
mode: single

Die Werte:

Uhrzeit Temperatur (Sonoff) Temperatur durch Summierung

0:00 12,8 25,6

1:00 12,4 50,4

2:00 12,0 74,4

Die Summe ist also immer das Doppelte vom eigentlichen Wert. Ich verstehe nicht warum.

Hm, bei mir passt das:

Addierst Du das vielleicht aus versehen woanders nochmal? :thinking:

Nachtrag

Was sich herauskristallisiert: Es wird langsam unübersichtlich - und damit wird es fehleranfälliger. :grimacing:

Die if … then … endif hast Du ja bereits gefunden. Die können wir nutzen, um ein wenig aufzuräumen. Ziel ist es eine Automation zu haben, in der all das getan wird, was bisher von den einzelnen Automationen geleistet wird. :wink:

Ich bin alles nochmal durchgegangen und hatte tatsächluch einen Fehler beim Kopieren drin.

Ob es jetzt funktioniert, werde ich morgen sehen.

Ich habe mit in eine Dashboard jetzt auch die Diagramme der einzelnen Helfer eingerichtet.

Da es unübersichtlich wird, habe ich alle Helfer/Automatisierungne umbenannt (859_1, 859_2… statt nur 859).

Ich melde mich morgen gegen Abend wieder.

(Einen Tag später!)

Ich hab gestern Deine Automationen 1:1 kopiert. Die einzige Anpassung, die ich vornehmen musste, war der Name des Temperatursensors für aussen. Mich dünkt, da ist noch irgendwo ein Fehler drin:

859_werte_summe_jede_stunde ist offensichtlich falsch. Hm … guck Dir mal bei Automation 3 und 4 ganz genau an, was sie tun. :wink:

Ich hab Deine Liste oben mal zusammengefasst und ein wenig formatiert - so komplett ohne Formatierung ist das schlecht zu lesen.

Helfer 1
859_Tagestemperatur_Summe_jede_Stunde (Zahlenwert-Eingabe)
→ input_number.859_tagestemperatur_summe_jede_stunde

summiert von 0:00:00 bis 23:00:00 Uhr jede volle Stunde die Temperatur auf, wird um 23:10:00 Uhr auf null zurück gesetzt

Helfer 2
859_Werte_Summe_jede_Stunde (Zahlenwert-Eingabe)
→ input_number.859_werte_summe_jede_stunde

summiert von 0:00:00 bis 23:00:00 Uhr jede h die Anzahl der Werte auf, wird um 23:10:00 Uhr auf null zurück gesetzt

Helfer 3
859_Tagesdurchschnittstemperatur (Template)
→ number.859_tagesdurchschnittstemperatur

Rechnet aus Helfer 1 und 2 die Tagesdurchschnittstemperatur aus (Helfer 1/Helfer 2), wird um 23:10:00 Uhr auf null zurück gesetzt

Helfer 4
859_Summe_Tagesdurchschnittstemperaturen_groesser_null (Zahlenwert-Eingabe)
→ input_number.859_summe_tagesdurchschnittstemperaturen_groesser_null

summiert vom 01. Januar bis 31. Dezember jeden Tag um 23:05:00 Uhr die positiven Tagesdurchschnittstemperaturen (Helfer 3) auf, wird am 31. Dezember um 23:10:00 Uhr auf null zurück gesetzt

TODO: Helfer 5
859_GTS_erreicht (Schalter)
→ input_boolean.859_gts_erreicht

Schalter, der als Bedingung für den späteren Mähvorgang dient.

Die bestehenden Automationen. Es sind jetzt bereits 5 und es fehlen noch 3. Jetzt wird es wirklich unübersichtlich.

Automatisierung 1
859 Temperatur jede Stunde addieren

Automatisierung 2
859 Anzahl Werte jede Stunde addieren

Automatisierung 3
859 Temperatur jede Stunde addieren zuruecksetzen

Automatisierung 4
859 Anzahl Werte jede Stunde addieren zuruecksetzen

Automatisierung 5
859 Tagesdurchschnittstemperatur groesser null jeden Tag addieren

TODO: Automatisierung 6
Helfer 5 auf ein schaltet, wenn Helfer 4 > 160 ist

TODO: Automatisierung 7
Helfer 4 am 31.12.2025 um 23:10:00 auf 0 zurück.

TODO: Automatisierung 8
4 am 31.12.2025 um 23:10:00 auf aus schaltet.

Wenn man sich das alles genauer anschaut, sieht man, dass jede Stunde etwas gerechnet wird und bei einigen, wenigen Zeitpunkten zusätzlich etwas passiert. Als Tabelle niedergeschrieben springt es einem förmlich ins Gesicht:

An jedem Tag zu jeder vollen Stunde wird es berechnet. Jeweils um 23 Uhr wird am Ende jeden Tages etwas gelöscht (Lt), am letzten Tag jeden Monats etwas gelöscht (Lm) und am letzten Tag des Jahres etwas gelöscht (Lj).

Die Funktion now() hast Du ja bereits gefunden. Mit now() lässt sich ziemlich viel lustiges Zeug anstellen. Eine Übersicht darüber findet sich in der Doku unter …

HA.io → Documentation → Advanced configuration → Templating → TIME
HA.io → Documentation → Automation → Trigger → Time
HA.io → Documentation → Automation → Trigger → Time pattern

Statt schnöder Theorie testen wir das natürlich im Template in Natura:

# Das einfachste ist die aktuelle Zeit abzufragen. Das beinhaltet Datum 
# und Zeit. Das geht nicht nur als ein langer String an einem Stück ...
-> {{ now() }}

# ... sondern auch diverse Bestandteile einzeln:
now().day    -> {{ now().day }}
now().month  -> {{ now().month }}
now().year   -> {{ now().year }}
now().hour   -> {{ now().hour }}
now().minute -> {{ now().minute }}
now().second -> {{ now().second }}

# Man kann HA mittels timedelta() einen Zeitpunkt vor oder nach 'Jetzt'
# berechnen lassen. timedelta erlaubt als Argument weeks, days, hours,
# minutes, seconds, milliseconds und microseconds:

# Jetzt -3 Stunden
now() - timedelta(hours=3)
-> {{ now() - timedelta(hours=3) }}

# Jetzt +1 Tag
now() + timedelta(days=1)
-> {{ now() + timedelta(days=1) }}

# Jetzt -4 Wochen
now() - timedelta(weeks=4)
-> {{ now() - timedelta(weeks=4) }}
        ^^
# Guck mal. Das war ja im letzten Monat. Und wir können, wie wir oben
# gesehen haben, einzelne Bestandteile abfragen. Hm ... da fallen
# einem doch sofort ganz spontan haufenweise Schweinereien ein, die
# man damit anstellen kann:

Ist es 23 Uhr (Genauer: zwischen 23:00 und 23:59)?
now().hour == 23
-> {{ now().hour == 23 }}

Ist es 17:45 Uhr?
(now().hour == 17) and (now().minute == 45)
-> {{ (now().hour == 17) and (now().minute == 45) }}

Ist heute der 19.?
now().day == 19
-> {{ now().day == 19 }}

Welcher Montat ist heute?
now().month
-> {{ now().month }}

Welcher Monat ist in 14 Tagen?
( now() + timedelta(days=14) ).month
-> {{ (now()+timedelta(days=14)).month }}

Ist der Monat heute gleich dem Monat in 14 Tagen?
Anders formuliert: Ist in 14 Tagen ein anderer Monat?
now().month == ( now() + timedelta(days=14) ).month
-> {{ now().month == (now()+timedelta(days=14)).month}}

Bei Automatisierung 3 fehlt ein *. Mich wundert, dass da at 231000 und nicht at: “23:10:00” steht.
Bei Automatisierung 4 ist die entity id beim target falsch.

Bei Automatisierung 2 würde ich außerdem die Condition weglassen.

Das ist nicht ganz richtig.

Jede volle Stunde passiert das Aufaddieren der gemessenen Werte (Temperatur und Zähler):

859-1 Temperatur jede Stunde addieren Summiert von 0:00:00 bis 23:00:00 Uhr jede volle Stunde die Temperatur auf.

859-3 Anzahl Werte jede Stunde addieren Summiert von 0:00:00 bis 23:00:00 Uhr jede volle Stunde die Anzahl der Werte auf

Jede volle Stunde wird daraus die Durchschnittstemperatzr berechnet, eigentlich würde es um 23:00:00 reichen (oder um sicher zu gehen, um 23:03:00 Uhr)

Um 23:05 Uhr (also 5 Minuten später) passiert:

859-5 Tagesdurchschnittstemperatur groesser null jeden Tag addieren Summiert täglich jeden Tag um 23:05:00 Uhr den Wert von Helfer 3 (wenn positiv) auf den Wert von Helfer 4; Januarwerte werden mit 0,5, Februarwerte mit 0,75 gewichtet

Das Zurücksetzen folgende Helfer geschieht um 23:10:00 Uhr:

Helfer/Entität/Zurücksetzen

täglich:
1/input_number.859_1_tagestemperatur_summe_jede_stunde/23:10:00 jeden Tag
2/number.859_2_tagesdurchschnittstemperatur/23:10:00 jeden Tag
3/input_number.859_3_werte_summe_jede_stunde/23:10:00 jeden Tag

Nur Ende des Jahres

4/input_number.859_4_summe_tagesdurchschnittstemperaturen_groesser_null/23:10:00, 31. Dezember
5/input_boolean.859_5_gts_erreicht/23:10:00, 31. Dezember

Hier noch die Screens der Verläufe.

Es scheint zu klappen.

In dem Code fehlen alle Satzzeichen:

alias 859 Temperatur jede Stunde addieren zuruecksetzen
description 
triggers
  - trigger time
    at 231000

Eigentlich müsste der so aussehen. Keine Ahnung, wie Du das geschafft hast. :hushed_face:

alias: 859 Temperatur jede Stunde addieren zuruecksetzen
description: ""
triggers:
  - trigger: time
    at: "23:10:00"

So hast Du es umgesetzt, ja. Aber warum lässt Du zwischen den Berechnungen 5 oder 10 Minuten verstreichen? Wichtig ist die korrekte Reihenfolge, in der die Berechnungen bzw. das Löschen gemacht werden! 5 oder gar 10 Minuten Pause dazwischen braucht es dafür nicht. :wink:

Yap. Sieht aus, als findest Du Dich so langsam zurecht!? Jetzt braucht es “nur noch” Routine und die eine oder andere pfiffige Idee. Die Routine musst Du Dir leider selber aneignen. Mit den pfiffigen Ideen kann ich Dir aber ein bissl weiterhelfen. :wink:

Zuerst einmal: einiges an den Automationen lässt sich vereinfachen. Fangen wir mal klein an. Bei diesen beiden Automationen …

alias: 859 Temperatur jede Stunde addieren
description: ""
triggers:
  - trigger: time_pattern
    hours: "*"
    minutes: "0"
    seconds: "0"
conditions:
  - condition: template
    value_template: "{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature') | float(0)>0 }}"
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_tagestemperatur_summe_jede_stunde
    data:
      value: >-
        {{ states('input_number.859_tagestemperatur_summe_jede_stunde') | float
        + states('sensor.859_sonoff_snzb_02wd_garten_temperature') | float }}
mode: single

alias: 859 Anzahl Werte jede Stunde addieren
description: ""
triggers:
  - trigger: time_pattern
    hours: "*"
    minutes: "0"
    seconds: "0"
conditions:
  - condition: template
    value_template: "{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature') | float(0)>0 }}"
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_werte_summe_jede_stunde
    data:
      value: "{{ states('input_number.859_werte_summe_jede_stunde') | float + 1 }}"
mode: single

… sind die triggers und die conditions identisch. Nur die actions sind unterschiedlich?! In dem Fall kann man das zusammenfassen:

alias: 859 Temperatur jede Stunde und Anzahl Werte jede Stunde addieren
description: ""
triggers:
  - trigger: time_pattern
    hours: "*"
    minutes: "0"
    seconds: "0"
conditions:
  - condition: template
    value_template: "{{ states('sensor.859_sonoff_snzb_02wd_garten_temperature') | float(0)>0 }}"
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_tagestemperatur_summe_jede_stunde
    data:
      value: >-
        {{ states('input_number.859_tagestemperatur_summe_jede_stunde') | float
        + states('sensor.859_sonoff_snzb_02wd_garten_temperature') | float }}
  - action: input_number.set_value
    target:
      entity_id: input_number.859_werte_summe_jede_stunde
    data:
      value: "{{ states('input_number.859_werte_summe_jede_stunde') | float + 1 }}"
mode: single

Gleiches gilt für die Automationen zum Zurücksetzen:

alias: 859 Temperatur jede Stunde addieren zuruecksetzen
description: ""
triggers:
  - trigger: time
    at: "23:10:00"
conditions: []
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_tagestemperatur_summe_jede_stunde
    data:
      value: >-
        {{ states('input_number.859_tagestemperatur_summe_jede_stunde') | float
        * 0 }}
mode: single

alias: 859 Anzahl Werte jede Stunde addieren zuruecksetzen
description: ""
triggers:
  - trigger: time
    at: "23:10:00"
conditions: []
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_werte_summe_jede_stunde
    data:
      value: "{{ states('input_number.859_werte_summe_jede_stunde') | float * 0 }}"
mode: single

triggers und conditions sind identisch, nur die actions sind unterschiedlich. Also kann man auch die zusammenfassen. Außerdem kann man noch ein bißchen was vereinfachen:

states('input_number.859_werte_summe_jede_stunde') | float * 0 ergibt immer 0. Statt der Berechnung kann man dann auch einfach die 0 hinschreiben. :laughing:

alias: 859 Temperatur jede Stunde addieren und Anzahl Werte jede Stunde addieren zuruecksetzen
description: ""
triggers:
  - trigger: time
    at: "23:10:00"
conditions: []
actions:
  - action: input_number.set_value
    target:
      entity_id: input_number.859_tagestemperatur_summe_jede_stunde
    data:
      value: "0"
  - action: input_number.set_value
    target:
      entity_id: input_number.859_werte_summe_jede_stunde
    data:
      value: "0"
mode: single

2 Minuten Arbeit und - ZACK - aus 5 Automationen 3 gemacht. :smiling_face_with_sunglasses:

Die 3 übriggebliebenen lassen sich ebenfalls zusammenfassen. Schau Dir doch den Ablauf der 3 Automationen mal ganz genau an. Dann sortieren wir ein wenig um, vereinfachen ein bisschen und fassen hier und da was zusammen:

# 859 ALLES in einer Automation
-- triggers --
jede Stunde

-- conditions --

-- actions --
# Jede Stunde aktuelle Temperatur aufsummieren
wenn akt_Temp > 0 dann
  temp_summe = temp_summe + akt_Temp
  zähler = zähler + 1

# Um 23 Uhr den Tagesdurchschnitt berechnen
# Diesen Tagesdurchschnitt zum GST addieren
# Summe und Zähler zurücksetzen für nächsten Tag
wenn 23:00
  tages_durchschnitt_temp = temp_summe / zähler
  wenn januar dann
    gst = gst + (0,5 * tages_durchschnitt_temp)
  wenn februar dann
    gst = gst + (0,75 * tages_durchschnitt_temp)
  wenn maerz bis dezember dann
    gst = gst + tages_durchschnitt_temp
  temp_summe = 0
  zähler = 0

# Helfer / Merker setzen, wenn GST groß genug
wenn gst > 150
  gst_erreicht = true

# Gaaanz am Ende des Jahres (23 Uhr am letzten Tag)
# alles löschen
wenn 23:00 und letzter Tag des Jahres
  temp_summe = 0
  zähler = 0
  tages_durchschnitt_temp = 0
  gst = 0
  gst_erreicht = false

Das meiste von dem, was man dafür benötigt, kennst Du bereits und/oder ist in der einen oder anderen Automation zu finden. Für Wenn 23 Uhr reicht das Wenn-dann aus. Aber wenn man Wenn 23 Uhr und letzter Tag des Jahres abfragen möchte? Klick mal in Wenn-dann bei Wenn auf Baustein hinzufügen:

Hey! EinUnd! Das kommt ja wie gerufen! :smiling_face_with_sunglasses:

Da klicken wir einfach mal mal drauf. Mit Bedingung hinzufügen kann man nun beliebig viele Bedingungen hinzufügen, die alle erfüllt sein müssen, damit der Dann-Block abgearbeitet wird. Ist auch nur eine der Bedingungen nicht erfüllt, wird der Sonst-Block abgearbeitet.

Ein Hinweis am Rande: man muss nicht zwingend in beiden Blöcken (Dann und Sonst) Aktionen haben. Wo man welche Aktion einfügt, hängt davon ab, was und wie man abfragt bzw. was man erreichen möchte. Ein paar Beispiele sollten das verdeutlichen:

Wenn es regnet
dann nimm den Regenschirm mit
sonst

Wenn es nicht regnet
dann lass den Regenschirm zu Hause
sonst nimm den Regenschirm mit

Wenn es regnet und windig ist
dann zieh die Regenjacke an
sonst

Wenn es regnet
dann
sonst gieße die Blumen

Für unseren Fall

wenn 23:00 und letzter Tag des Jahres

bietet sich folgendes an:

  - if:
      - condition: and
        conditions:
          - condition: template
            value_template: "{{ now().hour == 23 }}"
          - condition: template
            value_template: "{{ now().year != (now()+timedelta(days=1)).year}}"

if {{ now().hour == 23 }} ist selbsterklärend.

Für die Abfrage letzter Tag des Jahres müssen wir ein bissl in die Trickkiste greifen. Das gibt es nicht out of the box. Mal schauen, was es so alles gibt:

now().year ergibt das aktuelle Jahr, also 2025.

now()+timedelta(days=1) addiert zu now einen Tag. Das Ergebnis ist dieser Zeitpunkt (jetzt / nun) genau 1 Tag (24 Stunden) später, also 22.10.2025, 22:30 Uhr

Hmmm … das kann man auch kombinieren ( now()+timedelta(days=1) ).year zeigt das Jahr, in welchem der Zeitpunkt jetzt + 1 Tag liegt. Das Ergebnis ist 2025. Nun … das Ergebnis ist immer 2025 - außer für den 31.12., weil der 31.12.2025 + 1 Tag der 01.01.2026 ist. D.h. die Abfrage

now().year != (now()+timedelta(days=1)).year

ergibt immer am 31.12. true, und zwar nur am 31.12.! :smiling_face_with_sunglasses:

Sooo … mit diesen ganzen Infos kannst Du wieder ein wenig weiter basteln. Fragen? Fragen! :wink:

Mich hat das auch gewundert, aber das stand so im YAML Code in HA.

Inzwischen habe ich alles kontrolliert und korrigiert.

Und du liegst richtig, ich komme inzwischen echt klar. Tausend Dank für die Geduld und ausführlichen Erklärungen.

Ich habe mir ein Synology NAS für zuhause gekauft und eingebunden.

Das hat in der Integration die Gesamtgröße und den belegten Speicher angezeigt, aber nicht den freien. Ich habe also ein Template gemacht, was die Differenz berechnet. Hat auf Anhieb geklappt.

{{ (states(‘sensor.ds3622xsplus_volume_1_gesamtgrosse’)|float) - states(‘sensor.ds3622xsplus_volume_1_belegter_speicherplatz’)| float}}

Danke auch für deinen Input mit dem Zusammenlegen der Automaitisierungen.

Das mit den Pausen habe ich gemacht, damit es sicher klappt. Ich brauche die Werte ja nicht sofort.

Aktuell habe ich keine Fragen. Ich setze das um, was du geschrieben hast und gehe dann daran, das tägliche Rasenwachstum zu berechnen. Ich weiß ja jetzt wie es geht.

Da nich für! :blush:

Dann noch viel Spaß mit dem Projekt und vielleicht gibst Du ja mal ein Update wenn es fertig ist und läuft?! :thinking:

Natürlich, gerne.

Das Blöde wird nur sein, dass es im Realbetrieb erst nächstes Jahr der Fall sein wird.

Ich kümmere mich aber um deine vorgeschlagenen Vereinfachungen und mache mich dann an das berechnete tägliche Rasenwachstum.

Das ist wohl wahr. Das ist aber auch gleichzeitig ein Vorteil, weil Du es bis dahin ausgiebig testen kannst. :wink: