Abwesenheitssteuerung für die Heizung

Im Haus meiner Eltern gibt es einen klassischen Geschlechter-Konflikt: Während meine Mutter es gern warm hat, kann aus der Sicht meines Vaters die Heizung gar nicht weit genug heruntergedreht sein. Dabei ist seine Motivation jedoch weder Gehässigkeit noch Hitzewallungen, sondern einfach Kostenerwägungen. Um beiden Seiten Rechnung zu tragen, habe ich eine Abwesenheitssteuerung realisiert.

Wann komme ich wieder?

Grundsätzlich hat mein Vater ja recht: Während eines Tagesausflugs oder bei einer Wochenendreise ergibt es keinen Sinn, dass die Heizung durchgehend läuft. Auf der anderen Seite ist es auch wenig Lebensqualität, wenn man die erste Stunde nach der Rückkehr die Winterjacke besser noch nicht auszieht. Gleichzeitig ist der Aufwand auch recht hoch, jedes Mal die Heizkörperthermostate manuell auf die geplante Rückkehr hin zu programmieren. Theoretisch wäre es denkbar, die persönlichen Smartphonekalender via CalDAV auszulesen, aus dem Ort des letzten Termins die Rückkehrzeit zu prognostizieren und die Heizung entsprechend anzusteuern. Jedoch bin selbst ich nicht so diszipliniert, alle Termine in meinem elektronischen Kalender zu vermerken. Trotzdem muss eine Möglichkeit her, der Homematic-Zentrale mitzuteilen, wann die Rückkehr geplant ist. Dazu nutze ich einen 6er-Wandtaster (Beschriftungsvorlage), neben der Eingangstür, der mit den gängigsten Varianten belegt ist:

Ein Wandtaster neben der Eingangstür, um dem System die voraussichtliche Rückkehr mitzuteilen.
  • Automatik: Steuerung über Aktivitäten im Haus.
  • ein: Schnelles Hochheizen und anschließende Rückkehr zum Tagestemperaturprofil.
  • heute Abend zurück: Heizung bis 18 Uhr abschalten, dann Rückkehr zum Tagestemperaturprofil.
  • morgen Abend zurück: Heizung bis 18 Uhr des Folgetages abschalten, dann Rückkehr zum Tagestemperaturprofil.
  • Montag zurück: Heizung bis zum kommenden Montag
    abschalten, dann Rückkehr zum Tagestemperaturprofil.
  • aus: Heizung abschalten, keine automatische Rückkehr.

Thermostate gruppieren

Immer schön gruppieren – es spart später sehr viel Arbeit, wenn die Skripte nicht angepasst werden müssen.

Es ist immer sinnvoll, die in einem Raum vorhandenen Thermostate zu gruppieren. Nicht nur, dass man sich bei zwei oder mehr Heizkörpern im Raum im Laufe seines Lebens doch einige Kilometer sinnlose Wege spart, wenn man nicht mehr von einem zum anderen laufen muss, um die Temperatureinstellung einzeln vorzunehmen. Aber auch wenn nur ein Thermostat vorhanden ist, muss in den Skripten früher oder später der Name oder die ID angesprochen werden. Wenn die Gruppe angesprochen wird, brauchen dann die Skripte nicht angepasst werden, wenn ein Heizkörperthermostat dazu kommt oder ausgetauscht werden soll.

Hilfsmittel Urlaubsmodus

Im Wesentlichen geht es in nahezu allen Fällen darum, das normale Tagestemperaturprofil für eine gewisse Zeit zu unterbrechen und die Heizung „in den Urlaub“ zu schicken. Dafür gibt es seit geraumer Zeit den Urlaubsmodus (englisch: Partymode), der genau dies leistet. Damit können wir uns sehr viel Geraffel, was wir sonst von Hand programmieren müssten, ersparen.

Dann muss nach Drücken der entsprechenden Taste nur noch der Endzeitpunkt ausgerechnet werden und der Urlaubszeitraum an die Heizkörperthermostate übertragen werden.

