Grünlandtemperatursumme (GTS) in Home Assistant: Vegetationsbeginn automatisch berechnen

Was ist die Grünlandtemperatursumme?

Die Grünlandtemperatursumme (GTS) ist ein agrarmeteorologischer Index, der in der Landwirtschaft seit Jahrzehnten verwendet wird, um den Beginn der Vegetationsperiode vorherzusagen. Entwickelt wurde das Verfahren, um einen zuverlässigen Anhaltspunkt zu geben, wann das Graswachstum einsetzt — und damit der richtige Zeitpunkt für die erste Düngung gekommen ist.

Das Prinzip

Ab dem 1. Januar werden die positiven Tagesmitteltemperaturen aufsummiert — allerdings nicht gleichmäßig:

MonatFaktorBegründung
Januar× 0,5Niedrige Sonneneinstrahlung, Boden meist gefroren
Februar× 0,75Übergangsmonat, Boden beginnt sich zu erwärmen
März – September× 1,0Volle Gewichtung

Negative Tagesmittel werden ignoriert — sie fließen als 0 in die Berechnung ein.

Sobald die Summe den Wert 200 °Cd (Gradtage) erreicht, gilt der nachhaltige Vegetationsbeginn als erreicht. In Deutschland ist das je nach Region und Witterung typischerweise zwischen Mitte Februar (mild, Rheingraben) und April (Mittelgebirgslagen).

Warum ist das relevant?

  • Düngeverordnung: Die erste Stickstoffdüngung auf Grünland darf erst nach Vegetationsbeginn erfolgen
  • Pflanzenschutz: Viele Schädlinge und Pilze werden mit Vegetationsbeginn aktiv
  • Gartenplanung: Auch für Hobbygärtner ein guter Indikator, wann es "losgeht"

Was wir bauen

Unser Home-Assistant-Setup besteht aus drei Komponenten:

  1. Helper — Speichern die Messwerte, Zähler und Ergebnisse
  2. Automation — Sammelt stündlich Temperaturen, berechnet Tageswerte und erstellt Prognosen
  3. Template-Sensor — Fasst alles in einem übersichtlichen Sensor mit Phasen-Anzeige zusammen

Am Ende erhältst du:

  • Einen GTS-Wert, der sich automatisch über das Jahr aufbaut
  • Eine Prognose basierend auf deiner Wetter-Integration, wann der Vegetationsbeginn erreicht wird
  • Benachrichtigungen, wenn es soweit ist
  • Einen Sensor mit Phasenangabe (Tiefwinter, Vorfrühling, Vegetationsbeginn, etc.)

Schritt 1: Helper anlegen

Wir benötigen insgesamt fünf input_number-Helper und einen input_boolean-Helper. Du kannst sie über Einstellungen → Geräte & Dienste → Helper → Helper erstellen anlegen, oder direkt in deiner configuration.yaml.

Variante A: Über die UI

Gehe zu Einstellungen → Geräte & Dienste → Helper und erstelle nacheinander:

1. GTS Gesamtwert

EigenschaftWert
NameGTS: Grünlandtemperatursumme
Entity-IDinput_number.gts
Minimum0
Maximum10000
Schrittweite0.01
Einheit°Cd
ModusBox
Iconmdi:sigma

2. Tagessumme Temperatur

EigenschaftWert
NameGTS: Tagessumme Temperatur
Entity-IDinput_number.gts_tagessumme_temp
Minimum-10000
Maximum10000
Schrittweite0.01
Einheit°C
ModusBox
Iconmdi:temperature-celsius

3. Anzahl Tagesmessungen

EigenschaftWert
NameGTS: Anzahl Tagesmessungen
Entity-IDinput_number.gts_tages_messungen
Minimum0
Maximum100
Schrittweite1
Einheit(leer)
ModusBox
Iconmdi:counter

4. GTS Prognosewert

EigenschaftWert
NameGTS: Prognosewert
Entity-IDinput_number.gts_prognose
Minimum0
Maximum10000
Schrittweite0.1
Einheit°Cd
ModusBox
Iconmdi:thermometer-alert

5. Tage bis Vegetationsbeginn

EigenschaftWert
NameGTS: Tage bis Vegetationsbeginn
Entity-IDinput_number.gts_tage_bis_vegetation
Minimum-1
Maximum365
Schrittweite1
EinheitTage
ModusSlider
Iconmdi:calendar-arrow-right

6. Vegetationsbeginn erreicht (Boolean)

