Same Procedure as Every Year, James

Öfter mal was neues: Ein neues Konzept für ein Wärmebedarfsrelais ohne Temperaturmessung

Also ich lasse die Dinge ja gerne mal schleifen, aber dass ich zu wenige Wärmebedarfsrelais programmiert hätte, das kann wirklich keiner sagen.

Neue Script-Funktionen

Mit Firmware 2.29.22 wurden neue Funktionen in der Scriptsprache der CCU eingeführt, die auf dieser Seite genutzt werden. Achten Sie darauf, als Logikschicht-Version in den Systemeinstellungen der CCU nicht „Legacy“ zu wählen.

Wenn Sie eine ältere Firmware verwenden oder als Logikschicht-Version „Legacy“ ausgewählt haben, werden Sie Script-Fehler angezeigt bekommen, wenn Sie diese Anleitung umsetzen. Die Programme werden nicht funktionieren.

Aktualisieren Sie die Firmware Ihrer CCU! Wählen Sie „Standard“ als Logikschicht-Version aus!

Variablen in HomeMatic-Scripten

Die CCU hatte früher ein Limit von maximal 200 Variablen, das mit Firmware-Version 2.29.18 aufgehoben wurde. Dieses Limit bezog sich auf alle Variablen, die in allen Scripten verwendet werden. Gemeint sind Variablen, die direkt im Script definiert werden: object x; object y; var z;

Wenn Scripte nicht mehr funktionieren und bei der Prüfung unerklärliche Syntax-Fehler auftreten, sollte versuchsweise dieses Programm wieder gelöscht oder deaktiviert werden – oder, noch besser, auf die aktuelle Firmware-Version aktualisiert werden.

Strings in HomeMatic-Scripten

Durch String-Verwendung in HomeMatic-Scripten kann die CCU fehlerhaft arbeiten, instabil werden oder sogar abstürzen. Grundsätzlich gilt: Je öfter mit Strings hantiert wird, desto eher führt dies zu Problemen.

Ich empfehle daher, nach Umsetzung dieser Anleitung die CCU unter Beobachtung zu halten.

Benennung von Systemvariablen

Prinzipiell kann man Systemvariablen – so wie allen Objekten in der CCU – beliebige Namen geben, also z. B. auch Umlaute und Sonderzeichen verwenden. Ich empfehle jedoch, sich auf reguläre Buchstaben (a-z, A-Z) zu beschränken: Bei Umlauten und Sonderzeichen besteht die Gefahr, dass Systemvariablen in Scripten nicht überall gefunden werden.

Planung

Die etwas komplexeren Wärmebedarfsrelais mit Vorlaufregelung oder Temperaturberechnung fallen in unserer Zweitwohnung aus. Die Etagenheizung arbeitet auch als Durchlauferhitzer, hat entsprechend Bumms und bringt damit die Vorlauftemperatur ratzfatz auf ihren Sollwert, bevor das Wasser überhaupt alle Heizkörper erreicht hat. Danach wird die Temperatur problemlos gehalten. Da kann ich mit meinem einfachen Aktor nichts reißen.

Das einfache Wärmebedarfsrelais ist mir zu doof. Die Heizkörper-Thermostate melden zwar deutlich schneller ihre Ventilposition an die CCU als meine alten Raumthermostate mit Stellantrieben, aber das einfache Relais-Script setzt auf permanenten Ventil-Hub – das machen die Heizkörper-Thermostate nicht und das ist auch gut so.

Mein Plan ist es, anhand des Öffnungsgrades der Ventilantriebe den Brenner ein- und auszuschalten: Wenn die Antriebe in Summe zu 50% geöffnet sind, soll die Heizung 30 Minuten laufen und dann 30 Minuten Pause machen. Bei 25% sollen es 15 Minuten Betrieb und 45 Minuten Pause sein.

Das lässt sich zum Glück relativ leicht umsetzen.

Script 1: Wärmebedarf ermitteln