Grundsätzlich gibt es zwei Varianten, den Heizkörperthermostat mit den Daten zu füttern:

  1. jeden der Datenpunkte einzeln:
    • PARTY_START_TIME,
    • PARTY_START_DAY,
    • PARTY_START_MONTH,
    • PARTY_START_YEAR,
    • PARTY_STOP_TIME,
    • PARTY_STOP_DAY,
    • PARTY_STOP_MONTH,
    • PARTY_STOP_YEAR und
    • PARTY_TEMPERATURE.
  2. über den Datenpunkt PARTY_MODE_SUBMIT, der einen String mit allen Werten auf einmal aufnimmt.

Wenn man eine Sekunde darüber nachdenkt, dann kommt man nicht umhin, gleich zur Variante 2 zu greifen. Selbst wenn man nicht in einem fürstlichen Schloss wohnt und die Thermostate bereits pro Raum gruppiert hat, werden die Skripte sehr umfangreich und unübersichtlich, wenn jeder Datenpunkt einzeln gesetzt werden muss.

Der zu übergebende String wird die folgt aufgebaut:

  1. Temperatur (z. B. 16.0 – hier kein Komma verwenden!),
  2. Start-Uhrzeit in Minuten seit 0 Uhr auf 30 Minuten genau (z. B. 630 für 10:30 Uhr),
  3. Starttag (z. B. 13),
  4. Startmonat (z. B. 3),
  5. Letzte zwei Ziffern des Startjahres (z. B. 17 für 2017),
  6. End-Uhrzeit in Minuten seit 0 Uhr auf 30 Minuten genau (z. B. 660 für 11:00 Uhr),
  7. Endtag (z. B. 14),
  8. Endmonat (z. B. 3),
  9. Letzte zwei Ziffern des Endjahres (z. B. 17 für 2017)

Formatiert sieht das dann so aus:

16.0,630,13,03,17,660,14,03,17

Automatik

Die Automatik stützt sich auf die Systemvariable Anwesenheit. In dieser Installation wird diese durch Aktionen im Haus (Licht an/aus, Bewegungsmelder, Ändern der Einstellungen der Heizung etc.) ausgelöst und nach einer gewissen Zeit ohne Aktion auf abwesend geschaltet.

Die Idee bei dieser Funktion ist, dass wenn längere Zeit keine Aktionen im Haus stattgefunden haben, die Heizung automatisch abschaltet und – sobald wieder eine Anwesenheit festgestellt wird – wieder in die normalen Tagestemperaturprofile zurückgekehrt wird. Neben der Konfiguration auf der GUI der CCU ist nur ein Skript notwendig, welches etwaige noch existierende Urlaubszeiträume aus den Thermostaten löscht. Dies geschieht dadurch, dass einfach ein willkürlicher, in der Vergangenheit liegender Zeitraum gesetzt wird.

1
2
3
4
5
6
!etwaige Urlaubsmodi auflösen
 
String UMString = "16.0,0,01,01,17,30,01,01,17";
 
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_MODE_SUBMIT").State(UMString);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_MODE_SUBMIT").State(UMString);

Wer dies jedoch nicht über den Datenpunkt PARTY_MODE_SUBMIT, sondern die Datenpunkte lieber einzeln setzen möchte, kann es alternativ so machen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
!etwaige Urlaubsmodi auflösen
 
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_START_TIME").State(0);
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_START_DAY").State(1);
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_START_MONTH").State(1);
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_START_YEAR").State(17);
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_STOP_TIME").State(30);
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_STOP_DAY").State(1);
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_STOP_MONTH").State(1);
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_STOP_YEAR").State(17);
 
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_START_TIME").State(0);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_START_DAY").State(1);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_START_MONTH").State(1);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_START_YEAR").State(17);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_STOP_TIME").State(30);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_STOP_DAY").State(1);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_STOP_MONTH").State(1);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_STOP_YEAR").State(17);

Die Temperatur wird hierbei nicht gesetzt, da sie ohnehin nicht ausgelöst wird.

Das obige Programm hat grob gesprochen zwei Auslöser: Entweder ändert sich der Gesamtheitmodus auf Automatisch oder untertags ändert sich der Wert der Systemvariable Anwesenheit. Daher werden beide Variablen als Auslöser definiert, die jeweils andere wird nur geprüft.

Überraschende Rückkehr – Manuell einschalten

Bei aller Planung: Es passiert hin und wieder, dass die Abwesenheit vorher ändert. Natürlich besteht die Möglichkeit via VPN und Weboberfläche der CCU die Temperatur zu ändern. Nichtsdestotrotz sollte eine manuelle und einfache Möglichkeit unabhängig von Smartphone und Notebook existieren, die Heizung wieder einzuschalten. Dazu müssen auch hier erst einmal etwaige noch existierende Urlaubsmodi gelöscht werden. Danach werden die Temperaturen der Thermostate auf die Komfort-Temperatur gesetzt. Um das zu diesem Zeitpunkt aber gegebenenfalls etwas heruntergekühlte Haus schnell auf Betriebstemperatur zu bringen, wird anschließend ein Boost gestartet.

Rückkehr am heutigen Abend

Die Herausforderung besteht im Wesentlichen jetzt nur noch darin, wenn der Zustand „heute Abend zurück“ eintritt, den Rückkehrzeitpunkt zu berechnen und die Thermostate damit zu füttern:

1
2
3
4
5
6
7
8
!Urlaubsmodus bis heute Abend setzen
 
time UMEnde = system.Date("%F 18:00:00").ToTime();
 
string UMString = "16.0,"#( (system.Date("%H").ToInteger()*60)+system.Date("%M").ToInteger()-(system.Date("%M").ToInteger()%30) )#system.Date(",%d,%m,%y")#","#( (UMEnde.Format("%H").ToInteger()*60)+UMEnde.Format("%M").ToInteger()-(UMEnde.Format("%M").ToInteger()%30) )#UMEnde.Format(",%d,%m,%y");
 
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_MODE_SUBMIT").State(UMString);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_MODE_SUBMIT").State(UMString);

Erläuterung:

  • Zeile 3: Zunächst holen wir ein nach unseren Vorstellungen formatiertes Systemdatum, wobei dabei die Uhrzeit auf 18:00 h festgeschrieben wird.
  • Zeile 5: Zusammensetzen des PARTY-Strings:
    1. Festschreiben der Temperatur auf 16 Grad,
    2. Berechnung des Startzeitpunkts. Das geschieht über das Holen der aktuellen Stunde aus der Systemzeit, die dann mit 60 multipliziert wird, um die Minutenangabe zu erhalten. Da die PARTY allerdings eine halbstundengenaue Angabe benötigt, wird mittels Moduloberechnung die weiteren Minuten, die seit der letzten vollen halben Stunde vergangen ist, davon wieder abgezogen,
    3. Holen des aktuellen Tags, Monats und zweistelliger Jahreszahl. Da bei der Formatierung des Systemdatums das trennende Komma mitdefiniert werden kann, können wir alle drei Werte auf einmal holen,
    4. Berechnen des Endzeitpunkts auf volle halbe Stunde (analog zu 2). Theoretisch ist dies überflüssig, da die Angabe bereits halbstundengenau erfolgte – sie dient aber als Sicherung für die Zukunft, falls mal eine unvorsichtige Änderung vorgenommen wird.
  • Zeilen 7 und 8: Übergabe an die beiden Thermostatgruppen (pro Raum eine Gruppe).

Rückkehr am morgigen Abend

Dieser Fall ist prinzipiell identisch zu dem vorherigen, außer dass der Rückkehrzeitpunkt 24 Stunden (86400 Sekunden) weiter in der Zukunft liegt.

1
2
3
4
5
6
7
8
!Urlaubsmodus bis morgen Abend setzen
 
time UMEnde = (system.Date("%F 18:00:00").ToTime().ToInteger()+86400).ToTime().Format("%F %T").ToTime();
 