EigenschaftWert
NameGTS: Vegetationsbeginn erreicht
Entity-IDinput_boolean.vegetationsbeginn_erreicht
Iconmdi:sprout

Variante B: Über configuration.yaml

Falls du es lieber in YAML definierst:

input_number:
  gts:
    name: "GTS: Grünlandtemperatursumme"
    min: 0
    max: 10000
    step: 0.01
    unit_of_measurement: "°Cd"
    icon: mdi:sigma
    mode: box

  gts_tagessumme_temp:
    name: "GTS: Tagessumme Temperatur"
    min: -10000
    max: 10000
    step: 0.01
    unit_of_measurement: "°C"
    icon: mdi:temperature-celsius
    mode: box

  gts_tages_messungen:
    name: "GTS: Anzahl Tagesmessungen"
    min: 0
    max: 100
    step: 1
    icon: mdi:counter
    mode: box

  gts_prognose:
    name: "GTS: Prognosewert"
    min: 0
    max: 10000
    step: 0.1
    unit_of_measurement: "°Cd"
    icon: mdi:thermometer-alert
    mode: box

  gts_tage_bis_vegetation:
    name: "GTS: Tage bis Vegetationsbeginn"
    min: -1
    max: 365
    step: 1
    unit_of_measurement: "Tage"
    icon: mdi:calendar-arrow-right
    mode: slider

input_boolean:
  vegetationsbeginn_erreicht:
    name: "GTS: Vegetationsbeginn erreicht"
    icon: mdi:sprout

Hinweis: Der Wert -1 bei "Tage bis Vegetationsbeginn" dient als Indikator, dass entweder der Vegetationsbeginn bereits erreicht wurde oder keine Prognose möglich ist.


Schritt 2: Die Automation

Die Automation ist das Herzstück des Systems. Sie erledigt vier Aufgaben:

  1. Stündlich Temperatur messen und aufsummieren
  2. Um 23:59 den Tageswert berechnen und zur GTS addieren
  3. Mehrmals täglich eine Prognose basierend auf Wetterdaten erstellen
  4. Am 30. September alles für das neue Jahr zurücksetzen

Voraussetzung

Du benötigst:

  • Einen Außentemperatur-Sensor (z.B. sensor.aussentemperatur)
  • Eine Wetter-Integration mit Vorhersagedaten (z.B. weather.zuhause — die Standard-Met.no-Integration funktioniert hier gut)

Automation anlegen

Gehe zu Einstellungen → Automatisierungen → Neue Automatisierung erstellen → In YAML bearbeiten und füge folgenden Code ein.

Wichtig: Passe die Entity-IDs sensor.aussentemperatur und weather.zuhause an deine eigenen Entitäten an!

alias: "GTS: Grünlandtemperatursumme"
description: >-
  Sammelt stündlich Temperaturen, berechnet Tageswert um 23:59 und setzt am 1.
  Januar zurück
triggers:
  - hours: /1
    id: stundlicher_sammler
    trigger: time_pattern
  - at: "23:59:00"
    id: tagesabschluss
    trigger: time
  - at: "08:00:00"
    id: prognose
    trigger: time
  - event: start
    id: prognose
    trigger: homeassistant
conditions:
  - condition: template
    value_template: "{{ now().month < 10 }}"
