NEWS
WW Zirkulationspumpe bedarfsgerecht ein- und ausschalten
-
Anwendungsbeschreibung
Komponenten- Brauchwasserspeicher (Warmwasser)
- Zirkulationspumpe in der Steigleitung
- NodeMCU V2.0 (ESP8266) OS:tasmota Doris 8.1
- 3x Temperaturfühler DS18B20 (1wire) zum Messen von der Vorlauftemperatur
- Relaismodul zum Schalten der Zirkulationspumpe
Ziel
Ich möchte mit der Steuerung Energiekosten sparen. Der aktuell Aufbau startet die Zirkulationspumpe mit einer Zeitschaltuhr, z.B. Morgens 30min, Mittag 30min und Abends 30min. Der Aufbau ist wohl sehr weit verbreitet und ist mir schon eine ganze Weile in Dorn im Auge weil wenig innovativ.Die Zirkulationspumpe soll bedarfsgerecht eingeschaltet werden und die aktuelle Zeitschaltuhr kommt weg. Bedarfsgerecht meint beim Aufdrehen vom Warmwasser im Gebäude soll die Zirkulationspumpe starten und die Steigleitung mit Warmwasser befüllen. Damit ist das Warmwasser schneller an der Bedarfsstelle im Bad/WC.
Kurzbeschreibung der Steuerhardware
Ein 5V Netzteil versorgt den NodeMCU und das Relaismodul mit 5.0V Spannung. Auf dem NodeMCU steht eine geregelte 3.3.V Versorgung für die DS18B20 zur Verfügung.
Als Betriebssystem für den NodeMCU verwende ich tasmota in einer damals neuen Version 8.1. Alle Hardwarekomponenten sind günstig und leicht am Markt verfügbar.
Begonnen habe ich drei Temperatursensoren einzusetzen - ich wusste noch nicht so genau wie es werden wird. Am Ende braucht man nur einen Sensor am Heizungsrohr für den Warmwasservorlauf vom Brauchwasserspeicher in die Steigleitung.
Wichtig: Der NodeMCU ist echt billig gemacht und verträgt wenig Spannungsschwankungen. Schon beim Einschalten des Radios gibt es den einen oder anderen Effekt und tasmota hängt sich auf. Also umbedingt reichlich (~2) Cbulk ~330uF außen an die 3.3V Versorgungspins anschließen.Kurzbeschreibung der Steuersoftware auf dem NodeMCU
Tasmota bietet eine schicke Möglichkeit mit "Rules" direkt und schnell auf Events zu reagieren und neue Events auszulösen. Damit lässt sich eine tolle Steuerung umsetzen. Inspiriert hat mich ein Beispiel in der Tasmotat Dokumentation der eine Poolheizung realisiert hat. Dazu gibt es noch Variablen (var) und Konstante (mem) für mehr Transparenz des Ganzen nach außen.Tasmota rule1
Der Thermostat
Nachdem die Zirkulationsregelung gestartet ist stellt sich der Thermostat auf die aktuellen Temperaturen des Vorlauf ( DS18B20_2) und Rücklauf ( DS18B20_1 )ein. Es werden Grenzen zum Einschalten der Pumpe festgelegt um zu erkennen wenn Warmwasser entnommen wird. Dann erwärmt sich das Vorlaufrohr nach dem Brauchwasserspeicher, der Vorlaufsensor signalisiert einen Temperaturanstieg.Event
- DS18B20_2:
-- Obere Vorlaufgrenze (UpperVL): var1
-- Untere Vorlaufgrenze (LowerVL): var2 - DS18B20_1: Aktuell nicht benutzt, LowerRL Limit: var3
------------------------------------------------------------------ -- rule1 Thermostat und Regelung. Entscheidung ob Pumpe eingeschaltet werden soll. -- -- Rücklauf DS18B20-1#temperature -- Vorlauf DS18B20-2#temperature -- Intern DS18B20-3#temperature -- -- var1 obere Temperaturschwelle Vorlauf (VL) -- var2 untere Temperaturschwelle Vorlauf (VL) -- var3 maximale Rücklaufschwelle (RL) -- Löse event aus wenn Vorlauf temp ausserhalb oberer (var1) und unterer (var2) Schwelle, Pumpe an. rule1 on system#boot do Backlog var1 26; var2 25; var3 25 endon on DS18B20_2#temperature>%var1% do Backlog var1 %value%;var2 %value%;add1 0.5;sub2 0.5;var3 %value%;sub3 5;event UpperVL=%value% endon on DS18B20_2#temperature<%var2% do Backlog var2 %value%;var1 %value%;add1 0.5;sub2 0.5;var3 %value%;sub3 5;event LowerVL=%value% endon
Es wird Warmwasser entnommen
Die Zirkulationsregelung läuft und hat die obere und untere Vorlauftemperaturgrenzen ( DS18B20_2 ) eingestellt, die Pumpe ist aus ( power1 0 ).
Es wird Warmwasser aus dem Brauchwasserspeicher entnommen und das Vorlaufrohr erwärmt sich. Der Vorlaufsensor signalisiert einen Temperaturanstieg und die obere Vorlauftemperaturgrenze ( DS18B20_2 ) wird überschritten.
Beim Überschreiten wird der Thermostat neu definiert und eine Event ausgelöst UpperVL der die Pumpe einschalten soll.
Die Pumpe wird über rule2 gesteuert. Wenn die Zirkulationspumpe eine definierte Zeit ( mem5 ) gelaufen ist gibt es eine Wartezeit vor dem nächsten Pumpenanlauf ( mem4 ) um eine schnelles Ein-/Ausschalten zu vermeiden.Tasmota rule1
Event
- UpperVL: Event zum einschalten der Pumpe für eine bestimmte Zeit.
- LowerVL: Event Pumpe aus
- LowerRL: Event Pumpe aus
- PumpOn=0: Pumpe/Power1 aus.
- PumpOn>0: Entscheiden ob und wie lange die Pumpe power1 eingeschaltet werden soll.
- Var4: Pumpenfreigabe in minuten, zählt von 0 aufwärts.
- Mem4: Grenze in Minuten wann die Pumpe wieder freigegeben wird und einschalten darf.
------------------------------------------------------------------ -- rule2 Controller: Pumpe einschalten und ausschalten -- rule2 1 Regel einschalten -- rule2 0 Regel ausschalten -- -- Pumpe einschalten, delay %value%, Pumpe abschalten. -- PumpOn=0 Pumpe aus -- PumpOn=10 Pumpe an, setze timer zum ausschalten -- PumpOn=180 Pumpe an, setze timer zum ausschalten -- -- Benutze Rule timer zum abschalten der pumpe -- RuleTimer2 60 60sec -- on Rules#Timer=2 o when countdown RuleTimer2 expires -- var4 Wird beim löschen von power verwendet und es wird das wiedereinschalten verzögert. Die Einheit ist minuten. -- Jede Minute zählt var4 im eines hoch. Nach z.B. 5 minuten kann die Pumpe wieder eingeschaltet werden. -- mem4 45 Warte mem4 Minuten bis wiedereinschalten, e.g. 45 (Minuten) -- mem5 19 Pumpenlaufzeit in sekunden, e.g. 19 (Sekunden) rule2 on system#boot do Backlog var4 0.0 ; ruletimer2 0 endon on event#UpperVL do event PumpOn=1 endon on event#LowerVL do event PumpOn=0 endon on event#PumpOn=0 do power1 off endon on event#PumpOn>0 do event ChkWait=%var4% endif endon on event#ChkWait>%mem4% do Backlog var4 0; ruletimer2 %mem5%; power1 on endon on Rules#Timer=2 do power1 off endon on Time#Minute|1 do add4 1 endon on var4#state==3 do power1 off endonSperrzeit nach einem Pumpenlauf / Pumpenfreigabe
Pause für die Pumpe nach einer Zirkulationspumpzeit. Hier wird verhindert, dass die Pumpe rythmisch wieder ein und ausgeschaltet wird.Event
- event#PumpOn>0:
-- Wenn die Pumpe über var4 freigegeben ist:
if (%var4%>=%mem4%) - Time#Minute|1
-- Vorwärtszählen der Pumpenfreigabe pro Minute.
rule2 ... on event#PumpOn>0 do if (%var4%>=%mem4%) power1 on; ruletimer2 %value%; var4 0.0 endif endon ... on Time#Minute|1 do add4 1 endon ...MQTT Verbindung in der Applikation mit Tasmota
------------------------------------------------------------------ -- MQTT Verbindung über rule3 -- -- Vorlauf DS18B20-2#temperature -- var1 -- var4 rule3 on tele-DS18B20_2#temperature do Backlog publish stat/zirkulation/vlUpper %var1%; publish stat/zirkulation/PumpWait %var4% endon on power1#state do Backlog publish stat/zirkulation/Pump %value% endonKonfiguration der Applikation in Tasmota
-- SetOption53 1 Display hostname and IP address in GUI 0=default -- SetOption0 0 Save power state and use after restart (=SaveState) 1=default -- SetOption64 1 Switch between - or _ as sensor name separator, 0 = sensor name index separator is - (hyphen) (default), 1 = sensor name index separator is _ (underscore) -- mem4 legt die Wartezeit bis zum Wiedereinschalten der Pumpe fest. Bei mir 45Minuten. Gerne auch anpassen. -- mem5 legt die Laufzeit der Pumpe fest. Bei mir reichen 19Sekunden. Gerne auch anpassen. Backlog PowerOnState 0; TelePeriod 61; rule3 1; rule1 1; rule2 1; SetOption0 0; SetOption53 1; SetOption64 1; mem4 45; mem5 19Und wie läuft das Ganze jetzt los?
Mit dem folgende Kommando wird alle 61Sekunden eine Messung der Sensoren an den MQTT Broker geschickt:.TelePeriod 61Davor ist die Option 64 wichtig, die einfach ein Problem (im iobroker) behebt, wenn man ein Eventnamen ein Bindestrich enthalten ist ;-). Daran kann man verzweifeln.
SetOption64 1;Und folgend werden die rules aktiviert, damit es auch eine Steuerung gibt:
rule3 1; rule1 1; rule2 1;Typischer Log aus der Tasmota console
8:50:57 MQT: tele/zirkulation/STATE = {"Time":"2020-03-01T18:50:57","Uptime":"0T02:27:12","UptimeSec":8832,"Heap":23,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":1,"POWER1":"OFF","POWER2":"OFF","Wifi":{"AP":1,"SSId":"blabla","BSSId":"Z0:B0:VV:3K:D6:20","Channel":11,"RSSI":100,"Signal":-50,"LinkCount":1,"Downtime":"0T00:00:06"}} 18:50:57 MQT: tele/zirkulation/SENSOR = {"Time":"2020-03-01T18:50:57","DS18B20_1":{"Id":"01143B9799AA","Temperature":26.1},"DS18B20_2":{"Id":"01143BDE6DAA","Temperature":33.9},"DS18B20_3":{"Id":"03209779E6D3","Temperature":22.1},"TempUnit":"C"} 18:50:57 RUL: TELE-DS18B20_1#TEMPERATURE performs "Backlog publish stat/zirkulation/rl 26.1; publish stat/zirkulation/rlUpper 29.100" 18:50:57 RUL: TELE-DS18B20_2#TEMPERATURE performs "Backlog publish stat/zirkulation/vl 33.9; publish stat/zirkulation/vlUpper 34.600; publish stat/zirkulation/vlLower 33.600" 18:50:57 RUL: TELE-DS18B20_3#TEMPERATURE performs "publish stat/zirkulation/int 22.1" 18:50:57 MQT: stat/zirkulation/int = 22.1 18:50:57 MQT: stat/zirkulation/rl = 26.1 18:50:58 MQT: stat/zirkulation/rlUpper = 29.100 18:50:58 MQT: stat/zirkulation/vl = 33.9 18:50:58 MQT: stat/zirkulation/vlUpper = 34.600 18:50:58 MQT: stat/zirkulation/vlLower = 33.600 18:51:00 RUL: TIME#MINUTE|1 performs "add4 1" 18:51:00 MQT: stat/zirkulation/RESULT = {"Add4":"31.000"} 18:51:00 RUL: VAR4#STATE performs "publish stat/zirkulation/PumpWait 31.000" 18:51:00 MQT: stat/zirkulation/PumpWait = 31.000Kurzbeschreibung iobroker
InfoPlattform: linux Betriebssystem: linux Die Architektur: arm CPUs: 4 Geschwindigkeit: 1500 MHz Modell: ARMv7 Processor rev 3 (v7l) RAM: 3.7 GB System-Betriebszeit: 19 T. 00:08:11 Node.js: v12.22.6 NPM: 6.14.15 Datenträgergröße: 29.0 GiB Datenträger verfügbar: 26.0 GiB Adapter-Anzahl: 362 Betriebszeit: 16 T. 00:39:00 Aktive Instanzen: 17 location: /opt/iobroker/JS zirkulation ZirkParseSTATE
Bei mir heisst der Tasmota MQTT client "zirkulation". Damit kommt der Name relativ oft in dem JS vor.
Hier werden die vom MQTT Client/Server glieferten Daten vom Tasmota client verarbeitet und umgewandelt. Das liegt daran dass ich keinen besseren Weg gefunden habe die Daten im VIS json table vom tasmota client zu bekommen.Hier nun das JS:
// const util = require('util'); // STATE // {"Time":"2020-06-06T15:19:52","Uptime":"0T21:11:25","UptimeSec":76285,"Heap":25,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":3,"POWER":"OFF","Wifi":{"AP":1,"SSId":"Kreuzspitz","BSSId":"F0:B0:14:3F:D6:20","Channel":1,"RSSI":78,"Signal":-61,"LinkCount":1,"Downtime":"0T00:00:03"}} // createState('zirkulation.TimeStampSTATE'); createState('zirkulation.UpTimeSTATE'); createState('zirkulation.jsonSENSOR'); createState('zirkulation.jsonSTATE'); // prepare tasmota format for json format createState('zirkulation.PowerSTATE'); ////////////////////////////////////////////////////////////////////////// // Convert map to JSON string // https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify // // @param // @return function mapToJson(map) { return JSON.stringify([...map]); } ////////////////////////////////////////////////////////////////////////// // convert JSON string key value pairs to Map key value pairs // https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse // // @param jsonStr key value pairs // @return map converted from jsonStr to map key value pairs. function jsonToMap(jsonStr) { return new Map(JSON.parse(jsonStr)); } on({id: 'mqtt.0.tele.zirkulation.STATE', change: "any"}, function (obj) { var jsonSensorText = ''; jsonSensorText = obj.state.val; // {"Time":"2020-06-06T15:19:52","Uptime":"0T21:11:25","UptimeSec":76285,"Heap":25,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":3,"POWER":"OFF","Wifi":{"AP":1,"SSId":"Kreuzspitz","BSSId":"F0:B0:14:3F:D6:20","Channel":1,"RSSI":78,"Signal":-61,"LinkCount":1,"Downtime":"0T00:00:03"}} try {obj = JSON.parse(jsonSensorText); } catch (e) { console.error('Cannot parse: ' + getState('mqtt.0.tele.zirkulation.STATE').val); return; } //console.debug( util.inspect(jsonSensorText, {showHidden:true, depth: null}) ); var sTimeStamp = obj.Time; var fUptimeSec = obj.UptimeSec; var sPOWER = obj.POWER; // "POWER":"OFF" var fPOWER = 0; if (sPOWER == "OFF") { fPOWER = 0; } else { fPOWER = 1; } setState('javascript.0.zirkulation.TimeStampSTATE', sTimeStamp , true); setState('javascript.0.zirkulation.UpTimeSTATE', fUptimeSec , true); setState('javascript.0.zirkulation.PowerSTATE', fPOWER , true); }); ///////////////////////////////////////////////////////////////////////// // preapre tasmota json format to use in iobroker vis jason table // {"Time":"2021-08-17T16:04:47","Uptime":"16T23:08:54","UptimeSec":1465734,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":30,"POWER":"OFF","Wifi":{"AP":1,"SSId":"Kreuzspitz","BSSId":"3C:A6:2F:26:25:8B","Channel":11,"RSSI":88,"Signal":-56,"LinkCount":24,"Downtime":"0T00:01:15"}} on({id: 'mqtt.0.tele.zirkulation.STATE', change: "any"}, function (obj) { var jsonSensorText = ''; jsonSensorText = obj.state.val; var myMap = new Map(); try {obj = JSON.parse(jsonSensorText); } catch (e) { console.error('Cannot parse: ' + getState('mqtt.0.tele.zirkulation.STATE').val); return; } // {"Time":"2021-08-17T16:04:47","Uptime":"16T23:08:54","UptimeSec":1465734,"Heap":26,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"MqttCount":30,"POWER":"OFF","Wifi":{"AP":1,"SSId":"Kreuzspitz","BSSId":"3C:A6:2F:26:25:8B","Channel":11,"RSSI":88,"Signal":-56,"LinkCount":24,"Downtime":"0T00:01:15"}} for (let [key, value] of Object.entries(obj)) { if ( typeof value === 'object' ) { // iterate one level down for (let [key2, value2] of Object.entries(value)) { // log level 2 // console.log(key + ":" + key2 + "=" + value2); myMap.set(key + ":" + key2, value2); } } else { // log level 1 // console.log(key + "=" + value); myMap.set(key , value); } } var jsonString = mapToJson(myMap); //console.log( util.inspect(myMap, {showHidden:true, depth: null}) ); //console.log( util.inspect(jsonSENSOR, {showHidden:true, depth: null}) ); setState('javascript.0.zirkulation.jsonSTATE', jsonString , true); }); ///////////////////////////////////////////////////////////////////////// // preapre tasmota json format to use in iobroker vis jason table // {"Time":"2021-08-17T16:05:48","DS18B20_1":{"Id":"01143B9799AA","Temperature":24.1},"DS18B20_2":{"Id":"01143BDE6DAA","Temperature":37.9},"DS18B20_3":{"Id":"03209779E6D3","Temperature":25.2},"TempUnit":"C"} on({id: 'mqtt.0.tele.zirkulation.SENSOR', change: "any"}, function (obj) { var jsonSensorText = ''; jsonSensorText = obj.state.val; var myMap = new Map(); try {obj = JSON.parse(jsonSensorText); } catch (e) { console.error('Cannot parse: ' + getState('mqtt.0.tele.zirkulation.SENSOR').val); return; } // {"Time":"2021-08-17T16:05:48","DS18B20_1":{"Id":"01143B9799AA","Temperature":24.1},"DS18B20_2":{"Id":"01143BDE6DAA","Temperature":37.9},"DS18B20_3":{"Id":"03209779E6D3","Temperature":25.2},"TempUnit":"C"} for (let [key, value] of Object.entries(obj)) { if ( typeof value === 'object' ) { // iterate one level down for (let [key2, value2] of Object.entries(value)) { // log level 2 // console.log(key + ":" + key2 + "=" + value2); myMap.set(key + ":" + key2, value2); } } else { // log level 1 // console.log(key + "=" + value); myMap.set(key , value); } } var jsonString = mapToJson(myMap); //console.log( util.inspect(myMap, {showHidden:true, depth: null}) ); //console.log( util.inspect(jsonSENSOR, {showHidden:true, depth: null}) ); setState('javascript.0.zirkulation.jsonSENSOR', jsonString , true); });JS zirkulation ZirkParseSENSOR
Hier wirkt nun die spezielle Option aus der Tasmota Konfiguration um das "-" in ein "_" zu wandeln.// const util = require('util'); // SENSOR // {"Time":"2020-03-28T19:07:12","DS18B20_1":{"Id":"01143B9799AA","Temperature":30.4},"DS18B20_2":{"Id":"01143BDE6DAA","Temperature":36.1},"DS18B20_3":{"Id":"03209779E6D3","Temperature":24.6},"TempUnit":"C"} // createState('zirkulation.TimeStampSENSOR'); createState('zirkulation.VorlaufTempSENSOR'); createState('zirkulation.RuecklaufTempSENSOR'); createState('zirkulation.InnerhalbTempSENSOR'); on({id: 'mqtt.0.tele.zirkulation.SENSOR', change: "any"}, function (obj) { var jsonSensorText = ''; jsonSensorText = obj.state.val; try {obj = JSON.parse(jsonSensorText); } catch (e) { console.error('Cannot parse: ' + getState('mqtt.0.tele.zirkulation.SENSOR').val); return; } //console.debug( util.inspect(jsonSensorText, {showHidden:true, depth: null}) ); // {"Time":"2020-06-06T15:11:44","DS18B20_1":{"Id":"01143B9799AA","Temperature":21.8},"DS18B20_2":{"Id":"01143BDE6DAA","Temperature":35.1},"DS18B20_3":{"Id":"03209779E6D3","Temperature":22.6},"TempUnit":"C"} var fRLTemp = obj.DS18B20_1.Temperature; // RL var fVLTemp = obj.DS18B20_2.Temperature; // VL var fINTemp = obj.DS18B20_3.Temperature; // IN var sTimeStamp = obj.Time; setState('javascript.0.zirkulation.TimeStampSENSOR', sTimeStamp , true); setState('javascript.0.zirkulation.InnerhalbTempSENSOR', fINTemp , true); setState('javascript.0.zirkulation.VorlaufTempSENSOR', fVLTemp , true); setState('javascript.0.zirkulation.RuecklaufTempSENSOR', fRLTemp , true); });@alk ich habe ein Sonoff Pow R2 mit Tasmota vor die Zirkulationspumpe gesetzt. Jetzt kann ich über die Zeitschaltuhr (Tasmota Funktion) zu den tapischen Zeiten die Pumpe ein oder aus schalten. Mit dem Handy kann ich die Zeitschaltuhr übersteuern und wenn ich in der Küche bin und zwischendrinnen (Kuchen backen etc.) warmes Wasser für den Abwasch brauche die Pumpe einfach einschalten....
Das funktioniert ganz gut und jeder im Haushalt kann so mit dem eigenen Smartphone die Pumpe wenn nötig einschalten... -
Wie messt Ihr denn vernünftig die Temperatur an einem Kupferrohr? Ich habe das bisher mit Zigbee Funkfühlern nicht hinbekommen....
-
Wie messt Ihr denn vernünftig die Temperatur an einem Kupferrohr? Ich habe das bisher mit Zigbee Funkfühlern nicht hinbekommen....
So wirklich smart wird das mit BWM. Da wir faktisch überall das Licht per Hue Motion Sensoren steuern wird dies im neuen Haus auch die Zirkulationspumpe aktivieren.
Ach ja, die Legionellenspülung mit hoher Temperatur 1x die Woche kann man da auch automatisieren. Ich weiß ja, wann der Kessel hochheizt.
-
Wie messt Ihr denn vernünftig die Temperatur an einem Kupferrohr? Ich habe das bisher mit Zigbee Funkfühlern nicht hinbekommen....
@disaster123 sagte in WW Zirkulationspumpe bedarfsgerecht ein- und ausschalten:
Wie messt Ihr denn vernünftig die Temperatur an einem Kupferrohr? Ich habe das bisher mit Zigbee Funkfühlern nicht hinbekommen....
So etwas wie ein Wemos D1 Mini + DS18B20 Temperaturfühlern wäre dein Freund.
Auf den Wemos kannst du einfach Tasmota aufspielen, den Wemos selbst per USB-Netzteil mit Strom versorgen.
Du kannst bei Tasmota dann bis zu 8 dieser Temperatursensoren anschließen, die werden alle parallel geschaltet, du brauchst einmal einen 4.7K Wiederstand zusätzlich. Also ein Wemos misst dann 8 Temperaturen gleichzeitig.
Die Daten landen per MQTT am ioBroker, alternativ mit dem Sonoff-Adapter.
https://tasmota.github.io/docs/DS18x20/Die Temperaturfühler gibt es in 2 Bauarten, du willst die mit langem Kabel + Metallkapsel, z.B. https://www.amazon.de/gp/product/B07KNQJ3D7
Die kannst du einfach mit Kabelbinder, Klebeband usw. (gerne etwas wärmeleitendes wie Metallkabelbinder) an den Kupferrohren befestigen (ggf. unter der Isolierung).
Als Gehäuse für den Wemos mit den Kabeln reicht zur Not auch eine Abzeigdose.
-
So wirklich smart wird das mit BWM. Da wir faktisch überall das Licht per Hue Motion Sensoren steuern wird dies im neuen Haus auch die Zirkulationspumpe aktivieren.
Ach ja, die Legionellenspülung mit hoher Temperatur 1x die Woche kann man da auch automatisieren. Ich weiß ja, wann der Kessel hochheizt.
@andygr42 sagte in WW Zirkulationspumpe bedarfsgerecht ein- und ausschalten:
So wirklich smart wird das mit BWM.
Hmm,
hatte ich auch mal überlegt aber auch dann dauert es immer noch ziemlich bis das Wasser einmal durchgewältzt wurde und auch an der entferntesten Zapfstelle sofort warmes wasser kommt.
Ein weiterer Nachteil: jedes mal wenn jemand den Raum betrifft springt die Pumpe an, egal ob Warmwasser benötigt wird oder nicht oder wie willst du das verhindern?
Das einzige was für mich "Bedarfsgerecht" ist, ist die Anforderung per manuellem Befehl. Sei es per Taster, Sprache oder einer anderen menschlichen Aktion.
Bei der Steuerung per Temp Fühler habe ich nicht wirklich verstanden was es bringen soll. Bis da ein nennenswerter Unterschied festgestellt wird, sei es durch Öffnen des Hahnes oder wenn die Temp des Wassers sinkt/steigt will ich schon Warmwasser haben. Wenn dann erst die Pumpe anspringt kann ich auch solange laufen lassen.
Aber vielleicht verstehe ich das auch nur falsch und mich kann jemand erleuchten.
Only my 2cents
-
@andygr42 sagte in WW Zirkulationspumpe bedarfsgerecht ein- und ausschalten:
So wirklich smart wird das mit BWM.
Hmm,
hatte ich auch mal überlegt aber auch dann dauert es immer noch ziemlich bis das Wasser einmal durchgewältzt wurde und auch an der entferntesten Zapfstelle sofort warmes wasser kommt.
Ein weiterer Nachteil: jedes mal wenn jemand den Raum betrifft springt die Pumpe an, egal ob Warmwasser benötigt wird oder nicht oder wie willst du das verhindern?
Das einzige was für mich "Bedarfsgerecht" ist, ist die Anforderung per manuellem Befehl. Sei es per Taster, Sprache oder einer anderen menschlichen Aktion.
Bei der Steuerung per Temp Fühler habe ich nicht wirklich verstanden was es bringen soll. Bis da ein nennenswerter Unterschied festgestellt wird, sei es durch Öffnen des Hahnes oder wenn die Temp des Wassers sinkt/steigt will ich schon Warmwasser haben. Wenn dann erst die Pumpe anspringt kann ich auch solange laufen lassen.
Aber vielleicht verstehe ich das auch nur falsch und mich kann jemand erleuchten.
Only my 2cents
@wendy2702 Ich denke, das hängt auch vom Einzelfall ab. Ein manuelles Einschalten kommt für mich nicht in Frage. Der WAF ist definitiv zu niedrig und wenn Du dann noch Kinder hast, wird das mal gar nix. Da würde ich lieber bei Zeitschaltuhr morgens und abends bleiben.
Im aktuellen Haus kann ich in der Küche darauf komplett verzichten. Die Spüle ist praktisch direkt über der TWWP und es ist schnell warm. Im Gäste WC verzichten wir fast ganz auf warmes Wasser (am Eckventil ziemlich abgedreht). Wäre aber auch schnell da. Das Duschbad unten wird kaum genutzt. Bleibt noch das Bad oben. Da möchte ich (fast) immer warmes Wasser haben. Egal ob nur jemand kurz auf dem Klo war oder duschen möchte, es wird fast immer benötigt.
Im neuen Haus könnte es auch für die Küche interessant werden. Hier wäre z.B. denkbar, an Stelle eines BWM einen Präsenzsensor zu nutzen und die Pumpe erst zeitverzögert einzuschalten. Damit halt nicht jedes Mal, wenn jemand zum Kühlschrank latscht, das Wasser zirkuliert. Wenn jemand länger in der Küche ist, steigt auch die Wahrscheinlichkeit, dass er warmes Wasser benötigt. Eben die Finger waschen oder einen Apfel abspülen geht auch mit kaltem Wasser.
Am Ende müsste man tatsächlich mal über einen längeren Zeitraum den Energieverbrauch messen und entschieden, was besser ist.
-
@wendy2702 Ich denke, das hängt auch vom Einzelfall ab. Ein manuelles Einschalten kommt für mich nicht in Frage. Der WAF ist definitiv zu niedrig und wenn Du dann noch Kinder hast, wird das mal gar nix. Da würde ich lieber bei Zeitschaltuhr morgens und abends bleiben.
Im aktuellen Haus kann ich in der Küche darauf komplett verzichten. Die Spüle ist praktisch direkt über der TWWP und es ist schnell warm. Im Gäste WC verzichten wir fast ganz auf warmes Wasser (am Eckventil ziemlich abgedreht). Wäre aber auch schnell da. Das Duschbad unten wird kaum genutzt. Bleibt noch das Bad oben. Da möchte ich (fast) immer warmes Wasser haben. Egal ob nur jemand kurz auf dem Klo war oder duschen möchte, es wird fast immer benötigt.
Im neuen Haus könnte es auch für die Küche interessant werden. Hier wäre z.B. denkbar, an Stelle eines BWM einen Präsenzsensor zu nutzen und die Pumpe erst zeitverzögert einzuschalten. Damit halt nicht jedes Mal, wenn jemand zum Kühlschrank latscht, das Wasser zirkuliert. Wenn jemand länger in der Küche ist, steigt auch die Wahrscheinlichkeit, dass er warmes Wasser benötigt. Eben die Finger waschen oder einen Apfel abspülen geht auch mit kaltem Wasser.
Am Ende müsste man tatsächlich mal über einen längeren Zeitraum den Energieverbrauch messen und entschieden, was besser ist.
@andygr42 sagte in WW Zirkulationspumpe bedarfsgerecht ein- und ausschalten:
@wendy2702 Ich denke, das hängt auch vom Einzelfall ab. Ein manuelles Einschalten kommt für mich nicht in Frage. Der WAF ist definitiv zu niedrig und wenn Du dann noch Kinder hast, wird das mal gar nix. Da würde ich lieber bei Zeitschaltuhr morgens und abends bleiben.
nach einigem Herumprobieren auch mit kommerziellen Automatik-Lösungen haben wir jetzt beides - Zeitschaltung morgend u. abends, plus an den "Hauptzapfstellen" Taster, die für 5 Minuten die Circopumpe laufen lassen. Das klappt insgesamt jetzt gut, und sogar Kinder verstehen das sehr schnell... :)
-
@jleg sagte in WW Zirkulationspumpe bedarfsgerecht ein- und ausschalten:
nach einigem Herumprobieren auch mit kommerziellen Automatik-Lösungen haben wir jetzt beides - Zeitschaltung morgend u. abends, plus an den "Hauptzapfstellen" Taster, die für 5 Minuten die Circopumpe laufen lassen. Das klappt insgesamt jetzt gut, und sogar Kinder verstehen das sehr schnell...
So habe ich das auch.
-
ich werf da mal was in den Ring
-
ich werf da mal was in den Ring
-
@homoran Hattest du eine Seite vorher schon :grinning:
Frage mich welche Hochleistungszirkulationspumpe da zum Einsatzkommen muss damit das Warme wasser schneller am Hahn ist.
Hat da jemand Erfahrungswerte?
@wendy2702 sagte in WW Zirkulationspumpe bedarfsgerecht ein- und ausschalten:
@homoran Hattest du eine Seite vorher schon :grinning:
Frage mich welche Hochleistungszirkulationspumpe da zum Einsatzkommen muss damit das Warme wasser schneller am Hahn ist.
Hat da jemand Erfahrungswerte?
unsere vermutlich nicht ungewöhnliche Stratos Eco-Z lässt sich von 6 - 60W einstellen. Und 60W ballern schon ganz gut ;) - im Timerbetrieb reichen bei uns 10-12W völlig…
-
@wendy2702 sagte in WW Zirkulationspumpe bedarfsgerecht ein- und ausschalten:
@homoran Hattest du eine Seite vorher schon :grinning:
Frage mich welche Hochleistungszirkulationspumpe da zum Einsatzkommen muss damit das Warme wasser schneller am Hahn ist.
Hat da jemand Erfahrungswerte?
unsere vermutlich nicht ungewöhnliche Stratos Eco-Z lässt sich von 6 - 60W einstellen. Und 60W ballern schon ganz gut ;) - im Timerbetrieb reichen bei uns 10-12W völlig…
-
@homoran Hattest du eine Seite vorher schon :grinning:
Frage mich welche Hochleistungszirkulationspumpe da zum Einsatzkommen muss damit das Warme wasser schneller am Hahn ist.
Hat da jemand Erfahrungswerte?
@wendy2702 Habe hier eininge Versuche gemacht und in einem typischen Haushalt/Haus mit Brauchwasserspeicher im Keller und Bäder im EG, OG, DG braucht eine typische Umwäzpumpe ca. 20sec und die Leitung ist genügend voll mit warmem Wasser. Von nun an kommt ja auch, ohne Pumpe, genügend warmes Wasser nach.
-
@alk
Das Problem dieser Lösung ist doch, dass warmes Wasser zu spät kommt. Wenn ich warmes Wasser brauche, dann in dem Augenblick, wenn ich den Hahn öffne. Das Warmwasser kommt aber erst zwei Minuten später. Gut, man kann ja auch mal kalt duschen. Tut aber der Scheidungsquote nicht gut.
Ich habe eine Funklösung realisiert, die wunderbar funktioniert. Im Bad und am Zugang zur Küche sind Taster, die die Umwälzpumpe einschalten. Das passt zeitlich fast immer. Und die Lösung ist käuflich und Plug'nPlay. Übrigens hatte ich eine manuelle Lösung ca. 20 Jahre drahtgebunden realisiert.Und in der Gästetoilette ist ein 16 A Klein-Durchlauferhitzer installiert. Der funktioniert sehr gut und ist kompatibel mit einer normalen Steckdose da nur Kurzzeitbetrieb. Eine sehr energiesparende Lösung, die auch einfach zu installieren ist, wenn eine Steckdose vorhanden ist.
@cumulus-0 Mit einem Schlater ist es auch ein gute Möglichkeit. Aktuell braucht es bis warmes Wasser kommt ca. 20sec nachdem du das Wasser aufgedreht hast.
-
Also bei mir geht im Bad das Radio an wenn jemand Licht anmacht ... da könnte ich auch gleich die Pumpe 20 Sekunden laufen lassen ...
Oder per ZigBee Türkontakt. Dann bräuchte es aber etwas um festzustellen ob man rein oder rausgeht. Oder man geht nach Zeit und ob sich die Wasseruhr vorher gedreht hat (was diese nicht getan haben sollte)
-
Also bei mir geht im Bad das Radio an wenn jemand Licht anmacht ... da könnte ich auch gleich die Pumpe 20 Sekunden laufen lassen ...
Oder per ZigBee Türkontakt. Dann bräuchte es aber etwas um festzustellen ob man rein oder rausgeht. Oder man geht nach Zeit und ob sich die Wasseruhr vorher gedreht hat (was diese nicht getan haben sollte)
@bananajoe Da hast Du mich auf eine super Idee gebracht. Ich hatte vorher schon die Zirkulationspumpe per Shelly angesteuert. Ich habe zwar im Haus auch 2 Wemos verbaut, aber für die Zirkulationspumpe finde ich die Shelly Lösung einfacher und wenn man den Eco Modus einschaltet und die Cloud ausschaltet ist der Stromverbrauch der Shellys auch wirklich niedrig (~0,4 W).
Jedenfalls habe ich über Homematic ein kleines Script aktiviert, was die Pumpe für 2 Minuten laufen lässt, sowie eine Variable setzt, wenn der Lichtschalter betätigt wird. Täglich prüft morgens ein weiteres Script ob am Vortag die Pumpe gelaufen ist und schaltet automatisch ein, wenn nicht. Somit wird jeden Tag mindestens einmal das Wasser umgewälzt, Desinfektionsschaltung läuft nach wie vor wöchentlich.
Im Bad ist zusätzlich ein Bewegungsmelder installiert, welcher aber das Licht nur gedimmt einschaltet. Somit drücken wir den Schalter in der Regel auch nur dann, wenn auch wirklich Bedarf besteht. -
Möchte mich hier mit meinen Gedanken anschließen, da ich die gleiche Idee / gleiche Ziel hatte, selber aber einen etwas anderen Weg gegangen bin.
Zeitschaltuhr
Ursprünglich war eine Zeitschaltuhr an der Zirkulationspumpe angeschlossen, welche die auf niedrigster Stufe laufende WW Zirkulationspumpe jeweils eine halbe Stunde über den Tag verteilt anschmiss.
Danach tauschte ich die Zeitschaltuhr gegen ein Sonoff/Tasmota Relais. Die Zirkulation musste ca. 10 Minuten auf höchster Stufe laufen, bis die Temperatur im Rücklauf nicht mehr stieg. Also baute ich eine Rule mit einer Dauer von ca. 10 Minuten und schaltete mit den Timern die Pumpe an, über die Rule aus.Smarte Lösungsideen
Folgende Lösungen standen/stehen zur Wahl:- Zeitschaltuhr nur bei Anwesenheit aktiv
- Temperaturabhängig VL zu RL Temperatur
- Bedarfsabhängig
-
- Temperatursteigerung
-
- Durchflussschalter (HT-120) oder Durchflusssensor (YF-B5 als Counter - ungenau, aber ausreichend als Schalter)
Die Zeitschaltuhr in Tasmota über iobroker nur bei Anwesenheit mindestens einer Person zu aktivieren war mir nicht smart genug. Auch ein Schalten ab einer definierten Differenz, oder dem Verhältnis zwischen Vor und Rücklauftemperatur schied aus, da hier zwar ebenfalls mit der Anwesenheit gearbeitet werden könnte, aber trotzdem zu viel Wärmeverlust im WW Speicher auftreten würde.
Bleiben also die Bedarfsabhängigen Lösungen übrig. Der Durchflussensor, oder -schalter war nicht vorhanden und müsse hinter/vor die Pumpe eingebaut werden, was ich mir nicht zutraute, wäre aber vermutlich die technisch bessere Lösung, da sie schneller reagiert.
Aktuell habe ich es über die Temperatursteigerung gelöst, da (bis auf die Temperatursensoren) kein großartiger Umbauaufwand notwendig war.Umsetzung
Ich stieß auf das Skript in diesem Post und passte es so an, dass ich nur die Temperaturänderung in einen Datenpunkt schrieb und diese mit Grafana loggte und erst mal die Lösung mit der Zeitschaltuhr analysierte:
Die Zirkulationspumpe wird regelmäßig 14x am Tag eingeschaltet, ob Warmwasser benötigt wird, oder nicht. Ob jemand daheim ist, oder nicht.Deaktiviere ich die Zeitschaltuhr und aktiviere das Bedarfsskript, sieht das schon mal anders aus:

Es wurde seltener WW benötigt und die Pumpe bei jedem Bedarf aktiviert.
Die Pumpe läuft nur noch so lange, bis der Rücklauf keine Temperatursteigerung mehr (unter angegebener Grenze) hat (ca. 8 Minuten, schwankend).
Damit die Pumpe nicht gleich wieder abschaltet, weil die Temperatursteigerung im Rücklauf noch zu gering ist, ist eine Mindestlaufzeit eingebaut nach welcher erst die Temperaturänderung im Rücklauf geprüft wird.
Um ein unnötiges weiteres Erhöhen der Temperatur zu vermeiden, habe ich eine Untergrenze für den Vorlauf eingebaut:
Man sieht schön wie um ca. 7 Uhr WW erzeugt wird und sich die Zuleitung aufgrund der aufsteigenden Temperatur erwärmt und wie ich um 0:30 Uhr noch Zähne geputzt habe :) Zwischen 17 und 19 Uhr war die Temperatur im Vorlauf wegen häufigen Bedarfen über dem Mindestwert, sodass die Pumpe nicht nachhelfen musste.Bei einem Tag mit Abwesenheit läuft die Pumpe noch seltener:

Ausreißer
Da sie DS18B20 Sensoren hin und wieder seltsame Temperaturen zurückgeben und sich so Ausreißer nach oben und unten ergeben, habe ich im Skript ab einem Höchstwert von 5 die Spitzen abgeschnitten, bzw. wird der Datenpunkt nicht aktualisiert. Diese Ausreißer werden zusätzlich noch mit Hilfe des alten Messwerts vermittelt (h1 + speedVLold).Nachteile:
- Verzögerung durch Aktualisierungsintervall von 10s und Trägheit des Temperaturanstiegs am Rohr zzgl. bis das WW an die Stichleitung gepumpt wird
- iobroker muss laufen
Fazit:
Bisher läuft das Skript sehr gut, Bedarfe werden gut erkannt und nicht auf zu kleine Mengen reagiert. Wird immer wieder Warmwasser gezapft, bleibt die Leitung warm und die Pumpe aus, bedeutet jedoch, dass das Warmwasser in der Leitung bis zur letzten Zapfstelle abkühlt...
Noch besser wäre wie beschrieben mit einem Durchflussensor schneller darauf zu reagieren, oder die gesammelten Daten in eine Art KI zu schieben und schon im Voraus zu erkennen, ob man gleich Warmwasser braucht :D aber dafür ist unser Bedarf vermutlich nicht regelmäßig genug...
Eine Ersparnis konnte ich bisher nicht feststellen und werde ich im Nachhinein auch nicht auswerten können, da die Heizung noch nicht ganz korrekt am iobroker angebunden ist, aber sie müsste allein aufgrund der Tage in Abwesenheit, oder im Urlaub (habe nie die Zeitschaltuhr deaktiviert) da sein.
Ich hoffe ich kann manch einem mit meinem Erfahrungsbericht helfen und somit auch mal was an die Community zurückgeben.hier noch der aktuelle Stand des Skripts mit allen (deaktivierten) Debug Meldungen während der Analyse:
//https://forum.iobroker.net/post/133815 //VL const idTempVL = 'sonoff.0.HWR.DS18B20-2_Temperature'; const iddTVL = '0_userdata.0.WWZirkulationspumpe.dTVL'; const swOn = 0.7; // Grenzwert in K/min var speedVL var speedVLold = 0; //RL const idTempRL = 'sonoff.0.HWR.DS18B20-1_Temperature'; const iddTRL = '0_userdata.0.WWZirkulationspumpe.dTRL'; const swOff = 0.3; // Grenzwert in K/min var speedRL var speedRLold = 0; var timer = null; const minTime = 60000 // Minimum Zeit in Millisekunden, welche die Pumpe laufen soll, bevor abgeschalten werden kann (TRL ist noch unter swOff) const minTemp = 36 // Minimum Temperatur, bevor die Pumpe wieder läuft var check = false; // Check für minTime var check2 = 1; // Check für minimalen speedVL für Ausschalten, sonst wird zu früh abgeschalten var h1, h2 const idAktor = 'sonoff.0.HWR.POWER2'; var aktor = getState(idAktor).val; on({id: idAktor, ack: true}, function(dp) {aktor = dp.state.val;}); ////////////////////////////////////////////////////////// /* Einschalten bei steigender Vorlauftemperatur */ on(idTempVL, function(dp) { // Triggern bei Wertänderung h1 = 60000 * (dp.state.val - dp.oldState.val) / (dp.state.lc - dp.oldState.lc); // K/min speedVL = (h1 + speedVLold)/2; //console.debug(([Math.round(speedVL*100)/100,' speedVL = (',Math.round(h1*100)/100,' + ',Math.round(speedVLold*100)/100,')/2 K/min'].join(''))); speedVLold = h1; if (speedVL < -5 || speedVL > 5) {return;} //console.debug((['state - oldState: ',dp.state.val,' - ',dp.oldState.val,' = ',Math.round((dp.state.val - dp.oldState.val)*100)/100].join(''))); //console.debug((['TDiff: ',(dp.state.lc - dp.oldState.lc),'ms'].join(''))); //console.debug(([speed,' K/min.'].join(''))); setState(iddTVL, Math.round(speedVL*1000)/1000, true); if (speedVL >= swOn && !aktor && getState(idTempVL).val <= minTemp) { setState(idAktor,true); var messageText =['Zirkulationspumpe an. (*dTVL: ',Math.round(speedVL*1000)/1000,', dTRL: ',Math.round(speedRL*1000)/1000,')'].join(''); //sendTo("telegram", "send", { text: messageText }); console.log((messageText)); /* Prüfung mit Alarm */ if (!getState("0_userdata.0.Anwesenheit.Status.anyonePresent").val) { var messageText =['Zirkulationspumpe an, obwohl niemand da ist!\r\n(*dTVL: ',Math.round(speedVL*1000)/1000,', dTRL: ',Math.round(speedRL*1000)/1000,')'].join(''); sendTo("telegram", "send", { text: messageText }); console.error((messageText)); } //console.debug(([Math.round(speed*100)/100,' K/min'].join(''))); //console.debug((['Temperatur ist um mehr als ',gw,' K/min gestiegen.'].join(''))); //clearTimeout(timer); timer = setTimeout(function() { //if(aktor) setState(idAktor, false); check = true }, minTime); } }); /* Ausschalten bei fallender Rücklauftemperatur, nach minimaler Zeit, bei stagnierender Vorlauftemperatur */ on(idTempRL, function(dp) { // Triggern bei Wertänderung h2 = 60000 * (dp.state.val - dp.oldState.val) / (dp.state.lc - dp.oldState.lc); // K/min speedRL = (h2 + speedRLold)/2; //console.debug(([Math.round(speedRL*100)/100,' speedRL = (',Math.round(h2*100)/100,' + ',Math.round(speedRLold*100)/100,')/2 K/min'].join(''))); speedRLold = h2; if (speedRL < -5 || speedRL > 5) {return;} setState(iddTRL, Math.round(speedRL*1000)/1000, true); if(speedRL <= swOff && speedRL > 0 && aktor && check && speedVL <= check2) { clearTimeout(timer); check = false setState(idAktor,false); var messageText =['Zirkulationspumpe aus. (dTVL: ',Math.round(speedVL*1000)/1000,', *dTRL: ',Math.round(speedRL*1000)/1000,')'].join(''); //sendTo("telegram", "send", { text: messageText }); console.log((messageText)); } }); //Debug /* on({id: new RegExp(idTempVL + "$|" + idTempRL + "$"), change: "ne"}, async function (obj) { console.debug((['(dTVL: ',Math.round(speedVL*1000)/1000,', dTRL: ',Math.round(speedRL*1000)/1000,', aktor: ',aktor,', timeout: ',check,')'].join(''))); }); */@h07d0q Ich habe das mit einem sonoff Basic R3 gelöst.
Da hat man esp, Relais und Netzteil alles in einem Gerät.
Viel besser als Rules ist Script, dazu muss man tasmota selbst kompilieren, das ist aber sehr easy.
Und wenn man original maxim ds18b20 bestellt, hat man auch keine Temperatur Ausreißer. -
@alk Richtig, genau so ist es aufgebaut (in diesem Fall ein Sonoff Dual R2, der auch die Außenbeleuchtung schaltet)
wiffi-pump habe ich davor auch gesehen, möglicherweise hat er mich inspiriert ;)Ich hab das Skript oben mit meiner aktuellen Version aktualisiert - es kamen ein paar Kommentare dazu und eine Alarmmeldung wenn niemand im Haus ist und die Zirkulationspumpe aktiviert wird (zu Testzwecken und jetzt drin geblieben).