string UMString = "16.0,"#( (system.Date("%H").ToInteger()*60)+system.Date("%M").ToInteger()-(system.Date("%M").ToInteger()%30) )#system.Date(",%d,%m,%y")#","#( (UMEnde.Format("%H").ToInteger()*60)+UMEnde.Format("%M").ToInteger()-(UMEnde.Format("%M").ToInteger()%30) )#UMEnde.Format(",%d,%m,%y");
 
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_MODE_SUBMIT").State(UMString);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_MODE_SUBMIT").State(UMString);

Rückkehr am kommenden Montag

Auch dieser Fall nutzt den Urlaubsmodus identisch zu den vorherigen. Die Aufgabe besteht hier darin, den Timestamp der Rückkehr zu ermitteln. Da die Eltern gern Ausflüge über das Wochenende machen und gerne erst am Montag Morgen zurückkehren, soll bei Drücken der entsprechenden Taste die Heizung bis zum nächsten Montag 11:00 h ausgeschaltet werden und ab dann in das gewohnte Tagestemperaturprofil übergehen. Im Skript wird dazu das aktuelle Systemdatum abgefragt und abhängig vom aktuellen Wochentag entsprechend viele Tage addiert, um den nächsten Montag zu erreichen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
!Urlaubsmodus bis morgen Abend setzen
 
time UMEnde;
 
if (system.Date("%w")==0){ !heute ist Sonntag
   UMEnde = (system.Date("%F %T").ToTime().ToInteger()+(86400)).ToTime();
}
if (system.Date("%w")==1){ !heute ist Montag
   UMEnde = (system.Date("%F %T").ToTime().ToInteger()+(7*86400)).ToTime();
}
if (system.Date("%w")==2){ !heute ist Dienstag
   UMEnde = (system.Date("%F %T").ToTime().ToInteger()+(6*86400)).ToTime();
}
if (system.Date("%w")==3){ !heute ist Mittwoch
   UMEnde = (system.Date("%F %T").ToTime().ToInteger()+(5*86400)).ToTime();
}
if (system.Date("%w")==4){ !heute ist Donnerstag
   UMEnde = (system.Date("%F %T").ToTime().ToInteger()+(4*86400)).ToTime();
}
if (system.Date("%w")==5){ !heute ist Freitag
   UMEnde = (system.Date("%F %T").ToTime().ToInteger()+(3*86400)).ToTime();
}
if (system.Date("%w")==6){ !heute ist Samstag
   UMEnde = (system.Date("%F %T").ToTime().ToInteger()+(2*86400)).ToTime();
}
 
UMEnde = UMEnde.Format("%F 11:00:00").ToTime();
 
string UMString = "16.0,"#( (system.Date("%H").ToInteger()*60)+system.Date("%M").ToInteger()-(system.Date("%M").ToInteger()%30) )#system.Date(",%d,%m,%y")#","#( (UMEnde.Format("%H").ToInteger()*60)+UMEnde.Format("%M").ToInteger()-(UMEnde.Format("%M").ToInteger()%30) )#UMEnde.Format(",%d,%m,%y");
 
dom.GetObject("OG1_Bad_Heizung:1").DPByHssDP("PARTY_MODE_SUBMIT").State(UMString);
dom.GetObject("OG1_AZi_Hiltud_Heizung:1").DPByHssDP("PARTY_MODE_SUBMIT").State(UMString);

Vollständig aus

Diese Funktion ist entweder für den Sommerbetrieb oder einen längeren Urlaub vorgesehen, der nicht in das Standardfallschema passt.

Dafür wird zunächst wieder jegliche bereits existierenden Urlaubsspannen aus den Thermostaten gelöscht, um ein versehentliches Rückkehren in die Tagestemperaturprofile während der Abwesenheit zu verhindern. Anschließend werden die Thermostate einfach in den manuellen Modus mit entsprechender Temperaturvorgabe geschaltet.

Verwendete Komponenten:

Hinterlasse einen Kommentar.

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*