Hallo zusammen,
in dieser Version gibt es jetzt die versprochene doorcheck Funktion. Wobei ich sagen muss dass die nicht ganz ungefährlich ist. Was passiert wenn jemand Abends im Sommer auf der Terrasse geht und instinktiv die Tür hinter sich zuzieht??? Richtig, nach einer Minute geht der letzte Rolladen runter. Aber das darf jeder selbst entscheiden ob er die Funktion nutzt.
Auf jeden Fall ist es so programmiert dass das Script nicht (eventuell stundenlang) in einer Endlosschleife verharrt, sondern weiterhin minütlich seine Bedingungen prüft.
Bis die Dokumentation fertig ist, mal kurz die Funktionsweise.
Die Funktion ‘goodNightWdoorCheck()’ prüft alle Rollläden aus dem lokalen Array ‘rollerIDsN’, in der alle Rollläden eingetragen sind die nächtens geschlossen werden sollen und vergleicht mit der Funktion ‘check4NC()’ die Rollläden die im lokalen Array ‘rollerIDsNC’ (NC steht hier für NotClose) stehen. Wird eine Übereinstimmung gefunden und eine Tür ist noch offen, geht der/die Rollläden nicht zu. Ist keine Tür offen, werden alle Rollläden geschlossen.
Das script prüft jetzt weiterhin jede Minute ob die Tür geschlossen wurde. Wenn ja ruft es die Funktion ‘closeAllNC()’ auf und schließt alle Rollläden aus dem lokalen Array ‘rollerIDsNC’. Zum Spielen und ein Gefühl damit zu bekommen kann man gut das obige kleine Script verwenden.
Klingt komplizierter als es ist. Der Vorteil, man muss nichts im Script umstellen, sondern kann alles mit den Variablen und den Bedingungen lösen. Dass vereinfacht die Pflege und das update. Jeder Benutzer kann seine Variablen die er mal eingestellt hat behalten. Ich werde, wenn keine Bugs auftreten auf Wunsch nur neue Funktionen hinzufügen, die muss man dann, oder auch nicht hinzufügen und muss nicht das ganze Script ersetzen.
Also mal die hier die Komplette Version: 1.2.8
–Changelog für Version 1.2.8
– DoorCheck function hinzugefügt
– Kleinere Codeoptimierungen
--[[
%% autostart
%% properties
%% globals
--]]
-- Shutter_control.lua
-- Section : EG
-- Release date : 07.07.2018
-- Version : 1.2.8
-- Copyleft : 12-2016 - 2018 {jeep}
-- benötigt wird eine Variable "rollershutter_runs" mit dem Wert 0
if (fibaro:countScenes()>1) then
fibaro:debug('Doppelte Szene - wird abgebrochen.')
fibaro:abort();
end
local function Debug( color, message )
fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end
math.randomseed( os.time() )
local sourceTrigger = fibaro:getSourceTrigger();
local luxSensorID = nil -- ID of brigthness sensor
local TempSensorID = 452 -- 427 -- ID of temperature sensor (ZWeather)
local doorSensorID = 202 -- nil ID of a door sensor
local lamp1ID = 166 -- lamp ID(s) for presence simulation
local randomMinValue = 7 -- kleinster Zufallswert
local randomMaxValue = 22 -- größter Zufallswert
local minuteslater = 10 -- Initialisierung Variable fuer spaeteres Oeffnen oder Schliessen
local notbeforeM = '07:30' -- nicht vorher Morgens
local notafterM = '08:10' -- nicht nach 08:10
local notbeforeE = '16:30' --
local notafterE = '21:00' --
local rollerIDsM = {150,164} -- IDs der Rolllaeden für morgens {n1, n2, nn}
local rollerIDsE = {150,} -- IDs der Rolllaeden für abends {n1, n2, nn}
local rollerIDsN = {150,164} -- (+)IDs der Rolllaeden für Nacht bevor man schlafen geht
local rollerIDsS = {150,418} -- IDs der Rolllaeden für Sonnenschutz Suedseite
local rollerIDsNC = {164,102} -- (+)IDs der Rolllaeden die nicht geschlossen werden
-- solange eine Tür offen ist.
local posQuarter = 25 -- viertel offen
local posHalf = 50 -- halb offen
local pos3Quarter = 70 -- 3/4 offen
local posOpen = 99 -- ganz offen
local posClose = 0 -- zu --
local rollerStat = nil -- gemeldeter Öffnungswert
local SUN_Protect = true -- Soll der Sonnenschutz aktiviert werden (Sommerbetrieb = true)
local sunProLuxOn = 35000 -- ab diesem Wert aktivieren
local sunProLuxOff = 15000 -- ab diesem Wert deaktivieren
local sunProTempOn = 26 -- Temperatur ab der der Sonnenschutz aktiviert wird
local sunProTempOff = 23 -- Temperatur ab der der Sonnenschutz deaktiviert wird
local sunProPos = 30 -- Rollläden nicht ganz schließen, Schlitze verhindern
-- Hitzestau und Schäden an den Lamellen.
local sunProtectActiv -- = false
local checkTime = "03:15" -- Uhrzeit zur Feststellug des Sonnenauf- und untergangs für den nächsten Tag
local checkSUN = false -- Die Variable stellt sich um 'checktime' auf true
if luxSensorID ~= nil then
brightness = tonumber(fibaro:getValue(luxSensorID, 'value')); --Wert des Luxsensors
elseif (fibaro:getGlobal('brightness') ~= nil) then
brightness = tonumber(fibaro:getGlobalValue("brightness")); -- LuxWert aus globaler Variable
end
temperatur = tonumber(string.format("%.2f",fibaro:getValue(TempSensorID, "value")));
local debug = true -- keine debug ausgaben
local debugonce = true -- | false
local version = "1.2.8"
-- Morning - negativer Wert - Morgens gehen die Rollläden früher auf
-- Evening - positver Wert - Abends gehen die Rollläden später zu
local function offSetM() -- offset morning
local month = tonumber(os.date('%m'))
local tabm = { [1] = "5", [2] = "10", [3] ="15", [4] = "25", [5] = "40", [6] = "45",
[7] = "45", [8] = "25", [9] ="20", [10] = "15", [11] = "10", [12] = 5 }
return tonumber(tabm[month])
end
local function offSetE() -- offset evening
local month = tonumber(os.date('%m'))
local tabm = { [1] = "5", [2] = "10", [3] ="15", [4] = "-5", [5] = "5", [6] = "10",
[7] = "10", [8] = "15", [9] ="20", [10] = "10", [11] = "5", [12] = "-5" }
return tonumber(tabm[month])
end
local function randomValue(randomMinValue, randomMaxValue)
local random = math.floor(math.random(randomMinValue, randomMaxValue));
local minutes = math.floor((random*60)/60);
return minutes;
end
local function calcTime( timeString, random )
local std, min = timeString:match("([^,]+):([^,]+)")
local newtimeString = os.date("%H:%M", -3600 + std*60*60 + (min*60 + random*60 ));
local laterClose = os.date("%H:%M", -3600 + std*60*60 + (min*60 + minuteslater*60 + random*60) );
return newtimeString, laterClose ;
end
local function addrandom(str, random)
local std, min = str:match("([^,]+):([^,]+)")
local newtimeString = os.date("%H:%M", -3600 + std*60*60 + (min*60 + random*60 ));
return newtimeString
end
-- ===================================================
-- Funktionen fuer den Sonnenschutz ein und auschalten
-- ===================================================
local function sunProtect(action)
if action == "ON" then
if sunProtectActiv == true then
print('Temperatur: '.. temperatur)
print('Helligkeit: '.. brightness)
Debug('yellow','Sonnenschutz wird aktiviert')
tdev = {}
if (rollerIDsS[1] ~= nil) then
-- Speichere Position der Rolllaeden
for r=1, #rollerIDsS do
if rollerIDsS[r] ~= nil then
rollerStat = fibaro:getValue(rollerIDsS[r], 'value')
table.insert(tdev, {rollerIDsS[r], rollerStat} )
fibaro:call(rollerIDsS[r], 'setValue', sunProPos)
end
end --for
end
end
else -- Sonnenschutz wird zurückgenommen, alter ZUstand wird wieder hergestellt
Debug('orange','Sonnenschutz wird deaktiviert')
print('Temperatur: '.. temperatur)
print('Helligkeit: '.. brightness)
if tdev ~= nil then
for r=1, #rollerIDsS do
fibaro:call(tdev[r][1],'setValue', tdev[r][2] )
end
end
end
end
local function check4sunProtect()
if (temperatur >= sunProTempOn and brightness >= sunProLuxOn ) and sunProtectActiv ~= true then
sunProtectActiv = true
sunProtect("ON")
elseif (temperatur <= sunProTempOff and brightness <= sunProLuxOff ) and sunProtectActiv == true then
print('Sonnenschutz aus.')
sunProtectActiv = false
sunProtect("OFF")
end
end
-- Function zum ueberpruefen welche IDs im Falle einer offenen Tuer
-- nicht geschlossen werden sollen.
local function check4NC(id) --(+) check the NotClose IDs if a door is open
for i=1,#rollerIDsNC do
if rollerIDsNC[i] == id then
return true
end
end -- for
return false
end --(+)
--
-- ========================================
-- Funktionen zum oeffnen und schliessen --
-- ========================================
--
local function earlymorning() -- 1.te Szene des Tages
Debug('orange', 'Funktion earlymorning gestartet. ') --(+)
fibaro:setGlobal("rollershutter_runs", "1");
fibaro:call(lamp1ID, "turnOn");
if (rollerIDsM[1] ~= nil) then
for r=1, #rollerIDsM do
if rollerIDsM[r] ~= nil then
fibaro:call(rollerIDsM[r],'setValue', posQuarter )
end
fibaro:sleep(math.random(4000,10000)) ; --4 bis 10 Sek. warten
end
end
Debug('orange','Rolllaeden ' ..posQuarter..'% geoeffnet - ' .. os.date("%c"));
fibaro:setGlobal("rollershutter_runs", "0");
end -- function earlymorning
local function goodmorningSun()
Debug('yellow', 'Funktion goodmorning gestartet.') --(+)
fibaro:setGlobal("rollershutter_runs", "1");
fibaro:call(lamp1ID, "turnOff"); -- Lampe wieder ausschalten
Debug('yellow','Sonnenaufgang - ' .. os.date("%c"));
Debug('yellow','Temperatur: ' .. temperatur .. '° um ' .. os.date('%H:%M'));
if (temperatur > 20) then -- es ist sommerlich warm
posOpen = 60 -- wir öffnen die Rolläden nicht ganz
Debug('yellow','Rolllaeden werden nur '..posOpen..'% geöffnet.')
end
if (rollerIDsM[1] ~= nil) then
for r=1, #rollerIDsM do
if rollerIDsM[r] ~= nil then
fibaro:call(rollerIDsM[r],'setValue', posOpen )
rollerStat=fibaro:getValue(rollerIDsM[r], 'value')
end
fibaro:sleep(math.random(3000,7000)); -- 3 bis 7 Sek. warten
end
end
Debug('yellow','Rolllaeden '..posOpen.. '% geöffnet' );
posopen = 99;
fibaro:setGlobal("rollershutter_runs", "0");
end -- function goodmorningSun
local function highNoon()
--Ersatzfunction falls man die Sonnenschutzfunktion nicht nutzt.
Debug('yellow', 'Funktion highNoon gestartet.') --(+)
fibaro:setGlobal("rollershutter_runs", "1");
Debug('yellow','Mittagshitze. Öffne Rollladen minimal' .. os.date("%c"));
-- es ist moerderisch heiss, wir
-- lassen nur einen kleinen Spalt offen
local posOpen = 15
if (rollerIDsM[1] ~= nil) then
fibaro:debug('Rollläden nur einen Spalt öffnen.')
for r=1, #rollerIDsE do
if rollerIDsE[r] ~= nil then
fibaro:call(rollerIDsE[r],'setValue', posOpen)
end
fibaro:sleep(math.random(4000,9000)); -- 4 bis 9 Sek. warten
end
end
Debug('darkorange','Rollladen minimal geöffnet');
fibaro:setGlobal("rollershutter_runs", "0");
end -- function highnoon
local function goodEvening() --Abenddaemmerung
Debug('darkorange', 'Funktion goodevening gestartet.')
fibaro:setGlobal("rollershutter_runs", "1");
fibaro:call(lamp1ID, "turnOn"); -- Licht an?
if (rollerIDsE[1] ~= nil) then
Debug('darkorange','Rollläden werden zur Haelfte geschlossen.' .. os.date("%c"))
for r=1, #rollerIDsE do
if rollerIDsE[r] ~= nil then
fibaro:call(rollerIDsE[r],'setValue', posHalf )
end
fibaro:sleep(math.random(5000,9000)) ;
end
end --
Debug('darkorange','Rolllaeden noch '..posHalf..'% offen');
fibaro:setGlobal("rollershutter_runs", "0");
end --end function goodEvening
local function goodNight()
Debug('green', 'Funktion goodNight gestartet.') --(+)
fibaro:setGlobal("rollershutter_runs", "1");
Debug('green','Es ist ganz dunkel... schließe Rollladen');
if (rollerIDsN[1] ~= nil) then
Debug('blue','Rolllaeden werden geschlossen.' .. os.date("%c"))
for r=1, #rollerIDsN do
if rollerIDsN[r] ~= nil then
fibaro:call(rollerIDsN[r],'setValue', posClose )
end
fibaro:sleep(math.random(5000,10000)) ;
end --for
end
Debug('blue','Rolllaeden '..posClose..'% offen.');
fibaro:setGlobal("rollershutter_runs", "0");
end -- function goodnight
--- Funktion goodnight mit Doorcheck
--- Es darf nur eine goodnight Funktion aktiviert werden!
local function goodNightWdoorCheck() --(+)
Debug('green', 'Funktion goodNNightWdoorCheck gestartet.') --(+)
doorvalue = tonumber(fibaro:getValue(doorSensorID, 'value'))
fibaro:setGlobal("rollershutter_runs", "1");
Debug('green','Es ist ganz dunkel... schließe Rollladen');
if (rollerIDsN[1] ~= nil) then
Debug('blue','Rolllaeden werden geschlossen.' .. os.date("%c"))
for r=1, #rollerIDsN do
if rollerIDsN[r] ~= nil then
if check4NC(rollerIDsN[r]) and doorvalue == 1 then
Debug('green', rollerIDsN[r] .. ' wird nicht geschlossen' )
else
Debug('blue', rollerIDsN[r] .. ' wird geschlossen' )
fibaro:call(rollerIDsN[r],'setValue', posClose )
end
end
fibaro:sleep(math.random(2000,4000)) ;
end -- for
end
Debug('blue','Rolllaeden '..posClose..'% offen.');
fibaro:setGlobal("rollershutter_runs", "0");
runNight = true
end --(+) function goodnightWdoorcheck
-- Die Funktion 'Close All Not Closed' ist im Prinzip eine Kopie der
-- goodNight(), mit dem Unterschied das die Rolllaeden aus dem Array
-- rollerIDsNC geschlossen werden.
local function closeAllNC()
Debug('blue', 'Funktion closeAllNC gestartet')
fibaro:setGlobal("rollershutter_runs", "1");
Debug('green','Es ist dunkel, alle Türen sind zu... schliesse alle Rollladen');
if (rollerIDsNC[1] ~= nil) then
Debug('blue','Rolllaeden werden geschlossen.' .. os.date("%c"))
for r=1, #rollerIDsNC do
if rollerIDsNC[r] ~= nil then
fibaro:call(rollerIDsNC[r],'setValue', posClose )
end
fibaro:sleep(math.random(2000,4000)) ;
end --for
end
Debug('blue','Rolllaeden '..posClose..'% offen.');
fibaro:setGlobal("rollershutter_runs", "0");
runCloseAll = true --bereits gelaufen
end
---
--- Ende der Funktionen fuer Oeffnen oder Schliessen ---
--- ================================================== ---
---
--######################################################
-- Initialize
--######################################################
local sunriseHour = fibaro:getValue(1,"sunriseHour");
local sunsetHour = fibaro:getValue(1,"sunsetHour");
local randminutes = randomValue(randomMinValue, randomMaxValue)
local newsunriseHour, laterOpen = calcTime(sunriseHour, tonumber(randminutes) + offSetM() )
local newsunsetHour, laterClose = calcTime(sunsetHour, tonumber(randminutes) + offSetE() )
runEarly,runMorning,runEvening,runNight,runcloseAll = false,false,false,false,false
function rollershutter() -- Hauptprogramm
--math.randomseed( os.time() )
temperatur = tonumber(string.format("%.2f",fibaro:getValue(TempSensorID, "value")));
-- (-) brightness = tonumber(fibaro:getValue(luxSensorID, 'value')); -- Wert des Luxsensors
if luxSensorID ~= nil then
brightness = tonumber(fibaro:getValue(luxSensorID, 'value')); -- Wert des Luxsensors
elseif (fibaro:getGlobal('brightness') ~= nil) then
brightness = tonumber(fibaro:getGlobalValue("brightness")); -- LuxWert aus globaler Variable
end
local currentDate = os.date("*t");
local actionTime = (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min));
local randminutes = randomValue(randomMinValue, randomMaxValue)
local minuteslater = randomValue(5,15) -- Spaeteres Oeffnen oder Schliessen
local holiday = tonumber(fibaro:getGlobalValue("Feiertag_heute"));
if (holiday == nil) then holiday = 0 end
local rollershutter_runs = tonumber(fibaro:getGlobalValue("rollershutter_runs"));
if (rollershutter_runs ~= 0 ) then
Debug('red',"Die Variable 'rollershutters_runs' hat für den Start einen falschen Wert, bitte korrigieren");
end
if ( checkSUN == false) then
sunriseHour = fibaro:getValue(1,"sunriseHour"); -- (+)
sunsetHour = fibaro:getValue(1,"sunsetHour"); -- (+)
newsunriseHour, laterOpen = calcTime(sunriseHour, tonumber(randminutes) + offSetM() )
newsunsetHour, laterClose = calcTime(sunsetHour, tonumber(randminutes) + offSetE() )
randomMorning = addrandom(notbeforeM,randomValue(4, 9))
temperatur = tonumber(string.format("%.2f",fibaro:getValue(TempSensorID, "value")));
checkSUN = true
runEarly,runMorning,runEvening,runNight,runcloseAll= false,false,false,false,false
Debug('lightblue','-- Zeiten für '.. (os.date("%d. %b %Y, "))..'Version: '..version.. ' --')
Debug('orange','RealSunrise: ' .. sunriseHour);
Debug('orange','New SunRise: ' .. newsunriseHour)
Debug('yellow','Later Open: ' .. laterOpen)
print('--')
Debug('darkorange','RealSunset: ' .. sunsetHour);
Debug('darkorange','New SunSet: ' .. newsunsetHour)
Debug('brown','LaterClose ' .. laterClose)
Debug('skyblue','Temperatur: ' .. temperatur .. '° um ' .. os.date('%H:%M'));
print('---------------------------------')
end
-- Fuer Simulation die 2 folgenden Variablen mit zeitnaher Uhrzeit fuettern
-- local newsunriseHour = "09:48"
-- local newsunsetHour = "22:39"
---------------------------------------------------------------
--- Ab hier koennen die verschiedenen Bedingungen zum Oeffnen
--- und Schliessen hinterlegt werden. Bitte beachten dass die Bedingungen
--- Funktionen nicht 2-fach aufrufen!
---------------------------------------------------------------
if (actionTime == newsunriseHour and rollershutter_runs == 0
and runEarly == false and (holiday == 0 or holiday == 1))
then --Morgenroete
earlymorning() --früh morgens, egal ob Werktag oder Feiertag
runEarly = true
--elseif (actionTime >= notbeforeM and holiday == 1
-- and rollershutter_runs == 0 and runEarly == false )
-- then --Morgenröte
-- earlymorning() -- es ist Feiertag, deshalb um notbeforM oeffnen
-- runEarly = true
elseif (actionTime == laterOpen and rollershutter_runs == 0
and runMorning == false )
then --es ist schon hell
goodmorningSun()
runMorning = true
--elseif ((actionTime == "12:00") and rollershutter_runs == 0
-- and temperatur >= 25)
-- then -- zusätzlicher Check um die Mittgaszeit falls man
-- keinen Sonnenschutz verwendet
-- highNoon()
elseif ((actionTime == sunsetHour) and rollershutter_runs == 0 )
then --Abenddämmeung
goodEvening()
runEvening = true
elseif (actionTime == laterClose and rollershutter_runs == 0 )
then -- Es wird/ist dunkel.
goodNight() -- oder goodNight() oder goodNightWdoorCheck()
runNight = true
elseif (actionTime > laterClose --(+)
and (tonumber(fibaro:getValue(doorSensorID, 'value')) == 0)
and runcloseAll == false and rollershutter_runs == 0 )
then -- Tuer zu, dann auch Rollladen zu.
-- Bitte diese Funktion mit Bedacht aktivieren. Nicht ohne Smartphone
-- ode FB hinausgehen.
closeAllNC()
runcloseAll = true --(+)
-----------------------------
-- Weitere Beispiele
-----------------------------
-- elseif (actionTime == randomMorning) --Oeffnen zu fester Uhrzeit + zufall
-- then
-- goodmorningSun()
-- elseif (actionTime == notafterE) -- Schliessen zu fester Uhrzeit
-- then
-- goodNight()
--
elseif (actionTime == checkTime) then
checkSUN = false
end -- Ende der elseif Bedingungen
if ((actionTime > newsunriseHour and actionTime < "20:00") -- Zeit in der auf Sonnenschutzbedingung gepüft wird
and SUN_Protect == true) then
check4sunProtect() -- Pruefen ob der Sonnenschutz aktiviert werden soll
end
setTimeout(rollershutter, 60*1000);
end -- function rollershutter
if (sourceTrigger["type"] == "autostart") then
rollershutter();
end