Zu Analysezwecken habe ich auch eine Heatmap in Grafana aufgebaut :DNatürlich wäre es schicker wenn die Logik wie bei Eugen Stall alles im Mikrocontroller umgesetzt wäre, dann hätte man eine kürzere Verzögerung für das Zuschalten der Pumpe. Das mit der Auswertung und Analyse müsste man dann anders lösen wenn man das möchte. Und ich bräuchte dann einen weiteren ESP nur für diese Aufgabe, außer man bekommt das irgendwie auch mit Tasmota Rules hin.
Naja wer weiß... "irgendwann" mal ;) -
-
@noschvie
meine aktuelle Version habe ich minimal angepasst.//https://forum.iobroker.net/post/133815 //VL const idTempVL = 'sonoff.0.HWR.DS18B20-2_Temperature'; const iddTVL = '0_userdata.0.WWZirkulationspumpe.dTVL'; const swOn = 0.7; // Grenzwert in K/min var speedVL var speedVLold = 0; //RL const idTempRL = 'sonoff.0.HWR.DS18B20-1_Temperature'; const iddTRL = '0_userdata.0.WWZirkulationspumpe.dTRL'; const swOff = 0.3; // Grenzwert in K/min var speedRL var speedRLold = 0; var timer = null, alarmTimer; var iAlarmTimer = 40*60000; // Wenn die Pumpe außergewöhnlich lange läuft const minTime = 120000; // Minimum Zeit in Millisekunden, welche die Pumpe laufen soll, bevor abgeschalten werden kann (TRL ist noch unter swOff) const minTemp = 38; // Minimum Temperatur, bevor die Pumpe wieder läuft const minPercent = 0.8; // Minimum Prozent von RL/VL bevor abgeschalten wird var checkMinTimeErreicht = false; // Check für minTime var checkMinSpeedVL = 1; // Check für minimalen speedVL für Ausschalten, sonst wird zu früh abgeschalten var h1, h2 const idAktor = 'sonoff.0.HWR.POWER2'; var aktor = getState(idAktor).val; on({id: idAktor, ack: true}, function(dp) {aktor = dp.state.val;}); // Erweiterter Log im ioBroker const LOG_INFO = true; // Informationen loggen const LOG_DEBUG = false; // Erweiterter Log für Debugging const Telegram_DEBUG = false; // Erweiterter Log für Debugging ////////////////////////////////////////////////////////// /* Einschalten bei steigender Vorlauftemperatur */ on(idTempVL, function(dp) { // Triggern bei Wertänderung h1 = 60000 * (dp.state.val - dp.oldState.val) / (dp.state.lc - dp.oldState.lc); // K/min speedVL = (h1 + speedVLold)/2; //if (LOG_DEBUG) console.debug(([Math.round(speedVL*100)/100,' speedVL = (',Math.round(h1*100)/100,' + ',Math.round(speedVLold*100)/100,')/2 K/min'].join(''))); speedVLold = h1; if (speedVL < -5 || speedVL > 5) {return;} //if (LOG_DEBUG) console.debug((['state - oldState: ',dp.state.val,' - ',dp.oldState.val,' = ',Math.round((dp.state.val - dp.oldState.val)*100)/100].join(''))); //if (LOG_DEBUG) console.debug((['TDiff: ',(dp.state.lc - dp.oldState.lc),'ms'].join(''))); //if (LOG_DEBUG) console.debug(speedVL + ' K/min.'); setState(iddTVL, Math.round(speedVL*1000)/1000, true); if (LOG_DEBUG) console.debug('VL: ' + speedVL + ' >= ' + swOn + ' & ' + !aktor + ' & ' + getState(idTempVL).val + ' <= ' + minTemp); if (speedVL >= swOn && !aktor && getState(idTempVL).val <= minTemp) { setState(idAktor,true); var messageText =['Zirkulationspumpe an. (*dTVL: ',Math.round(speedVL*1000)/1000,', dTRL: ',Math.round(speedRL*1000)/1000,')'].join(''); //if (Telegram_DEBUG) sendTo("telegram", "send", { text: messageText }); if (LOG_INFO) console.log((messageText)); /* Prüfung mit Alarm */ if (!getState("0_userdata.0.Anwesenheit.Status.anyonePresent").val) { var messageText =['Zirkulationspumpe an, obwohl niemand da ist!\r\n(*dTVL: ',Math.round(speedVL*1000)/1000,', dTRL: ',Math.round(speedRL*1000)/1000,')'].join(''); sendTo("telegram", "send", { text: messageText }); console.error((messageText)); } if (LOG_INFO) console.log(Math.round(speedVL*100)/100 + ' K/min'); if (LOG_INFO) console.log('Temperatur ist um mehr als ' + swOn + ' K/min gestiegen.'); //clearTimeout(timer); timer = setTimeout(function() { //if(aktor) setState(idAktor, false); checkMinTimeErreicht = true }, minTime); alarmTimer = setTimeout(function() { var messageText = 'speedRL: ' + Math.round(speedRL*1000)/1000 + ' <= ' + swOff + '\r\nspeedRL: ' + Math.round(speedRL*1000)/1000 + ' > 0 \r\nspeedRL: ' + Math.round(speedRL*1000)/1000 + ' > ' + Math.round(speedRLold*1000)/1000 + '(old)\r\naktor: ' + aktor + '\r\ncheckMinTimeErreicht: ' + checkMinTimeErreicht + '\r\nSpeedVl: ' + Math.round(speedVL*1000)/1000 + ' <= ' + checkMinSpeedVL + '\r\nRL/VL Temp: ' + (getState(idTempRL).val+4.0) + '/' + getState(idTempVL).val + ' = ' + Math.round(((getState(idTempRL).val+4.0)/getState(idTempVL).val)*100)/100 + ' > ' + minPercent; sendTo("telegram", "send", { text: 'Zirkulationspumpe läuft seit mehr als ' + iAlarmTimer/60000 + ' Minuten!\r\n\r\n' + messageText }); }, iAlarmTimer); } }); /* Ausschalten bei fallender Rücklauftemperatur, nach minimaler Zeit, bei stagnierender Vorlauftemperatur */ /* neu: minPercent */ on(idTempRL, function(dp) { // Triggern bei Wertänderung h2 = 60000 * (dp.state.val - dp.oldState.val) / (dp.state.lc - dp.oldState.lc); // K/min speedRL = (h2 + speedRLold)/2; //if (LOG_DEBUG) console.debug(([Math.round(speedRL*100)/100,' speedRL = (',Math.round(h2*100)/100,' + ',Math.round(speedRLold*100)/100,')/2 K/min'].join(''))); speedRLold = h2; if (speedRL < -5 || speedRL > 5) {return;} setState(iddTRL, Math.round(speedRL*1000)/1000, true); var messageText = 'speedRL: ' + Math.round(speedRL*1000)/1000 + ' <= ' + swOff + '\r\nspeedRL: ' + Math.round(speedRL*1000)/1000 + ' > 0 (deaktiviert) \r\nspeedRL: ' + Math.round(speedRL*1000)/1000 + ' < ' + Math.round(speedRLold*1000)/1000 + '(old)\r\naktor: ' + aktor + '\r\ncheckMinTimeErreicht: ' + checkMinTimeErreicht + '\r\nSpeedVl: ' + Math.round(speedVL*1000)/1000 + ' <= ' + checkMinSpeedVL + '\r\nRL/VL Temp: ' + (getState(idTempRL).val+4.0) + '/' + getState(idTempVL).val + ' = ' + Math.round(((getState(idTempRL).val+4.0)/getState(idTempVL).val)*100)/100 + ' > ' + minPercent; if (LOG_DEBUG) console.debug('RL! ' + messageText); //if(speedRL <= swOff && speedRL > 0 && speedRL < speedRLold && aktor && checkMinTimeErreicht && speedVL <= checkMinSpeedVL && (getState(idTempRL).val/getState(idTempVL).val) > minPercent) { if(speedRL <= swOff && speedRL < speedRLold && aktor && checkMinTimeErreicht && speedVL <= checkMinSpeedVL && (getState(idTempRL).val/getState(idTempVL).val) > minPercent) { clearTimeout(timer); checkMinTimeErreicht = false setState(idAktor,false); messageText = 'Zirkulationspumpe aus\r\n' + messageText if (Telegram_DEBUG) sendTo("telegram", "send", { text: messageText }); if (LOG_INFO) console.log((messageText)); clearTimeout(alarmTimer); } }); //Debug /* if (LOG_DEBUG) { on({id: new RegExp(idTempVL + "$|" + idTempRL + "$"), change: "ne"}, async function (obj) { console.debug((['(dTVL: ',Math.round(speedVL*1000)/1000,', dTRL: ',Math.round(speedRL*1000)/1000,', aktor: ',aktor,', timeout: ',checkMinTimeErreicht ,')'].join(''))); }); } */Das läuft so jetzt schon seit mehr als zwei Jahren und meine Frau hat sich nicht beschwert :grin: Die Infos per Telegram müsste ich eigentlich mal einstampfen. Der Alarm bei zu langer Laufzeit ist auf jeden Fall hilfreich, manchmal ist es in Fehlalarm, wenn der Aktor seit der Aktivierung keine WLAN Verbindung hat z.B.. Wie oben schon erwähnt, ist es nicht zu erwarten, dass beim Zapfen direkt Heißwasser kommt, aber nach kurzer Zeit, oder wenn man kurz zapft und dann wartet.