Heizungssteuerung Teil 3

Hier nun Teil drei auf meinem Weg zur smarten Heizungssteuerung.

Ich habe die Steuerung meine Heizung komplett über Home Assistant selbst gemacht, nachdem ich mit Better Thermostat keine so gute Erfahrung gemacht habe. Ein weiterer Grund ist, dass ich Heizkörper Thermostate verschiedener Hersteller habe.

Aber zu der Steuerung

Zunächst habe ich mal einige Helper angelegt, die ich in den Automatisierungen nutze:

Heizungssteuerung Teil 3
  • HZ_Nachttemperatur ist als Helper für die Nachtabsenkung.
  • HZ_Tagtemperatur ist als Helper für die Tagestemperatur.
  • HZ_Solltemperatur Wohnzimmer ist als Helper für die Solltemperatur für die Heizkörper im Wohnzimmer.
  • HZ_Solltemperatur Bad ist als Helper für die Solltemperatur für die Heizkörper im Bad.
  • HZ_Steuerung_An_Aus hebt die Automatisierung auf.
  • HeizungSzenen sind meine unterschiedlichen Anforderungen an die Heizungssteuerung:
    • – Di % Do in Köln, meine standard Tage im Büro
    • – Nachtabsenkung -> Nachtabsenkung z.B. wg. Urlaub
    • – Zuhause -> alles auf Tagtemperatur
    • – in Köln außergewöhnlicher Tag im Büro

HZ_Nacht bzw _Tagtemperatur sind meine beiden Temperaturvorgaben für nachts/ tagsüber. Die Automatisierung setzt dann je nach der ausgewählten Szene die Solltemperatur der Räume auf den Nacht- oder den Tag-Wert.
Da die Thermostate meist keine gute Offsetsteuerung haben, messe ich die Raumtemperatur mit einem Thermometer im Raum und steuere dann alle 10 min jedes Thermostat nach.

Die Auswahl der Szene steuert den Ablauf der Heizungssteuerung.
Z.B. Di & Do in Köln, dann geht morgens um 6:00Uhr alles auf Tagtemperatur, Di & Do schaltet die Heizung aber in der BüroZeit (7:00-17:00Uhr) auf Nachttemperatur um um 17:00Uhr wieder auf die Tag-Temperatur zu erhöhen.
Die Szene Nachtabsenkung setzt alle Thermostate dauerhaft auf Nachtemperatur. Meist läuft bei mir die Szene „Di & Do in Köln“, da dies mein Standard ist.
Jetzt mal im Detail:

Eine Automatisierung reagiert auf die Auswahl im DropDown der Szenen und dann hat jede Szene eine Automatisierung, die je nach Auswahl deaktiviert – oder aktiviert wird. Zum Teil wird die Automatisierung dann auch gestartet, um die gewollten Temperaturwerte einzustellen.

Yaml Code Heizungssteuerung

Wie oben erwähnt kommt dann je Szene eine Automatisierung, hier die „Di & Do in Köln“.

Heizungssteuerung Teil 3

Jede der Automatisierung für eine Szene beginnt mit Triggern, die meine Zeiten abdecken.

Ich bin dienstags und donnerstags im Büro, dann muss ich „nur“ ins Bad und komme dann im Nachmittag zurück. An den Tagen lasse ich das Bad hochfahren morgens und zum Feierabend mache ich alle Heizungen wieder an. In der Zwischenzeit steht alles auf Nachtabsenkung.
An den anderen Tagen bin ich im HomeOffice, da muss auch der Wohnraum angeheizt werden. Am Wochenende stehen wir später auf, da beginnt das Heizen erst um 8:00Uhr. Gegen 23:00Uhr gehen wir normal schlafen, also fährt die Heizung um 22:00Uhr runter.
Diese Trigger sind in allen Automatisierungen für die Heizungsszenen gleich, die Aktionen unterschieden sich.

Heizungssteuerung Teil 3

Trigger können IDs haben, die dann wieder von den Aktionen ausgewertet werden, so kann die Aktion je nach Uhrzeit angesteuert werden und über eine Bedingung noch nach Wochentag(en) unterschieden werden.

Das ist das Grundgerüst, jetzt müssen „nur“ noch je nach Bedingung die TemperaturSoll-Werte für alle Thermostate gesetzt werden.

Heizungssteuerung Teil 3

Damit ich die Steuerung ausschalten und „per Hand“ alles steuern kann, gibt es den Helper HZ_Steuerung_An_Aus, den die Automatisierung prüft. Ist HZ_Steuerung AN, werden die Automatisierungen und damit die Zeitsteuerungen ausgeführt, wenn HZ_Steuerung aus ist, kann über die Helper HZ_SollTempertur & HZ_Nachttemperatur die Steuerung manuell erfolgen.
Dies ist einfach mit einer Bedingung auf den Helper in jeder Automatisierung gelöst.

