Hallo zusammen,
heute möchte ich euch mal meine Heizungssteuerung der Wohnung vorstellen.
“Es gibt doch schon 1000 Projekte davon. Warum du auch noch?” Nunja, wir haben eine Mietwohnung wo ausschließlich elektrische IR-Heizkörper installiert sind. Diese Heizkörper haben natürlich Vor- und Nachteile.
Vorteil:
- schaltet man sie ein, kommt es einem nach 5min warm vor
- Der Vermieter hat im Prinzip keinerlei Wartungskosten
- Sie sind absolut problemlos zu steuern, wenn sie “dumm” bleiben dürfen
Nachteil:
- die Heizkörper fressen unfassbar viel Strom (beim Einzug ca. 350€/Monat)
- lässt man sie länger eingeschaltet, werden sie sehr heiß (max. 110°C laut Datenblatt)
Punkt 1 der Nachteile ist natürlich ein riesiges Problem. Ich hatte zum Einzug eh mit einer HA-Instanz geliebäugelt und dachte mir “Auch, da machst du einfach ein paar Automationen und dann klappt das schon” - Denkste! So einen Heizkörper zu steuern ist tatsächlich ein wenig komplizierter als ich gedacht habe, zumindest wenn man ihn wirklich smart machen möchte.
Zuerst habe ich geschaut, was die Heizkörper für eine Leistung haben. Es waren dann zu zwischen 400 und 1100W und es ist ja eine rein ohmsche Last. Ich dachte, dass ein Shelly das problemlos meistert. Dann habe ich mal für ein anderes Projekt einen Shelly gebrickt und ihn mal geöffnet. Als ich das Innenleben sah, dachte ich mir, dass der das schalten nicht lange aushalten kann und begab mich auf die Suche nach anderen Aktoren (HmIP-FSI16), denen ich vertrauen könne. Ich bin dann bei HomematicIP hängen geblieben. Dazu sollten es dann die Wandthermostate(HmIP-WTH-1) vom gleichen Hersteller sein.
Dazu gab es dann noch einen USB-Stick, damit die Raspberrymatic mit den Geräten kommunizieren könnte.
Als ich alles soweit eingerichtet habe, habe ich gesehen, dass die Raspberrymatic eigene Heizprogramme hat und ich habe es erstmal getestet. Die Steuerung an sich funktionierte problemlos, ließ nur kein echtes “Das ist jetzt Smart-Gefühl” aufkommen, denn Events die HA erkennt, konnte ich innerhalb der Raspberrymatic nicht verwenden. Aber immerhin habe ich mir von der Steuerung einiges abschauen können, z.Bsp schaltet diese Steuerung den Heizkörper nicht dauerhaft an, sondern immer nur in Intervallen.
Ich nahm also die Heizungssteuerung der Raspberrymatic wieder außer Betrieb und setzte mich daran es in HA selbst umzusetzen und es so smart zu machen, wie es gerade noch machbar ist für mich.
So sieht mein aktuelles Dashboard für die Heizungssteuerung aus
Das wichtigste davon würde ich euch jetzt gerne näher erklären.
Unter Messwerte stehen erstmal ein paar Daten meines Außentermometers.
Bei Parameter gibt es dann ein paar numerische Helper mit denen ich Kontrolle über ein paar Dinge übernehmen kann, da ich in der Heizperiode sicher noch ein Feintuning brauchen werde.
- Freigabe Außentemperatur - wird die Außentemperatur unterschritten, bekommt die Heizung ihre Freigabe zu arbeiten.
Code für den Helper
initial: null
editable: true
min: 0
max: 100
step: 0.1
mode: box
friendly_name: Freigabe Außentemperatur
Dazu gehören zwei Helper vom Typ boolean und zwei kleine Automationen die die Freigabe erst aktiviert, wenn die Freigabetemperatur länger als eine Stunde unterschritten wurde.
Code für die beiden Helfer und die Automation
Helper “Freigabetemperatur erreicht”
editable: true
icon: mdi:thermometer-chevron-up
friendly_name: freigabetemperatur_erreicht
Helper “Heizung aktiv”
editable: true
icon: mdi:radiator
friendly_name: Heizung_aktiv
Automation “Freigabetemperatur erreicht”
id: '1717766043654'
alias: freigabetemperatur_erreicht
description: ''
trigger:
- platform: time_pattern
seconds: /10
condition: []
action:
- if:
- condition: numeric_state
entity_id: sensor.luftdaten_84145_temperatur
below: input_number.freigabe_aussentemperaturt
then:
- service: input_boolean.turn_on
target:
entity_id:
- input_boolean.freigabetemperatur_erreicht
data: {}
- if:
- condition: numeric_state
entity_id: sensor.luftdaten_84145_temperatur
above: input_number.freigabe_aussentemperaturt
then:
- service: input_boolean.turn_off
target:
entity_id:
- input_boolean.freigabetemperatur_erreicht
data: {}
mode: single
Automation “Freigabe Heizung”
id: '1717938431717'
alias: Freigabe Heizung
description: ''
trigger:
- platform: time_pattern
seconds: /30
condition: []
action:
- choose:
- conditions:
- condition: state
entity_id: input_boolean.freigabetemperatur_erreicht
state: 'on'
for:
hours: 1
minutes: 0
seconds: 0
sequence:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.heizung_aktiv
data: {}
- choose:
- conditions:
- condition: state
entity_id: input_boolean.freigabetemperatur_erreicht
state: 'off'
for:
hours: 1
minutes: 0
seconds: 0
sequence:
- service: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id: input_boolean.heizung_aktiv
mode: single
Als nächstes kommt ein numerischer Helfer für die Hysterese. Das ist ganz angenehm, damit die Heizung über längere Zeit mal einen Zusand annehmen kann. Ob ich das wirklich brauche wird der Live-Test im Winter zeigen.
Hysterese-Helfer
initial: null
editable: true
min: 0
max: 1
step: 0.2
mode: box
friendly_name: Hysterese
Die Steps habe ich auf 0,2 gestellt damit ich später besser rechnen kann.
Danach kommt die Temperatur, um die während der Nacht und wenn niemand zuhause ist, die Temperatur abgesenkt werden soll.
Helfer Nachtabsenkung
initial: null
editable: true
min: 0
max: 3
step: 0.1
mode: box
icon: mdi:temperature-celsius
friendly_name: nachtabsenkung
Den Maximalwert habe ich auf 3 gestellt, da ich nicht denke dass mehr Sinn ergibt.
Nun folgt noch ein Helfer für die Nachtabsenkung für das Schlafzimmer. Dieser hat einen Wert auf den die Temperatur abgesenkt werden soll, da wir eigentlich keine Heizung im Schlafzimmer möchten, während der Nacht, aber auch ein absolutes Minimum nicht unterschreiten möchten, sollte es mal wirklich kalt werden (wir schlafen auch im Winter immer mit gekippten Fenstern).
Helfer Nachtabsenkung Schlafzimmer
initial: null
editable: true
min: 0
max: 25
step: 0.1
mode: box
icon: mdi:temperature-celsius
friendly_name: nachtabsenkung_schlafzmmer
Nun kommen wir zu dem Feld Status.
Die beiden ersten Punkte, “Freigabetemperatur erreicht” und “Heizung aktiv” habe ich ja schon beschrieben. Danach kommen die boolean Helfer und Zeitpläne zu den verschiedenen Bereichen welche unterschiedlich behandelt werden sollen.
Zu den Helfern gibt es natürlich entsprechende Automationen und noch zusätzliche Helfer.
Nachtabsenkung - Helfer und Automationen
“Wir haben Besuch” ist ein boolean-Helfer
editable: true
icon: mdi:emoticon-happy
friendly_name: besuch_ist_da
Dazu gehört eine Automation
alias: Kalendertrigger Besuch
description: ""
trigger:
- platform: calendar
event: start
offset: "0:0:0"
entity_id: calendar.bianka_jorg
id: Start
- platform: calendar
event: end
offset: "0:0:0"
entity_id: calendar.bianka_jorg
id: Ende
condition:
- condition: template
value_template: "{{ trigger.calendar_event.summary is search('Schlagwort um zu erkennen ob Besuch kommt') }}"
action:
- if:
- condition: trigger
id:
- Start
then:
- service: input_boolean.turn_on
data: {}
target:
entity_id: input_boolean.besuch_ist_da
- if:
- condition: trigger
id:
- Ende
then:
- service: input_boolean.turn_off
data: {}
target:
entity_id: input_boolean.besuch_ist_da
mode: single
“Jemand zuhause” noch ein boolean-Helfer
editable: true
icon: mdi:account
friendly_name: Jemand zuhause
Und die passende Automation dazu
id: '1718269761200'
alias: Jemand_zuhause_automation
description: ''
trigger:
- platform: time_pattern
seconds: /5
condition: []
action:
- if:
- condition: or
conditions:
- condition: state
entity_id: person.bianka
state: home
- condition: state
entity_id: person.sparki
state: home
then:
- service: input_boolean.turn_on
metadata: {}
data: {}
target:
entity_id: input_boolean.jemand_zuhause
else:
- service: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id: input_boolean.jemand_zuhause
mode: single
Als nächstes kommen dann die Zeitpläne
# Zeitpläne
schedule:
# Nachtabsenkung von Wohnzimmer, Gästezimmer, Küche, Flur
nachtabsenkung_main_schedule:
name: "nachtabsenkung_main_schedule"
monday:
- from: "00:00:00"
to: "07:00:00"
- from: "22:00:00"
to: "24:00:00"
tuesday:
- from: "00:00:00"
to: "07:00:00"
- from: "22:00:00"
to: "24:00:00"
wednesday:
- from: "00:00:00"
to: "07:00:00"
- from: "22:00:00"
to: "24:00:00"
thursday:
- from: "00:00:00"
to: "07:00:00"
- from: "22:00:00"
to: "24:00:00"
friday:
- from: "00:00:00"
to: "07:00:00"
- from: "23:00:00"
to: "24:00:00"
saturday:
- from: "00:00:00"
to: "08:00:00"
- from: "23:00:00"
to: "24:00:00"
sunday:
- from: "00:00:00"
to: "08:00:00"
- from: "22:00:00"
to: "24:00:00"
# Nachtabsenkung für Bad
nachtabsenkung_bath_schedule:
name: "nachtabsenkung_bath_schedule"
monday:
- from: "00:00:00"
to: "04:00:00"
- from: "22:30:00"
to: "24:00:00"
tuesday:
- from: "00:00:00"
to: "04:00:00"
- from: "22:30:00"
to: "24:00:00"
wednesday:
- from: "00:00:00"
to: "04:00:00"
- from: "22:30:00"
to: "24:00:00"
thursday:
- from: "00:00:00"
to: "04:00:00"
- from: "22:30:00"
to: "24:00:00"
friday:
- from: "00:00:00"
to: "04:00:00"
- from: "23:30:00"
to: "24:00:00"
saturday:
- from: "00:00:00"
to: "07:00:00"
- from: "23:00:00"
to: "24:00:00"
sunday:
- from: "00:00:00"
to: "07:00:00"
- from: "22:30:00"
to: "24:00:00"
# Nachtabsenkung für Schlafzimmer
nachtabsenkung_sleepingroom_schedule:
name: "nachtabsenkung_sleepingroom_schedule"
monday:
- from: "00:00:00"
to: "07:00:00"
- from: "20:00:00"
to: "24:00:00"
tuesday:
- from: "00:00:00"
to: "07:00:00"
- from: "20:00:00"
to: "24:00:00"
wednesday:
- from: "00:00:00"
to: "07:00:00"
- from: "20:00:00"
to: "24:00:00"
thursday:
- from: "00:00:00"
to: "07:00:00"
- from: "20:00:00"
to: "24:00:00"
friday:
- from: "00:00:00"
to: "07:00:00"
- from: "22:00:00"
to: "24:00:00"
saturday:
- from: "00:00:00"
to: "08:00:00"
- from: "22:00:00"
to: "24:00:00"
sunday:
- from: "00:00:00"
to: "08:00:00"
- from: "20:00:00"
to: "24:00:00"
Jetzt noch die Automationen zu den Nachtabsenkungen der Bereiche
Alle Räume außer Bad- und Schlafzimmer
alias: nachtabsenkung_main_aktive_automation
description: ""
trigger:
- platform: time_pattern
minutes: /1
condition: []
action:
- if:
- condition: or
conditions:
- condition: state
entity_id: schedule.nachtabsenkung_main_schedule
state: "on"
- condition: and
conditions:
- condition: state
entity_id: schedule.nachtabsenkung_main_schedule
state: "off"
- condition: state
entity_id: input_boolean.besuch_ist_da
state: "off"
- condition: state
entity_id: input_boolean.jemand_zuhause
state: "off"
then:
- service: input_boolean.turn_on
metadata: {}
data: {}
target:
entity_id: input_boolean.nachtabsenkung_aktiv
else:
- service: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id: input_boolean.nachtabsenkung_aktiv
mode: single
Schlafzimmer
alias: nachtabsenkung_sleepingroom_aktive_automation
description: ""
trigger:
- platform: time_pattern
minutes: /1
condition: []
action:
- if:
- condition: or
conditions:
- condition: state
entity_id: schedule.nachtabsenkung_sleepingroom_schedule
state: "on"
- condition: and
conditions:
- condition: state
entity_id: schedule.nachtabsenkung_sleepingroom_schedule
state: "off"
- condition: state
entity_id: input_boolean.besuch_ist_da
state: "off"
- condition: state
entity_id: input_boolean.jemand_zuhause
state: "off"
then:
- service: input_boolean.turn_on
metadata: {}
data: {}
target:
entity_id:
- input_boolean.nachtabsenkung_schlafzimmer_aktiv
else:
- service: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id:
- input_boolean.nachtabsenkung_schlafzimmer_aktiv
mode: single
und das Badezimmer
alias: nachtabsenkung_bath_aktive_automation
description: ""
trigger:
- platform: time_pattern
minutes: /1
condition: []
action:
- if:
- condition: or
conditions:
- condition: state
entity_id: schedule.nachtabsenkung_bath_schedule
state: "on"
- condition: and
conditions:
- condition: state
entity_id: schedule.nachtabsenkung_bath_schedule
state: "off"
- condition: state
entity_id: input_boolean.besuch_ist_da
state: "off"
- condition: state
entity_id: input_boolean.jemand_zuhause
state: "off"
then:
- service: input_boolean.turn_on
metadata: {}
data: {}
target:
entity_id:
- input_boolean.nachtabsenkung_bad_aktiv
else:
- service: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id:
- input_boolean.nachtabsenkung_bad_aktiv
mode: single
Die Zeitpläne und Abfragen sind so eingestellt, dass ich mich nicht darum kümmern muss ob gerade jemand krank ist, wir Urlaub haben, jemand Homeoffice macht, oder wir Besuch haben, wir aber trotzdem arbeiten. Nachts wird immer abgesenkt und das bleibt an normalen Arbeitstagen auch solange abgesenkt, bis jemand zum Feierabend, zuhause ist.
Zum Schluss möchte ich euch dann noch, exemplarisch, einen Raum (Flur), mit der zugehörigen Steurung vorstellen.
Oben steht erstmal die climate-Entität meiner Wandthermostate, die mir die Soll-Temperatur, Ist-Temperatur und rel. Luftfeuchtigkeit anzeigt. Klickt man darauf, kann man die Soll-Temperatur einstellen, welche dann auch vom Wandthermostat übernommen wird.
Danach kommen zwei Templatesensoren die mir dabei helfen die Automationen viel übersichtlicher zu halten. Zuerst wollte ich alles in einer Automation erledigen aber das war einfach viel zu kompliziert, war unleserlich und hat dann auch nicht funktioniert. Großer Lerneffekt: Unterteile große Probleme in möglichst kleine, löse dann die kleinen nacheinander!
Danach kommt noch ein boolean-Helfer um mir den Status des Aktors anzuzeigen. Es war eigentlich erstmal nur zum debuggen gedacht, aber jetzt finde ich das ganz praktisch.
Automation für einen Raum (Flur)
Template-Sensoren für Soll-max und Soll-min
template:
- sensor:
# Flur
- name: "flur_soll_max"
unit_of_measurement: "°C"
device_class: "temperature"
state: >
{% set nachtabsenkung = states('input_boolean.nachtabsenkung_aktiv')|bool(default=false) %}
{% set floor_temp = float(state_attr( 'climate.hmip_wth_2_flur', 'temperature' ), default=20.0) %}
{% set hysterese = float(states('input_number.hysterese'), default=0.4) / 2 %}
{% set absenkung_degC = float(states('input_number.nachtabsenkung'), default=0.0) %}
{{ floor_temp + hysterese - (absenkung_degC if nachtabsenkung else 0.0) }}
- name: "flur_soll_min"
unit_of_measurement: "°C"
device_class: "temperature"
state: >
{% set nachtabsenkung = states('input_boolean.nachtabsenkung_aktiv')|bool(default=false) %}
{% set floor_temp = float(state_attr( 'climate.hmip_wth_2_flur', 'temperature' ), default=20.0) %}
{% set hysterese = float(states('input_number.hysterese'), default=0.4) / 2 %}
{% set absenkung_degC = float(states('input_number.nachtabsenkung'), default=0.0) %}
{{ floor_temp - hysterese - (absenkung_degC if nachtabsenkung else 0.0) }}
Hilfs-boolean-Helper
editable: true
icon: mdi:radiator
friendly_name: heizung_flur_aktive
Und zum Abschluss noch die Automation für den Heizkörper im Flur
alias: Flur_Heizkörper_einschalten
description: ""
trigger:
- platform: time_pattern
seconds: /10
condition:
- condition: and
conditions:
- condition: numeric_state
entity_id: sensor.hmip_wth_2_flur_actual_temperature
below: sensor.flur_soll_max
- condition: state
entity_id: input_boolean.heizung_aktiv
state: "on"
action:
- repeat:
sequence:
- service: input_boolean.turn_on
metadata: {}
data: {}
target:
entity_id:
- input_boolean.heizung_flur_aktive
- service: switch.turn_on
metadata: {}
data: {}
target:
entity_id: switch.flur_aktor_heizung
- delay:
hours: 0
minutes: 5
seconds: 0
milliseconds: 0
- service: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id:
- input_boolean.heizung_flur_aktive
- service: switch.turn_off
metadata: {}
data: {}
target:
entity_id: switch.flur_aktor_heizung
- delay:
hours: 0
minutes: 5
seconds: 0
milliseconds: 0
while:
- condition: numeric_state
entity_id: sensor.hmip_wth_2_flur_actual_temperature
below: sensor.flur_soll_max
- service: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id:
- input_boolean.heizung_flur_aktive
- service: switch.turn_off
metadata: {}
data: {}
target:
entity_id: switch.flur_aktor_heizung
mode: single
Da in dieser Automation eine Wiederholung vorkommt und ich Angst habe, dass diese einmal ungünstig abgebrochen werden könnte, habe ich zum Abschluss noch einmal den Heizkörper ausgeschaltet.
Was bei meinen Automationen vielleicht auffällt, dass ich immer einen time_pattern als Auslöser benutze. Das hat den Hintergrund dass dies der einzige Trigger ist, den ich zuverlässig zum Laufen bekommen habe.
Am Anfang habe ich versucht die Automation zu triggern, wenn die Ist-Temperatur im Raum unter den Sollwert fällt. Das funktionierte bei mir mir aber nicht wenn die Soll-Temperatur unter dem Ist-Wert war und ich den Soll-Wert, am Thermostat nach unten gestellt habe.
Jetzt bleibt mir erstmal nur zu hoffen dass ich vielleicht einem mit meiner Vorstellung geholfen und alle anderen nicht gelangweilt habe.
Sollte jemand noch Fragen oder Anregungen haben, immer gern raus damit.
Viele Grüße
Sparki