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