actions:
  - choose:
      - conditions:
          - condition: trigger
            id: stundlicher_sammler
        sequence:
          - target:
              entity_id: input_number.gts_tagessumme_temp
            data:
              value: |
                {{ states('input_number.gts_tagessumme_temp') | float(0)
                   + states('sensor.aussentemperatur') | float(0) }}
            action: input_number.set_value
            alias: Update
          - target:
              entity_id: input_number.gts_tages_messungen
            data:
              value: |
                {{ states('input_number.gts_tages_messungen') | float(0) + 1 }}
            action: input_number.set_value
            alias: Update
        alias: Regelmäßige Temperaturmessungen aufsummieren
      - conditions:
          - condition: trigger
            id: tagesabschluss
        sequence:
          - variables:
              messungen: "{{ states('input_number.gts_tages_messungen') | float(0) }}"
          - if:
              - condition: template
                value_template: "{{ messungen > 0 }}"
                alias: >-
                  Nur wenn messungen registriert wurden, kann Der GTS Tageswert
                  berechnet werden
            then:
              - variables:
                  tagesmittel: >
                    {% set m = states('input_number.gts_tages_messungen') |
                    float(0) %} {% if m > 0 %}
                      {{ (states('input_number.gts_tagessumme_temp') | float(0) / m) | round(2) }}
                    {% else %}
                      0
                    {% endif %}
                  monat: "{{ now().month }}"
                  faktor: >
                    {% set monat = now().month %} {% if monat == 1 %}0.5 {% elif
                    monat == 2 %}0.75 {% else %}1.0 {% endif %}
                  beitrag: >
                    {% set m = states('input_number.gts_tages_messungen') |
                    float(0) %} {% if m > 0 %}
                      {% set mittel = (states('input_number.gts_tagessumme_temp') | float(0) / m) %}
                      {% set faktor = 0.5 if now().month == 1 else (0.75 if now().month == 2 else 1.0) %}
                      {% if mittel > 0 %}
                        {{ (mittel * faktor) | round(2) }}
                      {% else %}
                        0
                      {% endif %}
                    {% else %}
                      0
                    {% endif %}
                  new_gts: >-
                    {{ states('input_number.gts') | float(0) + beitrag | float |
                    round(2) }}
              - target:
                  entity_id:
                    - input_number.gts
                data:
                  value: |
                    {{ new_gts }}
                action: input_number.set_value
              - data:
                  title: 🌱 GTS Tagesbericht {{ now().strftime('%d.%m.%Y') }}
                  message: >
                    Messungen heute: {{ messungen | int }} Tagesmittel: {{
                    tagesmittel }}°C Faktor (Monat {{ monat }}): {{ faktor }}
                    Beitrag heute: {{ beitrag }}°C GTS gesamt: {{ new_gts }}°Cd
                action: notify.persistent_notification
            else:
              - data:
                  title: Fehler bei GTS Tagesabschluss
                  message: >-
                    Heute wurden schieinbar keine Temperaturmessungen
                    durchgeführt. Daher konnte das Tagesmittel für den GTS nicht
                    berechnet werden.
                action: notify.persistent_notification
          - target:
              entity_id: input_number.gts_tagessumme_temp
            data:
              value: 0
            action: input_number.set_value
            alias: Reset
          - target:
              entity_id: input_number.gts_tages_messungen
            data:
              value: 0
            action: input_number.set_value
            alias: Reset
          - alias: Wenn GTS > 199.99, dann Flag Vegetaionsbeginn erreicht = true
            if:
              - condition: template
                value_template: "{{ new_gts > 199.99 }}"
            then:
              - action: input_boolean.turn_on
                metadata: {}
                target:
                  entity_id: input_boolean.vegetationsbeginn_erreicht
                data: {}
              - data:
                  title: 🟢 Vegetationsbeginn erreicht!
                  message: |
                    🌱 Vegetationsbeginn (GTS > 200 °Cd) wurde heute erreicht!
                action: notify.persistent_notification
          - alias: >-
              Ende September GTS-Status komplett zurücksetzen und für das
              kommende Jahr vorbereiten 
            condition: template
            value_template: |
              {{ now().month == 9 and now().day == 30 }}
          - target:
              entity_id:
                - input_number.gts
            data:
              value: 0
            action: input_number.set_value
            alias: Reset
          - action: input_boolean.turn_off
            metadata: {}
            target:
              entity_id: input_boolean.vegetationsbeginn_erreicht
            data: {}
        alias: Messpunkte zurücksetzten (Täglich und Jährlich)
      - conditions:
          - condition: trigger
            id: prognose
        sequence:
          - target:
              entity_id: weather.zuhause
            data:
              type: daily
            response_variable: forecast_data
            action: weather.get_forecasts
          - variables:
              prognose_raw: >-
                {% set gts_aktuell = states('input_number.gts') | float(0) %} {%
                set forecast = forecast_data['weather.zuhause']['forecast']
                %} {% set p = namespace(summe=gts_aktuell,  date=none) %} {% for
                tag in forecast %}
                  {% set datum = tag.datetime | as_datetime | as_local %}
                  {% set monat = datum.month %}
                  {% set faktor = 0.5 if monat == 1 else (0.75 if monat == 2 else 1.0) %}
                  {% set tmax = tag.temperature | float(0) %}
                  {% set tmin = tag.templow | float(0) %}
                  {% set tmittel = ((tmax + tmin) / 2) | round(2) %}
                  {% if tmittel > 0 %}
                    {% set p.summe = p.summe + (tmittel * faktor) %}
                  {% endif %}
                  {% if gts_aktuell < 200 and p.summe > 199.99 and p.date == none %}
                    {% set p.date = datum %}
                  {% endif %}
                {% endfor %} {{ p.summe | round(1) }};{{
                p.date.strftime('%d.%m.%Y') if p.date else 'none' }};{{
                (p.date.date() - now().date()).days if p.date else -1 }}
              prognose_neu: "{{ prognose_raw.split(';')[0] | float(0) }}"
              prognose_alt: "{{ states('input_number.gts_prognose') | float(0) }}"
              prognose_date: "{{ prognose_raw.split(';')[1] }}"
              prognose_days: "{{ prognose_raw.split(';')[2] | int(-1) }}"
          - target:
              entity_id: input_number.gts_prognose
            data:
              value: "{{ prognose_neu | float(1) }}"
            action: input_number.set_value
          - target:
              entity_id: input_number.gts_tage_bis_vegetation
            data:
              value: |
                {{ prognose_days }}
            action: input_number.set_value
          - choose:
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ prognosewert > 199.99 and prognosewert_old | float(1) <
                      200 }}
                sequence:
                  - data:
                      title: 🟡 Vegetationsbeginn wird bald erreicht!
                      message: >
                        🌱 Vegetationsbeginn (GTS > 200 °Cd) wird
                        vorraussichtlich am "{{ prognose_date }}" in "{{
                        prognose_days }}" erreicht!

                        GTS Wert: "{{ states('input_number.gts') }}"

                        GTS Prognose: "{{ prognose_neu }}"
                    action: notify.persistent_notification
                alias: Wenn Prognosewert erstmalig über 200 liegt
        alias: Prognose Daten auslesen