Mein Programmkonzept für diese Installation sieht vor, dass ich Funktionen weitestgehend abstrahiere und in getrennten Programmen umsetze. Das erste Programm kümmert sich daher nur darum, den Wärmebedarf anhand der Ventilpositionen zu ermitteln und in eine Systemvariable zu schreiben.

Die Systemvariable nenne ich Heizung Anforderung – man sieht, ich habe mich hier auch von meiner bisherigen Namensgebung ohne Leerzeichen verabschiedet. Mal sehen, wie sich das bewährt. Origineller ist es jedenfalls nicht geworden.

Es handelt sich um eine Zahl mit nahezu beliebigem Maximalwert. Mehr als 600 kann es nicht werden bei sechs Thermostaten.

Das WebUI-Programm wird bei jeder Aktualisierung eines Thermostats ausgelöst.

Wichtig ist hier die Auswahl größer oder gleich 0% bei Aktualisierung. Entsprechend der Logik von WebUI-Programmen wird das Script dann jedes Mal ausgeführt, wenn irgendeiner der Heizkörper-Thermostate einen beliebigen Wert für die Ventilposition meldet.

Es sollten alle Thermostate aufgelistet werden, damit die Anforderung stets aktuell berechnet wird. Wenn Thermostate fehlen, ist das aber auch kein Drama – das Script wird ohnehin alle Thermostate im Gewerk Heizung durchgehen, um die Gesamtsumme der Ventilöffnungen zu ermitteln.

Das Script wird dann mit 10 Sekunden Verzögerung ausgeführt, damit die Systemvariable nicht unnötig durch die Gegend zappelt. Heizung ist träge – da können wir ruhig warten, bis sich alles etwas beruhigt hat.

! HomeMatic-Script
! SAME PROCEDURE AS EVERY YEAR, JAMES
! http://www.christian-luetgens.de/homematic/projekth/waermebedarf/Heizungsscript.htm

string s_channel;
object o_channel;
object o_dp;
object o_error;

integer i_valve = 0;

foreach (s_channel, dom.GetObject ("Heizung").EnumUsedIDs()) {
  o_channel = dom.GetObject (s_channel);
  o_dp = o_channel.DPByHssDP ("VALVE_STATE");
  if (o_dp) {
    o_error = o_channel.DPByHssDP ("FAULT_REPORTING");
    if (!o_error) {
      o_error = o_channel.DPByHssDP ("ERROR");
    }
    if (o_error.Value() == 0) {
      i_valve = i_valve + o_dp.Value();
    }
  }
}

dom.GetObject ("Heizung Anforderung").State (i_valve);

!  Ende des Scripts

Das Script ist kompakt:

Nach dem Speichern läuft das WebUI-Programm sofort los und schreibt die Summe in die Systemvariable. Darauf kann dann das zweite Script reagieren.

Exkurs: Funkstörungen vermeiden

Ich habe ja schon so meine Erfahrungen mit Funkstörungen sammeln dürfen. Selbstverständlich denke ich auch bei dieser Installation als erstes daran, was passiert, wenn die CCU ausfällt oder der Aktor aus anderen Gründen nicht erreichbar ist.

Am wichtigsten ist, dass die Heizung nicht unkontrolliert dauerhaft läuft. Sie würde es vermutlich überleben, aber unnötige Risiken sollte man trotzdem vermeiden. Außerdem wäre es eine fuchtbare Gasverschwendung.

Der wichtigste Schritt wird daher sein, dass ich den Aktor nicht einfach einschalte, sondern mit einer Einschaltdauer nach spätestens einer Stunde wieder ausschalten lasse.

Wenn man das als WebUI-Programm realisiert, sind es freilich wieder zwei Befehle, die bei jedem Schaltvorgang an den Aktor übertragen werden müssen: Einschaltdauer und eigentlicher Schaltbefehl. Was, wenn gerade die Einschaltdauer wegen einer Funkstörung verlorengeht?

Die Lösung ist eine direkte Verknüpfung mit einem virtuellen Kanal der CCU. Dazu benenne ich einen Kanal in Heizung Brenner einschalten um und verknüpfe ihn mit dem Kanal des Aktors, der dann die Etagenheizung steuert.

Wichtig ist, die Eigenschaften der direkten Verknüpfung zu bearbeiten. Die Einstellung Verweildauer im Zustand „ein“ (oder auch Treppenhauslicht) wird fest im Aktor gespeichert und jedes Mal angewendet, wenn über diese direkte Verknüpfung eingeschaltet wird.

Es ist dann kein zweiter Befehl nötig, um eine Einschaltdauer zu setzen.

Jetzt braucht es nur noch etwas Disziplin, um nicht doch noch in der WebUI oder irgendwo sonst den Aktor manuell zu schalten – das Profil gilt nur bei Auslösung über den verknüpften (virtuellen) Taster, sonst nicht. Das wird hart, aber ich schaffe das schon.

Script 2: Brenner steuern

Nach all diesen Vorbereitungen bin ich jetzt bereit für das zweite Script, mit dem dann der Brenner gesteuert wird.

Das WebUI-Programm ist wieder einfach:

Die Auslösung erfolgt bei jeder Aktualisierung der Systemvariable Heizung Anforderung, um die sich Script 1 kümmert. Da die Thermostate regelmäßig ihren Status melden, wird die Variable auch regelmäßig aktualisiert und das Programm ausgeführt.

Das Script wird nur ausgeführt, wenn die Systemvariable Heizung gesamt auf heizen oder absenken steht. Anderenfalls – im Zustand aus – ist die Brennersteuerung durch die HomeMatic praktisch deaktiviert. Nach spätestens einer Stunde  – siehe vorheriger Abschnitt – schaltet sich der Aktor aus und die Heizung ist tot. Mehr zur Systemvariablen hier.

Eine Verzögerung für die Scriptausfühung habe ich mir gespart: Auch darum kümmert sich bereits die Verzögerung in Script 1.

Script 2 ist ähnlich übersichtlich wie Script 1:

! HomeMatic-Script
! SAME PROCEDURE AS EVERY YEAR, JAMES
! http://www.christian-luetgens.de/homematic/projekth/waermebedarf/Heizungsscript.htm

object o_relais = dom.GetObject ("Heizung Brenner").DPByHssDP("STATE");
object o_taster = dom.GetObject ("Heizung Brenner einschalten");
integer i_bedarf = dom.GetObject ("Heizung Anforderung").Value().ToInteger();

integer i_diff = system.Date ("%F %T").ToTime().ToInteger() - o_relais.Timestamp().ToInteger();

if (
  (i_diff > 21600) || 
  ((o_relais.Value()) && (i_diff > (i_bedarf * 36).Min(3300)))
  ) {
  o_relais.State (0);
} elseif (
  (!o_relais.Value()) &&  (i_diff > (3600 - (i_bedarf * 36).Min(3600)).Max(300)) &&  (i_bedarf >= 5)
  ) {
    o_taster.State (1);
}

!  Ende des Scripts

Hier steckt ein bisschen Logik drin.

Objekte suchen

Als erstes suche ich mir den Aktor (Heizung Brenner), den virtuellen Taster zum Einschalten (Heizung Brenner einschalten) und die Systemvariable aus Script 1 (Heizung Anforderung) heraus.

Zeitspanne ermitteln

Danach berechne ich die Differenz (in Sekunden) seit der letzten Statusmeldung des Aktors (i_diff).

Das sollte man im Hinterkopf behalten, falls der Aktor in anderen Programmen oder Scripten angesprochen wird: Wenn der Timestamp durcheinandergebracht wird, funktioniert das Brenner-Script nicht mehr. Ein Grund mehr, den Aktor in Ruhe zu lassen..

Ausschalten

Der Aktor erhält in folgenden Fällen einen Ausschaltbefehl:

  • Wenn seit 21600 Sekunden kein Status übermittelt wurde; das sind 6 Stunden. Der Fall tritt ein, wenn der Aktor ausgeschaltet wurde und seinen neuen Status aus irgendeinem Grunde nicht übermitteln konnte – ansonsten nur dann, wenn die Heizung sehr lange ausgeschaltet ist, zum Beispiel im Sommer.
  • Wenn der Aktor eingeschaltet ist und die Laufzeit, die dem Bedarf entspricht, verstrichen ist. Hier wird die Summe der Ventilöffnungen mit 36 multipliziert: 100% Ventilöffnung = 3600 Sekunden = 1 Stunde Betrieb. Mit einem kleinen Haken – mehr als 3300 Sekunden, also 55 Minuten, bleibt der Aktor niemals an.

Man sieht: Auch hier treibt mich stets das Misstrauen, dass die Heizung unbemerkt weiterlaufen könnte, weil der tatsächliche Status in der CCU unbekannt ist. Darum gibt es turnusmäßige Resets.

Der Haken bei den Resets ist natürlich, dass damit die Timestamps des Aktors ebenfalls zurückgesetzt werden. Wenn der Wärmebedarf 125 beträgt, die Heizung also 75 Minuten laufen sollte, geht sie trotzdem nach 55 Minuten aus – und dann wieder an, um nochmals bis zu 55 Minuten zu laufen. Statt 75 haben wir dann vielleicht 110 Minuten Laufzeit.

Im Normalfall sollten die Ventile sich aber schnell schließen, wenn die Räume warm werden. Da die Laufzeit stets mit der aktuellen Wärmeanforderung verglichen wird, geht die Heizung dann entsprechend früher aus.

Normalerweise sollte dieses Problem nur beim Anheizen nach längerer Abwesenheit auftreten – da kann die Wohnung dann die zusätzliche Wärme auch brauchen.

Einschalten

Umgekehrt gibt es einen Einschaltbefehl, wenn alle folgenden Bedingungen erfüllt sind:

  • Der Aktor muss ausgeschaltet sein.
  • Es muss seit dem Ausschalten (genauer: seit dem letzten Timestamp) genug Zeit verstichen sein: 3600 Sekunden abzüglich der Laufzeit des Brenners abhängig von der Wärmeanforderung. Wenn 25% angefordert werden, bleibt der Brenner 3600 Sekunden – 25*36 Sekunden ausgeschaltet, also 2700 Sekunden = 45 Minuten.
  • Seit dem letzten Ausschalten müssen 300 Sekunden = 5 Minuten vergangen sein, weil ich die Heizung nicht unnötig hektisch aus- und einschalten will.
  • Wenn nicht mindestens 5% Ventilöffnung in der ganzen Wohnung vorliegen, bleibt die Heizung aus.

Klingt kompliziert, ist aber eigentlich ganz einfach: Wenn 25% Wärmebedarf angefordert werden, läuft der Aktor eine Viertelstunde und bleibt danach eine Dreiviertelstunde aus. Bei 50% wäre es jeweils eine halbe Stunde. Wenn sich die Ventilöffnung während der Ein- oder Ausschaltphase ändert, wird die Ein- oder Ausschaltzeit jeweils frisch berechnet. So wie geplant.

Zusammen mit einem weiteren Programm, das mir bei jeder Aktualisierung des Aktors eine Telegram-Nachricht schickt, kann ich die Funktion überprüfen. Bisher sieht es OK aus:

In jedem Fall ein deutlicher Fortschritt zum „repräsentativen Wohnraum“.

Der im Script eingestellte Faktor von 36 kann natürlich verändert werden. Bei Faktor 18 würde die Heizung, wenn 50% angefordert werden, nur 15 Minuten laufen. Der richtige Wert hängt von der Anzahl der Heizkörper, der Leistung der Heizungsanlage und vielen anderen Faktoren ab – ausprobieren ist angesagt.

Bei einem altertümlichen Monster wie dem unsrigen könnte man sogar überlegen, eine Abhängigkeit von der Außentemperatur einzubauen: Je kälter es draußen ist, desto länger läuft die Heizung. Außentemperaturabhängige Vorlauftemperatur kennt das gute Stück nämlich nicht. Voraussetzung dafür ist freilich ein Außentemperaturfühler oder Kombisensor, den wir hier nicht haben. Noch nicht.

Navigation