Jetzt kommt das Offset noch einmal ins Spiel, wenn die Solltemperatur für den Raum nicht gleich der gemessenen Temperatur im Raum ist, müssen alle Thermostate an den Heizkörpern höher eingestellt werden.
Den Offset pro Raum berechne ich über einen Template Sensor, der in der configuration.yaml definiert ist.

YAML Code OffSet Sensor

template:

  • sensor:
    • name: „Bad1OGZimmerOffset“
      state: >
      {{ (states.input_number.HZ_Solltemperatur_Bad1OG.state | float) – (states.sensor.bad_1og.state | float ) }}
    • name: „WohnZimmerOffset“
      state: >
      {{ (states.input_number.hz_solltemperatur_wohnesszimmer.state | float) – (states.sensor.wohnzimmer.state | float ) }}

Das Raumthermostat, dass früher die Heizung gesteuert hat, habe ich durch einen Shelly ersetzt, der das zentrale Raumthermostat simuliert und die Heizung komplett ausstellt, wenn alle Räume auf ihrer eingestellten Solltemperatur sind.

YAML Code Offset Raumthermostat Steuerung

Ich habe insgesamt neun Heizkörperthermostate in 7 Räumem zu steuern, dass wollte ich jetzt nicht x mal in den Automatisierungen per Copy&Passt haben, daher habe ich im nächsten Schritt, das eigendliche Einstellen der Zieltemperatur als Script ausgelagert.
Dies Script bekommt dann von der Automatisierung die Variablen übergeben, die es braucht.

Das Script schaut, ob die berechnete Zieltemperatur schon eingestellt ist, wenn nicht, regelt es das Thermostat hoch oder runter.

Jetzt zu der eigentlichen Automatisierung, hier der Code für meine Standard Automatisierung „Di&Do in Köln“ Diese setzt in Abhänigkeit von der Uhrzeit und dem Wochentag die Helper für die Raum-Soll-Temperaturen.

Automatisierung

alias: Heizung_di_do_koeln
description: „“
trigger:

  • platform: time
    at: „06:05:00“
    id: „6“
  • platform: time
    at: „07:05:00“
    id: „7“
  • platform: time
    at: „08:05:00“
    id: „8“
  • platform: time
    at: „17:05:00“
    id: „17“
  • platform: time
    at: „22:35:00“
    id: „22“
    condition:
  • condition: state
    entity_id: input_boolean.hz_steuerung_an_aus
    state: „on“
    action:
  • choose:
    • conditions:
      • condition: trigger id:
        • „6“
      • condition: time weekday:
        • tue
        • thu
          sequence:
        • service: input_number.set_value
          data:
          value: „{{states(‚input_number.hz_tagtemperatur‘)}}“
          target:
          entity_id:
          – input_number.hz_solltemperatur_bad1og
        • conditions:
          • condition: trigger id:
            • „7“
          • condition: time weekday:
            • tue
            • thu
              sequence:
          • service: input_number.set_value
            data:
            value: „{{states(‚input_number.hz_nachttemperatur‘)}}“
            target:
            entity_id:
            – input_number.hz_solltemperatur_wohnesszimmer
            – input_number.hz_solltemperatur_bad1og
          • conditions:
            • condition: trigger id:
              • „7“
            • condition: time weekday:
              • mon
              • wed
              • fri
                sequence:
            • service: input_number.set_value
              data:
              value: „{{states(‚input_number.hz_tagtemperatur‘)}}“
              target:
              entity_id:
              – input_number.hz_solltemperatur_wohnesszimmer
              – input_number.hz_solltemperatur_bad1og
            • conditions:
              • condition: trigger id:
                • „8“
              • condition: time weekday:
                • sun
                • mon
                • wed
                • fri
                • sat
                  sequence:
              • service: input_number.set_value
                data:
                value: „{{states(‚input_number.hz_tagtemperatur‘)}}“
                target:
                entity_id:
                – input_number.hz_solltemperatur_wohnesszimmer
                – input_number.hz_solltemperatur_bad1og
              • conditions:
                • condition: trigger id:
                  • „17“
                • condition: time weekday:
                  • tue
                  • thu
                    sequence:
                  • service: input_number.set_value
                    data:
                    value: „{{states(‚input_number.hz_tagtemperatur‘)}}“
                    target:
                    entity_id:
                    – input_number.hz_solltemperatur_wohnesszimmer
                    – input_number.hz_solltemperatur_bad1og
                  • conditions:
                    • condition: trigger id:
                      • „22“
                        sequence:
                      • service: input_number.set_value
                        data:
                        value: „{{states(‚input_number.hz_nachttemperatur‘)}}“
                        target:
                        entity_id:
                        – input_number.hz_solltemperatur_wohnesszimmer
                        – input_number.hz_solltemperatur_bad1og
                        default: []
                        mode: single

Alle 10 min läuft dann eine Automatisierung, die die einzelen Thermostate in Abhänigkeit zur Soll-Raum-Temperatur einstellt, so der .

Automatisierung zur Thermostatsteuerung

