NEWS
Skalierbares Skript zur Steuerung einer Fussbodenheizung
-
Moin,
ich bin gerade dabei mein Erdgeschuss um eine Fussbodenheizung zu erweitern. Ich habe darauf verzichtet, mir in jeden Raum einen Thermostat zu installieren und habe stattdessen meine vorhandenen Raumtemperatursensoren und einen Satz Shelly 1 Dazu verwendet, die Heizung zu steuern.
Ich habe hier eine Umwälzpumpe die den Heizkreisverteiler mit mit Rücklaufwasser abgekühltem Vorlaufwasser versorgt.
Diese Pumpe ist mit einer Oderverknüpfung an die Normally Closed Stellmotoren angeschlossen: Ist mindestens ein Stellantrieb auf, läuft die Pumpe, sollte keiner auf sein schaltet sie ab.Ich habe diese Geschichte zunächst für die Küche auf Basis eines Scripts, das ich von @Matt77CHE bekommen habe, zum Laufen gebracht.
Ich habe dieses Script stark vereinfacht und Hysterese basiert aufgebaut.
Zusammengefasst funktioniert es so:
Alle 10 min wird die Raumtemperatur mit der Solltemperatur erfasst und wenn die Istwerte über Sollwert+Hysterese sind wird abgeschaltet. Fallen sie unter Istwert-Hysterese wird eingeschaltet.
Das ganze habe ich gestern mal in eine For Schleife gepackt, so dass es übe Anpassung des Array am anfang auf Eure Situation angepasst werden kann.
Ihr müsstet lediglich den Array entsprechend vergrößern/verkleinern und eure Sensoren und Aktoren sowie NO/NC eintragen.
Alles andere wird angelegt. Alle nötigen Parameter liegen dann im Javascript Objektordner//Steuerparameter createState("javascript.0.Heizung.VirtualSwitchFB", 0.0, {name: "Virtueller SChalter Fussbodenheizung", type: 'boolean'}); createState("javascript.0.Heizung.FBPumpActive", 0.0, {name: "FB Pumpe aktiv", type: 'boolean'}); createState("javascript.0.Heizung.refreshFloorHeatingCircuits", 0.0, {name: "Update FB", type: 'boolean'}); createState("javascript.0.Heizung.FBWidget", 'leer', {type: 'string',name: 'FB Widget'}); //Unterordner definieren const paramPath = "javascript.0.Heizung.Parameter.";//Pfad für Parameterordner const setpointPath = paramPath+"Zieltemperaturen."; //Pfad Vorgabetemperturen const hysteresisPath = paramPath+"Hysteresen."; //Pfad Hysteresen const manualTempModePath = paramPath+"ManualTempMode."; //Pfad manuelle Temperaturauswahl //Hauptarray anlegen [Nummer, Raum, Temperatursensor, Schaltaktor, Logik (NO: Stromlos offen, NC: Stromlos geschlossen)] var fb_array = [ "##1","Küche","zigbee.0.00158d0002fbecb1.temperature","shelly.0.SHSW-1#349454738F09#1.Relay0.Switch","NC", "##2","Kinderzimmer","zigbee.0.00124b002918fc07.temperature","shelly.0.SHSW-1#34945474BB26#1.Relay0.Switch","NC", "##3","Wohnzimmer","zigbee.0.00158d000429ef25.temperature","shelly.0.SHSW-1#34945474C344#1.Relay0.Switch","NC", "##4","Bad","zigbee.0.00124b002918afdf.temperature","shelly.0.SHSW-1#349454738DC9#1.Relay0.Switch","NC" ]; //Anlegen der Systemparameter und Variablen im Ordner 0.javascript.Heizung for (var i = 0; i < fb_array.length; i++) { // for every 5th array object if (fb_array[i].includes("##")){ //Neue Zeile createState(setpointPath+fb_array[i+1], false, {name: "Zieltemperatur "+fb_array[i+1], type: 'number', unit: '°C'}); createState(hysteresisPath+fb_array[i+1], false, {name: "Hysterese "+fb_array[i+1], type: 'number', unit: '°C'}); createState(manualTempModePath+fb_array[i+1], false, {name: "Manuelle Temperaturauswahl "+fb_array[i+1], type: 'boolean'}); } } //Alle 10 Minuten die Räume überprüfen log('FB restarted')// Nur zur Info function refreshFloorHeatingCircuits(){ log('...') var PumpActive = false; //Rücksetzen der Hilfsvariable //Array durchlaufen um die Räume zu steuern for (var i = 0; i < fb_array.length; i++) { if (fb_array[i].includes("##")){ //Neue Zeile gefunden //Fallunterscheidung ob Solltemperatur Parameter durch Heizungssystem oder eigene if (getState(manualTempModePath+fb_array[i+1]).val == true) { var targetTemp = parseInt(getState(setpointPath+fb_array[i+1]).val); }else{ var targetTemp = parseInt(getState("ems-esp.0.heatingCircuits.hc1.currentRoomSetpoint").val); }; //Hysterese auslesen var hysteresis = parseInt(getState(hysteresisPath+fb_array[i+1]).val); // Wenn der Virtuelle schalter eingeschaltet ist if (getState("javascript.0.Heizung.VirtualSwitchFB").val == true) { //Nur schalten wenn nötig im bereich wird nichts gemacht if (getState(fb_array[i+2]).val >= targetTemp+hysteresis) {//Warm genug-> ausschalten setState(fb_array[i+3], false, true); } else if (getState(fb_array[i+2]).val < targetTemp-hysteresis) { // zu kalt -> einschalten setState(fb_array[i+3], true, true); PumpActive = true; } } else { // alles stoppen, alles aus log(fb_array[i+1]+' wird ausgeschaltet'); setState(fb_array[i+3], false, true); } } } setState("javascript.0.Heizung.FBPumpActive", PumpActive, true); //Wenn einer der Aktoren aktiv ist schaltet meine Pumpe in } schedule("*/10 * * * *", function () { refreshFloorHeatingCircuits(); }); //Wenn der Hauptschalter verändert wurde dann einmal durchlaufen (ToDo: Triggerbedingung um Vorgabetemperaturen usw Parameter erweitern) on({id: 'javascript.0.Heizung.VirtualSwitchFB', change: 'any'}, async function (obj) { refreshFloorHeatingCircuits(); }); on({id: 'javascript.0.Heizung.refreshFloorHeatingCircuits', change: 'gt'}, async function (obj) { setState("javascript.0.Heizung.refreshFloorHeatingCircuits",false); //Rücksetzen der Triggervariable refreshFloorHeatingCircuits(); });
Ergänzend erzeuge ich noch ein HTML Widget was das schön darstellt. (nicht in diesem Listing)
Es ist noch sehr wichtig, dass Zustand und Erreichbarkeit aller beteiligten Sensoren/Aktoren noch separat überwacht werden. Ein Problem wird auf alles VIS dargestellt und ich bekomme einen Warnung via Telegram.
Falls ich was ändere, poste ich updates-
LG
Nils
Ich hoffe das Programm ist was für den ein oder anderen.
Ich freue mich über Feedback, Verbesserungsvorschläge und alternative Ansteuerungen.[edit] jetzt als function anstatt doofer hilfsvariablen