Was passiert wann?

Tabelle kopieren
TriggerZeitpunktAktion
stundlicher_sammlerJede volle StundeAußentemperatur ablesen und aufsummieren
tagesabschluss23:59 UhrTagesmittel berechnen, Faktor anwenden, GTS aktualisieren
prognose08:00, 12:00, 16:00 + HA-StartWettervorhersage abrufen, GTS hochrechnen

Die Monatsfaktoren im Detail

Die unterschiedliche Gewichtung nach Monat bildet ab, dass warme Januartage noch kaum Vegetationswirkung haben — der Boden ist gefroren, die Tage zu kurz. Erst ab März zählt jeder Gradtag voll:

 
Januar:    Tagesmittel × 0,50
Februar:   Tagesmittel × 0,75
März–Sep:  Tagesmittel × 1,00

Prognose-Logik

Die Prognose nutzt die weather.get_forecasts-Action deiner Wetter-Integration. Sie iteriert über die kommenden Tage, berechnet für jeden Tag das Mittel aus Hoch- und Tieftemperatur und summiert es mit den jeweiligen Monatsfaktoren auf die aktuelle GTS auf. So erhältst du eine Schätzung, wann der Wert 200 erreicht wird.


Schritt 3: Template-Sensor

Der Template-Sensor gibt dir einen übersichtlichen Gesamtstatus mit mehreren Attributen: aktuelle Phase, Jahreszeit, Fortschritt in Prozent und ob der Vegetationsbeginn bereits erreicht wurde.

Füge folgenden Code in deine configuration.yaml ein (oder in eine separate Datei, falls du Template-Sensoren ausgelagert hast):

