So pausiert der Heizplan in der Fibaro, wenn ein Fenster geöffnet wird, oder die Wohnung verlässt.
Daniel hat mal wieder programmiert (richtig cool!) und ich versuch euch mal erklären was dieses LUA Script macht. :-)
Features v.0.1 :
- pausiert den Heizplan bei:
- geöffnetem Fenster
- Abwesenheit
- verschiedene Temperaturen für Fenster-auf und Abwesenheit
- erkennt ob Fenster zum Lüften geöffnet- oder nur kurz geöffnet wurde
- prüft offene Fenster bei Abwesenheit und Ankunft
- kehrt nach schließen des Fensters, oder bei Ankunft sofort in regulären Heizplan zurück
Ich glaub, ich muss da etwas ausholen. Ich hatte Daniel gebeten, eine Lösung zu finden programmieren, dass die Heizung abgesenkt wird wenn das Fenster geöffnet wird. Aber nach dem Schließen des - oder der Fenster, sollte der reguläre Heizplan im Fibaro Home Center wieder greifen.
Letztes Jahr hatte Alex mal ein ziemlich cooles Script hier im Forum gepostet, welches eigentlich genau das macht. Dieses hab ich seit einem Jahr im Einsatz und es funktioniert meistens wie es soll. Warum "meistens"? Es funktioniert folgendermaßen: Wenn das Fenster geöffnet wird, wartet das Script ob das Fenster länger als eine Minute offen bleibt. Dann wird die aktuelle SOLL - Temperatur des Heizkörperthermostats in einer globalen Variable gespeichert und die Heizung abgesenkt. Wird das Fenster wieder geschlossen, setzt das LUA Script die ursprüngliche Temperatur aus der globalen Variable.
Nun kann es aber sein, das ich zum Beispiel um 16:00 Uhr das Fenster im Kinderzimmer öffne. Es wird eine Temperatur von 23°C gespeichert. Es gibt im Heizplan den Schaltpunkt 16:30 Uhr auf 19°C herunter regeln. Schließe ich das Fenster 16:35 Uhr oder später, wird die Absenktemperatur ignoriert, da das Script die ursprüngliche Temperatur wieder setzt.
Auch für den Abwesenheitsmodus war das Script recht schwierig, denn dem Danfoss Thermostat muss man ausser der SOLL Temperatur auch einen Zeitstempel mitgeben. Dieser gibt an, wie lange die übermittelte Temperatur gilt. Maximal sind hier 6 Stunden möglich. Danach wechselt das Thermostat in den regulären Heizplan zurück.
Wenn es nach Ablauf der Zeit zurück in den regulären Heizplan wechselt, warum also diese Funktion nicht für Fenster - auf nutzen? Nun, wenn ich das Fenster öffne, weiß ich meistens nicht wie lange ich dieses offen lasse ;-)
Fibaro Heizplan pausieren
Auch von Alex kam dann hier ein Script im Forum, welches ursprünglich Fibaro selbst veröffentlicht hat und welches von Alex modifiziert wurde. Dieses nutzt den "Urlaubsmodus" und pausiert somit den Fibaro Heizplan. Das ist genial und gab Daniel die Grundlage für folgendes Script.
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 |
--[[ %% properties 710 value %% globals PresentState --]] --------------- Absenk-Temperatur bei Fenster-Öffnung------------- local schedule = { id = 486, --ID des Raumes im Heiz-Panel idleTemp = 5 --Temperatur, die bei Fenster-Öffnung gesetzt werden soll } --------------- Absenk-Temperatur bei Abwesenheit ---------------- local scheduleAway = { id = 486, --ID des Raumes im Heiz-Panel idleTemp = 20 --Temperatur, die bei Abwesenheit gesetzt werden soll } sensorID = 710 --ID des Tür-/Fenstersensor -- AB HIER NICHTS MEHR ÄNDERN function Debug( color, message ) fibaro:debug(string.format('<%s style="color:%s;">%s<!--%s-->', "span", color, message, "span")); end local function getMethod(requestUrl, successCallback, errorCallback) local http = net.HTTPClient() http:request(requestUrl, { options = { method = 'GET' }, success = successCallback, error = errorCallback }) end local function putMethod(requestUrl, data, successCallback, errorCallback) local http = net.HTTPClient() http:request(requestUrl, { options = { method = 'PUT', data = json.encode(data) }, success = successCallback, error = errorCallback }) end local function setVactionModeTrue(subjectToChange) local url = 'http://127.0.0.1:11111/api/panels/heating/' .. subjectToChange.id getMethod(url, function(resp) if resp.status == 200 then print('Verbindung zum Heizpanel erfolgreich, Status ' .. resp.status) local panel = json.decode(resp.data) if panel.properties.vacationTemperature ~= nil then panel.properties.vacationTemperature = subjectToChange.idleTemp print('Setze Temperatur auf ' .. subjectToChange.idleTemp .. ' C') putMethod(url, panel, function(resp) if resp.status == 200 then print('Änderung wurde vorgenommen.') end end, function(err) print('Error ' .. err) end ) else print('Panel nicht gefunden') end else print('Verbindung konnte nicht hergestellt werden, Status ' .. resp.status) end end, function(err) print('error ' .. err) end ) end local function setVactionModeFalse(subjectToChange) local url = 'http://127.0.0.1:11111/api/panels/heating/' .. subjectToChange.id getMethod(url, function(resp) if resp.status == 200 then print('Verbindung zum Heizpanel erfolgreich, Status ' .. resp.status) local panel = json.decode(resp.data) if panel.properties.vacationTemperature ~= nil then panel.properties.vacationTemperature = 0 print('Setze Heizplan wieder fort.') putMethod(url, panel, function(resp) if resp.status == 200 then print('Änderung wurde vorgenommen.') end end, function(err) print('Error ' .. err) end ) else print('Panel nicht gefunden') end else print('Verbindung konnte nicht hergestellt werden, Status ' .. resp.status) end end, function(err) print('error ' .. err) end ) end local trigger = fibaro:getSourceTrigger(); if (trigger['type']=='global') then if (fibaro:getGlobalValue("PresentState") == "Away") then if (tonumber(fibaro:getValue(sensorID, 'value')) == 0) then setVactionModeTrue(scheduleAway) Debug("blue",'Abwesend, niemand Zuhause, Fahre Heizung runter.') else Debug("white",'Abwesend, niemand Zuhause, Fenster ist noch geöffnet. Es bleibt bei der festgelegten Temperatur.') end elseif (fibaro:getGlobalValue("PresentState") == "Home") then if (tonumber(fibaro:getValue(sensorID, 'value')) == 0) then setVactionModeFalse(schedule) Debug("red", 'Anwesend, jemand ist wieder Zuhause. Schalte Heizplan wieder ein.') else Debug("white",'Anwesend, jemand ist wieder Zuhause. Fenster ist noch geöffnet. Es bleibt bei der festgelegten Temperatur.') end end elseif (trigger['type']=='property') then if (tonumber(trigger['deviceID'])==tonumber(sensorID)) then local sensor = fibaro:getValue(sensorID, 'value') if (tonumber(sensor) == 1) then Debug("yellow", 'Fenster geöffnet.') counter = 0 while (tonumber(fibaro:getValue(sensorID, 'value')) == 1 and counter < 60) do counter = counter + 1 fibaro:sleep(1*1000) end if (tonumber(fibaro:getValue(sensorID, 'value')) == 1) then Debug("blue",'Fenster ist immer noch auf, es wird gelüftet. Fahre Heizung runter.') setVactionModeTrue(schedule) else Debug("yellow", 'Fenster wurde innerhalb einer Minute wieder geschlossen.') end else fibaro:debug('Fenster geschlossen.') Debug("red", 'Fenster ist wieder zu. Schalte Heizplan wieder ein.') setVactionModeFalse(schedule) end end end |
Was macht das neue Fibaro Heizungsscript?
Es adressiert keine Heizkörper Thermostate direkt und gibt diesen keine SOLL Temperatur vor, sondern aktiviert den Urlaubsmodus, in welchem eine definierte Temperatur pro Raum gesetzt wird. Diese wird solange gehalten, bis der Urlaubsmodus wieder deaktiviert wird.
Eine runde Sache mit der perfekten Lichtsteuerung
Wir haben euch in der letzten Zeit wirklich viele, teils sehr komplexe Scripte präsentiert. Letztendlich ist das Smart Home eine modular wachsende Geschichte, aber dennoch greift jedes Modul und jedes Script wie ein Zahnrad in das andere.
Im LUA Script für die perfekte Lichtsteuerung werden die Leuchten alle ausgeschaltet, sobald die globale Variable "PresentState" von Home auf "Away" wechselt. Diese Variable findest du auch hier in diesem Script. Denn nicht nur wenn die Fenster geöffnet werden wird die Heizung gesenkt, sondern auch wenn du das Haus bzw. deine Wohnung verlässt. Ich verwende das RFID Script von Daniel ebenfalls mit der PresentState Variable (anstelle der rfid_alarm Variable wie von Daniel vorgeschlagen). Verlasse ich also das Haus, und schalte den Alarm via RFID Tag oder Karte scharf, so wird nicht nur der Alarm scharf geschaltet, das Danalock schließt die Tür zu, das Licht wird ausgeschaltet und der Staubsauger fährt los, sondern nun senkt sich auch die Temperatur individuell pro Raum ab.
Ich verwende zum Beispiel 5°C als Fenster-offen Einstellung, damit das Ventil komplett geschlossen wird. Bei Abwesenheit wird die Temperatur auf 19°C gesenkt, damit die Wohnung nicht zu sehr auskühlt.
Was passiert, wenn ein Fenster noch offen ist wenn ich die Wohnung verlasse? Auch dies prüft das Script ab und setzt in diesem Fall nicht die Temperatur für Abwesenheit. In meinem Beispiel oben würden also weiterhin 5°C für Fenster-offen gesetzt bleiben. Gleiches gilt, wenn jemand nach Hause kommt. Auch hier wird geprüft ob noch ein Fenster offen ist und der Heizplan pausiert weiterhin mit 5°C, bis das Fenster geschlossen wird.
Was muss ich dazu im Script anpassen?
Nicht viel. Beginnen wir mal ganz oben. Logisch in den Properties die Trigger, also die Auslöser für diese Szene.
- der Fensterkonakt, welcher die Szene startet wenn das Fenster geöffnet wurde (z.B. 710 value)
- deine globale Variable für die Anwesenheit (hier: PresentState)
1 2 3 4 5 6 7 8 |
--[[ %% properties 712 value %% globals PresentState --]] |
Die ID der Zone sieht du in der URL im Browser, wenn du den Heizplan der entsprechenden Zone bearbeitest.
1 2 3 4 5 |
--------------- Absenk-Temperatur bei Fenster-Öffnung------------- local schedule = { id = 486, --ID des Raumes im Heiz-Panel idleTemp = 5 --Temperatur, die bei Fenster-Öffnung gesetzt werden soll } |
Ab der Zeile 14, findest du die identische Funktion, welche aber definiert welche Temperatur "angefahren" werden soll wenn du deine Wohnung verlässt.
1 2 3 4 5 |
--------------- Absenk-Temperatur bei Abwesenheit ---------------- local scheduleAway = { id = 486, --ID des Raumes im Heiz-Panel idleTemp = 20 --Temperatur, die bei Abwesenheit gesetzt werden soll } |
In die Zeile 19 gehört noch die ID deines Fenstersensors hinein:
1 |
sensorID = 710 --ID des Tür-/Fenstersensor |
Danach folgt viel Script. Hier verbindet sich die Fibaro mit sich selbst und pausiert eben den genannten Heizplan. Die IP 127.0.0.1 welche im Script auftaucht, adressiert den local Host, also sich selbst.
Ab Zeile 114 pürft das Script, was eigentlich der Trigger, also der Auslöser war, welcher die Szene gestartet hat. War es die Abwesenheits Variable, so wird die Funktion oben aufgerufen welche die Temperatur setzt für "Abwesenheit"
1 |
if (trigger['type']=='global') then ... |
Sollte die Bedingung (getriggert durch globale Variable) nicht erfüllt sein, so wird ab Zeile 131 abgeprüft, ob es vielleicht durch den Fensterkontakt (property) ausgelöst wurde. Dann wird die andere Funktion ausgeführt und somit auch diese andere definierte Temperatur gesetzt.
1 |
elseif (trigger['type']=='property') then ... |
Falls du in einem Raum zwei Fenster haben solltest, nimmst du das folgende Script:
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 |
--[[ %% properties 710 value 712 value %% globals PresentState --]] --------------- Absenk-Temperatur bei Fenster-Öffnung------------- local schedule = { id = 261, --ID des Raumes / Zone im Heiz-Panel idleTemp = 5 --Temperatur, die bei Fenster-Öffnung gesetzt werden soll } --------------- Absenk-Temperatur bei Abwesenheit ---------------- local scheduleAway = { id = 261, --ID des Raumes im Heiz-Panel idleTemp = 19 --Temperatur, die bei Abwesenheit gesetzt werden soll } sensorID = 710 --ID des Tür-/Fenstersensor1 sensorID2 = 712 --ID des Tür-/Fenstersensor2 -- AB HIER NICHTS MEHR ÄNDERN function Debug( color, message ) fibaro:debug(string.format('<%s style="color:%s;">%s<!--%s-->', "span", color, message, "span")); end local function getMethod(requestUrl, successCallback, errorCallback) local http = net.HTTPClient() http:request(requestUrl, { options = { method = 'GET' }, success = successCallback, error = errorCallback }) end local function putMethod(requestUrl, data, successCallback, errorCallback) local http = net.HTTPClient() http:request(requestUrl, { options = { method = 'PUT', data = json.encode(data) }, success = successCallback, error = errorCallback }) end local function setVactionModeTrue(subjectToChange) local url = 'http://127.0.0.1:11111/api/panels/heating/' .. subjectToChange.id getMethod(url, function(resp) if resp.status == 200 then print('Verbindung zum Heizpanel erfolgreich, Status ' .. resp.status) local panel = json.decode(resp.data) if panel.properties.vacationTemperature ~= nil then panel.properties.vacationTemperature = subjectToChange.idleTemp print('Setze Temperatur auf ' .. subjectToChange.idleTemp .. ' C') putMethod(url, panel, function(resp) if resp.status == 200 then print('Änderung wurde vorgenommen.') end end, function(err) print('Error ' .. err) end ) else print('Panel nicht gefunden') end else print('Verbindung konnte nicht hergestellt werden, Status ' .. resp.status) end end, function(err) print('error ' .. err) end ) end local function setVactionModeFalse(subjectToChange) local url = 'http://127.0.0.1:11111/api/panels/heating/' .. subjectToChange.id getMethod(url, function(resp) if resp.status == 200 then print('Verbindung zum Heizpanel erfolgreich, Status ' .. resp.status) local panel = json.decode(resp.data) if panel.properties.vacationTemperature ~= nil then panel.properties.vacationTemperature = 0 print('Setze Heizplan wieder fort.') putMethod(url, panel, function(resp) if resp.status == 200 then print('Änderung wurde vorgenommen.') end end, function(err) print('Error ' .. err) end ) else print('Panel nicht gefunden') end else print('Verbindung konnte nicht hergestellt werden, Status ' .. resp.status) end end, function(err) print('error ' .. err) end ) end local trigger = fibaro:getSourceTrigger(); if (trigger['type']=='global') then if (fibaro:getGlobalValue("PresentState") == "Away") then if (tonumber(fibaro:getValue(sensorID, 'value')) == 0 and tonumber(fibaro:getValue(sensorID2, 'value')) == 0) then setVactionModeTrue(scheduleAway) Debug("blue",'Abwesend, niemand Zuhause, Fahre Heizung runter.') else Debug("white",'Abwesend, niemand Zuhause, Fenster ist noch geöffnet. Es bleibt bei der festgelegten Temperatur.') end elseif (fibaro:getGlobalValue("PresentState") == "Home") then if (tonumber(fibaro:getValue(sensorID, 'value')) == 0 and tonumber(fibaro:getValue(sensorID2, 'value')) == 0) then setVactionModeFalse(schedule) Debug("red", 'Anwesend, jemand ist wieder Zuhause. Schalte Heizplan wieder ein.') else Debug("white",'Anwesend, jemand ist wieder Zuhause. Fenster ist noch geöffnet. Es bleibt bei der festgelegten Temperatur.') end end elseif (trigger['type']=='property') then if (tonumber(trigger['deviceID'])==tonumber(sensorID) or tonumber(trigger['deviceID'])==tonumber(sensorID2)) then local sensor = fibaro:getValue(sensorID, 'value') local sensor2 = fibaro:getValue(sensorID2, 'value') if (tonumber(sensor) == 1 or tonumber(sensor2) == 1) then Debug("yellow", 'Fenster geöffnet.') counter = 0 while ((tonumber(fibaro:getValue(sensorID, 'value')) == 1 or tonumber(fibaro:getValue(sensorID2, 'value')) == 1 ) and counter < 60) do counter = counter + 1 fibaro:sleep(1*1000) end if (tonumber(fibaro:getValue(sensorID, 'value')) == 1 or tonumber(fibaro:getValue(sensorID2, 'value')) == 1 ) then Debug("blue",'Fenster ist immer noch auf, es wird gelüftet. Fahre Heizung runter.') setVactionModeTrue(schedule) else Debug("yellow", 'Fenster wurde innerhalb einer Minute wieder geschlossen.') end else fibaro:debug('Fenster geschlossen.') Debug("red", 'Fenster ist wieder zu. Schalte Heizplan wieder ein.') setVactionModeFalse(schedule) end end end |
So, dass war mal wieder ein kleines LUA Script passend zur Jahreszeit. Ich hoffe es macht dein Leben ab sofort etwas smarter. Wenn du Ideen hast, wie wir das Script noch weiterentwickeln könnten, dann immer her damit, unden gibt eine eine Kommentarspalte. Vielleicht ein "Holiday Modus" ? Was solltedieser können?
Hier noch ein paar Icon Vorschläge für deine neue Szene: