Inhalt
Die leidige Zirkulation
Vergeudete Energie
Eigenheimbesitzer kennen das Problem: will man in einer entlegeneren Ecke des Hauses oder der Wohnung Warmwasser zapfen, dauert es eine Weile, bis es warm wird. Abhilfe schafft die Warmwasserzirkulation, die das warme Wasser ständig im Kreis durchs ganze Haus schickt.
Das spart zwar Wasser, verschwendet aber Energie, weil Wärme über die Leitung verloren geht. Das läppert sich: Unter Umständen gehen so pro Jahr 1 MWh und mehr verloren, was je nach Energiekosten 500€ und mehr pro Jahr ausmachen kann. Um so mehr bei längerer Abwesenheit oder schlecht isolierten Zirkulationsleitungen.
Expertenmeinung
Hierzu gibt es auch einen interessanten Artikel, den ich im Netz gefunden habe: https://www.ikz.de/uploads/media/Brauchwasser.pdf
Was tun?
- Zirkulation abschalten oder gar nicht erst einbauen lassen.
Je nach Wasserpreis die wahrscheinlich günstigste Lösung – außer man lebt in Spanien oder anderen Gegenden, in denen Wasser sehr kostbar ist. Natürlich entsteht ein Komfortverlust, den eventuell nicht alle Familienmitglieder mittragen wollen.
Ggf. droht die Verkeimung des Brauchwassers durch Stagnation in den Rohren. - Festes Zeitprogramm
Zum Beispiel von 6:00 Uhr bis 21:00 Uhr gibt's sofort warmes Wasser, sonst dauert es ein bisschen.
Bei längerer Abwesenheit könnte man die Pumpe manuell ausschalten – wenn Viessmann diese Funktion hätte – hamse abba nich!
Umprogrammieren ist umständlich – macht kaum einer. - Bedarfsweises Einschalten der Zirkulation
Hier gibt es sehr interessante, fast schon KI getriebene Lösungen, die auch in dem oben verlinkten Artikel beschrieben sind.
Oder alternativ über einen externen Schalter (Shelly o.ä.). - Oder durch kurzfristiges Umstellen des Zirkulationsplans in ViCare mittels der hier beschriebene Lösung – kostet erstmal nichts, kann beliebig mit weiteren Features ergänzt werden.
Kurzzeitige Planänderung
Das API Feature heißt heating.dhw.pumps.circulation.schedule
Viessmann bietet keine direkte Schaltmöglichkeit für die Z-Pumpe an! Man muss also hilfsweise den gesamten Plan (die Schedule) umstellen (Stand März 2024).
Aktuellen Plan wegsichern
Hat man sich einen komplexen Z-Plan überlegt und mühevoll mit der App aktiviert, will man diesen natürlich nicht verlieren, wenn eine temporäre Planänderung eingestellt werden soll. Das Sichern geschieht wie folgt:Den Universal Header Function Node kennt ihr schon. Anschließend wird nur die Schedule und nicht das gesamte Featureset geholt, aus dem JSON ausgelesen und in einer Textdatei gespeichert.
Wenn ihr an der in den vorherigen Kapiteln beschriebenen Benennung der Kontextvariablen (flow.xxx) nichts geändert habt, braucht ihr an dem Flow nichts weiter ändern. Der letzte Schritt ist noch, das Unterverzeichnis für die Datei zu definieren: Im Debian Terminal des Raspberry Pi gebt ihr ein
mkdir /home/pi/.node-red/data
Vorausgesetzt euer NR User heißt "pi". Das war's auch schon. Bei anderen Setups müsst ihr selber herausfinden, wo das NR Verzeichnis liegt.
Nachfolgend noch der NR Flow:
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
[ { "id": "307332136dcf9aba", "type": "file", "z": "640d4a161fb8fa28", "name": "store schedule", "filename": "/home/pi/.node-red/data/schedule.dat", "filenameType": "str", "appendNewline": true, "createDir": false, "overwriteFile": "true", "encoding": "none", "x": 1980, "y": 2600, "wires": [ [] ] }, { "id": "983a8a37d11bbb84", "type": "function", "z": "640d4a161fb8fa28", "name": "Universal Header", "func": "var atoken = flow.get('accessToken')\nmsg.headers = {\n Authorization: \"Bearer \"+ atoken\n}\nmsg.installationID = flow.get('installationID');\nmsg.gatewaySerial = flow.get('gatewaySerial');\nmsg.deviceId = flow.get('deviceID');\nreturn msg;\n\n", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1390, "y": 2600, "wires": [ [ "ea11d14313a275cf" ] ] }, { "id": "a19080bc537c55c6", "type": "inject", "z": "640d4a161fb8fa28", "name": "trigger", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 1210, "y": 2600, "wires": [ [ "983a8a37d11bbb84" ] ] }, { "id": "ea11d14313a275cf", "type": "http request", "z": "640d4a161fb8fa28", "name": "get schedule", "method": "GET", "ret": "obj", "paytoqs": "ignore", "url": "https://api.viessmann.com/iot/v1/features/installations/{{installationID}}/gateways/{{gatewaySerial}}/devices/{{deviceId}}/features/heating.dhw.pumps.circulation.schedule", "tls": "", "persist": false, "proxy": "", "insecureHTTPParser": false, "authType": "", "senderr": true, "headers": [], "x": 1590, "y": 2600, "wires": [ [ "4da8f020882d3638" ] ] }, { "id": "4da8f020882d3638", "type": "function", "z": "640d4a161fb8fa28", "name": "extract schedule", "func": "msg.payload=msg.payload.data.properties.entries.value; \nmsg.topic=\"dhwCircSched\"; \nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1780, "y": 2600, "wires": [ [ "307332136dcf9aba" ] ] }, { "id": "4e3ab02d22894671", "type": "comment", "z": "640d4a161fb8fa28", "name": "aktuellen Plan sichern", "info": "", "x": 1260, "y": 2560, "wires": [] } ] |
Gespeicherten Plan wieder herstellen
Aus Effizienzgründen nutzen alle "Plan ändern" Funktionen dieselben beiden Nodes auf der rechten Seite.
Der Plan wird aus der Datei gelesen. Allerdings liegt dieser im Textformat vor und muss noch etwas erweitert und in JSON konvertiert werden. Das geschieht im schedule JSON Funktionsnode:
1 2 3 4 |
let sched = msg.payload sched = '{"newSchedule":' + sched + '}'; msg.payload = JSON.parse(sched); return msg; |
Pumpe komplett ausschalten
Diese Funktion ist u.a. sinnvoll als standardmäßige Einstellung der Zirkulation. Das Einschalten erfolgt dann – ggf. für nur wenige Minuten – über einen manuellen Befehl oder eine andere Logik. Siehe Kapitel "Intelligenz" weiter unten.
Der set schedule "0" Node sieht wie folgt aus:
1 2 3 4 5 6 7 8 |
//Lösungsidee aus https://forum.iobroker.net/topic/46778/test-viessmannapi-v2-0-0/420?_=1663696561218 // Plan: Pumpe AUS var pump = '{"newSchedule":{"mon":[], "tue":[],"wed":[],"thu":[],"fri":[],"sat":[],"sun":[]}}' msg.payload = JSON.parse(pump); return msg; |
Hier wird für jeden Wochentag ein leeres Objekt übergeben.
Auch hier macht es Sinn, diese Funktion einige Minuten nach dem Einschalten der Pumpe auszuführen; das Wasser in der Leitung ist warm, die Pumpe wird nicht mehr benötigt.
Pumpe zu bestimmten Zeiten einschalten
Mit den Einschaltzeiten kann man beliebig spielen. Es können auch mehrere Zeiten pro Tag definiert werden. In diesem Beispiel wird die Pumpe tagsüber eingeschaltet: Darauf achten, dass die Minuten immer durch 10 teilbar sind, also 10, 20, 30, etc.
1 2 3 4 5 6 7 8 |
//Lösungsidee aus https://forum.iobroker.net/topic/46778/test-viessmannapi-v2-0-0/420?_=1663696561218 // Plan: Pumpe an tagsüber - ggf anpassen var pump = '{"newSchedule":{"mon":[{"start":"06:00","end":"21:00","mode":"on","position":0}],"tue":[{"start":"06:00","end":"21:00","mode":"on","position":0}],"wed":[{"start":"06:00","end":"21:00","mode":"on","position":0}],"thu":[{"start":"06:00","end":"21:00","mode":"on","position":0}],"fri":[{"start":"06:00","end":"21:00","mode":"on","position":0}],"sat":[{"start":"06:00","end":"21:00","mode":"on","position":0}],"sun":[{"start":"06:00","end":"21:00","mode":"on","position":0}]}}' msg.payload = JSON.parse(pump); return msg; |
Und hier die drei "Plan ändern" Funktionen in einem JSON Flow:
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
[ { "id": "71109d791bde5d1a", "type": "file in", "z": "640d4a161fb8fa28", "name": "read schedule", "filename": "/home/pi/.node-red/data/schedule.dat", "filenameType": "str", "format": "utf8", "chunk": false, "sendError": false, "encoding": "none", "allProps": false, "x": 1440, "y": 2720, "wires": [ [ "ec61153bef8c6208" ] ] }, { "id": "ec40ad233db9c172", "type": "inject", "z": "640d4a161fb8fa28", "name": "trigger", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 1210, "y": 2720, "wires": [ [ "71109d791bde5d1a" ] ] }, { "id": "dfc2b8b5f9bf9337", "type": "http request", "z": "640d4a161fb8fa28", "name": "set schedule", "method": "POST", "ret": "txt", "paytoqs": "ignore", "url": "https://api.viessmann.com/iot/v1/features/installations/{{installationID}}/gateways/{{gatewaySerial}}/devices/{{deviceId}}/features/heating.dhw.pumps.circulation.schedule/commands/setSchedule", "tls": "", "persist": false, "proxy": "", "insecureHTTPParser": false, "authType": "", "senderr": false, "headers": [], "x": 2070, "y": 2820, "wires": [ [] ] }, { "id": "cd43bdcdffc780c7", "type": "function", "z": "640d4a161fb8fa28", "name": "Headers & Parameter", "func": "var atoken = flow.get('accessToken')\n\nmsg.headers = {};\nmsg.headers['content-type'] = 'application/json';\nmsg.headers['Authorization'] = \"Bearer \" + atoken;\n\nmsg.installationID = flow.get('installationID');\nmsg.gatewaySerial = flow.get('gatewaySerial');\nmsg.deviceId = flow.get('deviceID');\n\nreturn msg;\n\n", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1860, "y": 2820, "wires": [ [ "dfc2b8b5f9bf9337" ] ] }, { "id": "8696147cdc1f5a57", "type": "inject", "z": "640d4a161fb8fa28", "name": "", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 1220, "y": 2820, "wires": [ [ "8d2f4b411ce7d751" ] ] }, { "id": "ec61153bef8c6208", "type": "function", "z": "640d4a161fb8fa28", "name": "schedule JSON", "func": "let sched = msg.payload\nsched = '{\"newSchedule\":' + sched + '}';\nmsg.payload = JSON.parse(sched);\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1640, "y": 2720, "wires": [ [ "cd43bdcdffc780c7" ] ] }, { "id": "f0e6321196d4733c", "type": "comment", "z": "640d4a161fb8fa28", "name": "gesicherten Plan aktivieren", "info": "", "x": 1270, "y": 2680, "wires": [] }, { "id": "d4de2144d70bbb3d", "type": "comment", "z": "640d4a161fb8fa28", "name": "Pumpe immer AUS", "info": "", "x": 1250, "y": 2780, "wires": [] }, { "id": "ae960b9ae438849d", "type": "function", "z": "640d4a161fb8fa28", "name": "set schedule \"1\"", "func": "//Lösungsidee aus https://forum.iobroker.net/topic/46778/test-viessmannapi-v2-0-0/420?_=1663696561218\n\n// Plan: Pumpe an tagsüber - ggf anpassen \nvar pump = '{\"newSchedule\":{\"mon\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"tue\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"wed\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"thu\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"fri\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"sat\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"sun\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}]}}'\n\n// Plan: Pumpe AUS\n//var pump = '{\"newSchedule\":{\"mon\":[], \"tue\":[],\"wed\":[],\"thu\":[],\"fri\":[],\"sat\":[],\"sun\":[]}}' \n\nmsg.payload = JSON.parse(pump);\n\nreturn msg;\n\n\n\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1440, "y": 2920, "wires": [ [ "cd43bdcdffc780c7" ] ] }, { "id": "7a20a29270cfef5b", "type": "inject", "z": "640d4a161fb8fa28", "name": "", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 1220, "y": 2920, "wires": [ [ "ae960b9ae438849d" ] ] }, { "id": "8d2f4b411ce7d751", "type": "function", "z": "640d4a161fb8fa28", "name": "set schedule \"0\"", "func": "//Lösungsidee aus https://forum.iobroker.net/topic/46778/test-viessmannapi-v2-0-0/420?_=1663696561218\n\n// Plan: Pumpe an tagsüber - ggf anpassen \n//var pump = '{\"newSchedule\":{\"mon\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"tue\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"wed\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"thu\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"fri\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"sat\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}],\"sun\":[{\"start\":\"06:00\",\"end\":\"21:00\",\"mode\":\"on\",\"position\":0}]}}'\n\n// Plan: Pumpe AUS\nvar pump = '{\"newSchedule\":{\"mon\":[], \"tue\":[],\"wed\":[],\"thu\":[],\"fri\":[],\"sat\":[],\"sun\":[]}}' \n\nmsg.payload = JSON.parse(pump);\n\nreturn msg;\n\n\n\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1440, "y": 2820, "wires": [ [ "cd43bdcdffc780c7" ] ] }, { "id": "cb2e13786812f0f3", "type": "comment", "z": "640d4a161fb8fa28", "name": "Pumpe tagsüber AN", "info": "", "x": 1250, "y": 2880, "wires": [] } ] |
"Intelligenz"
Wir haben jetzt unser Rüstzeug beisammen, um fast beliebige Szenarien zu realisieren.
- Manuelles Aus-/Einschalten
Triviallösung über einen Button in NR oder über eine an NR angeschlossene Fernbedienung (z.B. Shellybutton) oder Alexa. Sinnvoll ist es bei jedem Szenario, die Pumpe nach eine gewissen Laufzeit auch wieder automatisch auszuschalten. - Automatisches Einschalten bei Bedarf
z.B. über einen Anlegefühler an der WW Vorlaufleitung. Wird dort ein Temperaturanstieg bemerkt – jemand zapft Warmwasser – wird die Pumpe eingeschaltet, um die Wartezeit zu verkürzen.
Oder über einen PIR Annäherungsschalter im Badezimmer oder der Toilette.
Oder, oder, oder - Automatisches "Entkeimen" der Leitung wenn der WW Speicher gerade auf 60°C oder mehr aufgeheizt ist. Das Thema Legionellen ist nicht zu unterschätzen.
Hallo Chris,
danke für die tolle Lösung.
Das wird meine Energiekosten für die Warmwasseraufbereitung senken.
Mein Haus ist über 30 Jahre alt, und über die Zirkulation geht jede Menge Energie verloren, da damals die Leitungen nur sehr stiefmütterlich isoliert wurden.
Ich koppele jetzt deine Lösung mit unserer Alarmanlage; wenn an, dann außer Haus, dann keine Zirkulation.
Ich denke mal, dass ich die Pumpe nicht komplett ausschalten werde, sondern im Urlaubsfall für 10 / 20 Minuten laufen lasse, da mir das Thema "Legionellen" doch ein wenig zu heikel ist.
Nochmals Danke!
Viele Grüße Jürgen