template:
  - sensor:
      - name: "GTS: Status"
        unique_id: gts_status_001
        unit_of_measurement: "°Cd"
        icon: mdi:grass
        state: >
          {{ states('input_number.gts') | float(0) | round(1) }}
        attributes:
          phase: >
            {% set gts = states('input_number.gts') | float(0) %}
            {% set monat = now().month %}

            {# ========== WINTER (Dez - Feb) ========== #}
            {% if monat == 12 or (monat in [1, 2] and gts < 50) %}
              Tiefwinter ❄️
            {% elif monat in [1, 2] and gts < 100 %}
              Spätwinter 🌨️

            {# ========== VORFRÜHLING / FRÜHLING ========== #}
            {% elif gts < 50 %}
              Winterruhe ❄️
            {% elif gts < 100 %}
              Frühes Vorfrühjahr 🌨️
            {% elif gts < 150 %}
              Vorfrühjahr 🌤️
            {% elif gts < 200 %}
              Kurz vor Vegetationsbeginn 🌱
            {% elif gts < 300 %}
              Vegetationsbeginn ✅

            {# ========== SOMMER ========== #}
            {% elif monat in [6, 7, 8] and gts >= 300 %}
              Frühsommer 🌞
            {% elif monat == 6 and gts >= 400 %}
              Hochsommer ☀️
            {% elif monat in [7, 8] and gts >= 500 %}
              Hochsommer ☀️
            {% elif monat == 8 and gts >= 700 %}
              Spätsommer 🌤️

            {# ========== HERBST ========== #}
            {% elif monat == 9 %}
              Frühherbst 🍂
            {% elif monat == 10 %}
              Herbst 🍁
            {% elif monat == 11 and gts > 50 %}
              Spätherbst 🌫️
            {% elif monat == 11 %}
              Vorwinter 🌧️

            {# ========== FALLBACK ========== #}
            {% else %}
              Übergangszeit 🌈
            {% endif %}

          jahreszeit: >
            {% set monat = now().month %}
            {% if monat in [12, 1, 2] %}
              Winter ❄️
            {% elif monat in [3, 4, 5] %}
              Frühling 🌸
            {% elif monat in [6, 7, 8] %}
              Sommer ☀️
            {% else %}
              Herbst 🍂
            {% endif %}

          vegetationsbeginn_erreicht: >
            {{ states('input_number.gts') | float(0) >= 200 }}

          fortschritt_prozent: >
            {% set gts = states('input_number.gts') | float(0) %}
            {{ [((gts / 200) * 100) | round(0) | int, 100] | min }}

          prognose: >
            {{ states('input_number.gts_prognose') | float(0) | round(1) }}

          tage_bis_vegetation: >
            {{ states('input_number.gts_tage_bis_vegetation') | int(-1) }}
 

Attribute im Überblick

Tabelle kopieren
AttributBeschreibungBeispielwert
phaseAktuelle phänologische PhaseVorfrühjahr 🌤️
jahreszeitKalendarische JahreszeitFrühling 🌸
vegetationsbeginn_erreichtWurde GTS ≥ 200 erreicht?true / false
fortschritt_prozentFortschritt Richtung 200°Cd73
prognosePrognostizierter GTS-Endwert187.4
tage_bis_vegetationGeschätzte Tage bis Vegetationsbeginn12

Anpassungen

Anderen Temperatursensor verwenden

Ersetze in der Automation sensor.aussentemperatur durch deine eigene Entity-ID. Jeder Sensor mit Temperaturwerten in °C funktioniert.

Andere Wetter-Integration

Ersetze weather.zuhause an beiden Stellen in der Prognose-Sektion (im target und im Template bei forecast_data['weather.zuhause']).

Benachrichtigungen anpassen

Die Automation nutzt notify.persistent_notification, was Home-Assistant-interne Benachrichtigungen erzeugt. Du kannst das durch jeden anderen Notify-Dienst ersetzen, z.B.:

  • notify.mobile_app_dein_handy — Push-Nachricht
  • notify.telegram — Telegram-Bot
  • notify.email — E-Mail

Dashboard-Karte

Ein einfaches Beispiel für eine Dashboard-Karte:

type: entities
title: 🌱 Grünlandtemperatursumme
entities:
  - entity: sensor.gts_status
    name: GTS Wert
  - type: attribute
    entity: sensor.gts_status
    attribute: phase
    name: Phase
  - type: attribute
    entity: sensor.gts_status
    attribute: fortschritt_prozent
    name: Fortschritt
    suffix: "%"
  - type: attribute
    entity: sensor.gts_status
    attribute: prognose
    name: Prognose
    suffix: "°Cd"
  - type: attribute
    entity: sensor.gts_status
    attribute: tage_bis_vegetation
    name: Tage bis Vegetation
  - entity: input_boolean.vegetationsbeginn_erreicht
    name: Vegetationsbeginn erreicht

Fazit

Mit diesen drei Komponenten hast du ein vollständiges agrarmeteorologisches Messsystem in Home Assistant. Die stündliche Messung sorgt für ein verlässliches Tagesmittel, die Monatsfaktoren bilden die reale Vegetationswirkung ab, und die Prognose-Funktion gibt dir rechtzeitig Bescheid, wann es Zeit wird, den Dünger rauszuholen.

Die GTS ist natürlich nur ein Modell — regionale Besonderheiten, Bodenart und Exposition spielen ebenfalls eine Rolle. Aber als datengestützter Richtwert direkt aus deinem Smart Home ist sie ein starkes Werkzeug für jeden, der Grünland bewirtschaftet oder einfach wissen will, wann der Frühling wirklich beginnt. 🌱

Kommentare

PostadresseE-MailadresseFestnetzMobiltelefonSMS/SignalThreemaTwitter DirektnachrichtFAXWeb Page