alias: HZ_Neu_mit_Script
description: „“
trigger:

  • platform: time_pattern
    minutes: /10
    enabled: true
    condition:
  • condition: state
    entity_id: input_boolean.hz_steuerung_an_aus
    state: „on“
    action:
  • service: script.1704663143799
    data:
    entity: climate.esszimmer
    solltemp: “ {{states.input_number.hz_solltemperatur_wohnesszimmer.state |float(0)}}“
    offset: „{{states.sensor.wohnzimmeroffset.state |float(0) }}“
    factor: 5
    enabled: true
  • service: script.1704663143799
    data:
    entity: climate.wohnzimmer_fenster_thermostat
    solltemp: “ {{states.input_number.hz_solltemperatur_wohnesszimmer.state |float(0)}}“
    offset: „{{states.sensor.wohnzimmeroffset.state |float(0) }}“
    factor: 5
    enabled: true
  • service: script.1704663143799
    data:
    entity: climate.schlafzimmmer
    solltemp: “ {{states.input_number.hz_solltemperatur_wohnesszimmer.state |float(0)}}“
    offset: „{{states.sensor.schlafzimmeroffset.state |float(0) }}“
    factor: 15
  • service: script.1704663143799
    data:
    entity: climate.kuche
    solltemp: “ {{states.input_number.hz_solltemperatur_wohnesszimmer.state |float(0)}}“
    offset: „{{states.sensor.KuecheOffset.state |float(0) }}“
    factor: 5
    enabled: true
  • service: script.1704663143799
    data:
    entity: climate.bad_1_og
    solltemp: “ {{states.input_number.hz_solltemperatur_bad1og.state |float(0)}}“
    offset: „{{states.sensor.bad1ogzimmeroffset.state |float(0) }}“
    factor: 5
    enabled: true
  • service: script.1704663143799
    data:
    entity: climate.bad_1_og_fenster
    solltemp: “ {{states.input_number.hz_solltemperatur_bad1og.state |float(0)}}“
    offset: „{{states.sensor.bad1ogzimmeroffset.state |float(0) }}“
    factor: 5
    enabled: true
  • if:
    • condition: numeric_state
      entity_id: sensor.wohnzimmeroffset
      below: 0.1
    • condition: and conditions:
      • condition: numeric_state
        entity_id: sensor.bad1ogzimmeroffset
        below: 0.1
    • condition: and conditions:
      • condition: numeric_state
        entity_id: sensor.SchlafZimmerOffset
        below: 0.1
        enabled: true
        then:
    • service: switch.turn_off
      data: {}
      target:
      entity_id:
      – switch.shelly1l_heizung
      else:
    • service: switch.turn_on
      data: {}
      target:
      entity_id: switch.shelly1l_heizung
      enabled: true

Diese Automatisierung startet dann dies Script pro Thermostat.

Script zur Einstellung der Thermostate

alias: HZ_set_temperatur
sequence:

  • variables:
    sollZimmmer: >-
    {{offset |float() * factor |float() +
    state_attr(entity,’current_temperature‘) | float(0)}}
    mintemp: „{{state_attr(entity,’min_temp‘)}}“
    maxtemp: „{{state_attr(entity,’max_temp‘)}}“
    TRVist: „{{state_attr(entity,’temperature‘)}}“
  • service: climate.set_temperature
    data:
    entity_id: „{{ entity }}“
    temperature: |-
    {% if sollZimmmer < mintemp -%} {{mintemp | float | round(0) }} {%- else -%} {% if sollZimmmer > maxtemp -%}
    {{maxtemp | float | round(0)}}
    {%- else -%}
    {{sollZimmmer |float | round(0)}}
    {%- endif %}
    {%- endif %}
    enabled: false
  • service: persistent_notification.create
    data:
    title: richtig
    message: “ {{entity}} {{(state_attr(entity,’temperature‘) – sollZimmmer) | float | round(0)}}“
    enabled: false
  • if:
    • condition: template
      value_template: „{{ offset | float != 0 }}“
      enabled: true
    • condition: and conditions:
      • condition: template
        value_template: >-
        {{sollZimmmer | float | round(0) != (TRVist | float |round(0))
        }}
        then:
    • service: climate.set_temperature
      data:
      entity_id: „{{ entity }}“
      temperature: |-
      {% if sollZimmmer < mintemp -%} {{mintemp | float | round(0) }} {%- else -%} {% if sollZimmmer > maxtemp -%}
      {{maxtemp | float | round(0)}}
      {%- else -%}
      {{sollZimmmer |float | round(0)}}
      {%- endif %}
      {%- endif %}
      enabled: true
    • service: persistent_notification.create
      data:
      title: true
      message: >-
      Device {{ entity }}. offset ist {{offset}} soll ist
      {{sollZimmer}} ist {{TRVist}}
      enabled: false
      enabled: true
      else:
    • service: persistent_notification.create
      data:
      title: falsch
      message: >-
      Device {{ entity }}. offset ist {{offset}} soll ist
      {{sollZimmer}} ist {{TRVist}}
      enabled: false
      mode: queued

Schreibe einen Kommentar