Hi Dirk,
bitte schön, da ist es. Bitte das angehängte PDF beachten, da gibts noch Unterschiede zu den Vorgängerversionen.
--[[
%% autostart
--]]
-- Shutter_control.lua
-- Section : EG
-- Version : 1.3.5
-- Release date : 22.04.2019
-- Copyleft : 12-2016 - 2019 {jeep}
-- Documentation: RollerShutterControl1.3.5.pdf
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 = 462 -- 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 = 5 -- kleinster Zufallswert
local randomMaxValue = 15 -- größter Zufallswert
local minuteslater = 8 -- Initialisierung Variable fuer spaeteres Oeffnen oder Schliessen
local notbeforeM = '07:40' -- 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 Abenddaemmerung {n1, n2, nn}
local rollerIDsN = {150,} -- IDs der Rolllaeden für Nachtanbruch bevor man schlafen geht
local rollerIDsS = {150,170,172} -- IDs der Rolllaeden für Sonnenschutz Suedseite
local rollerIDsNC = {} -- 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 = false -- Soll der Sonnenschutz aktiviert werden (Sommerbetrieb = true)
local sunProLuxOn = 35000 -- ab diesem Wert aktivieren
local sunProLuxOff = 15000 -- ab diesem Wert deaktivieren
local sunProTempOn = 25 -- Temperatur ab der der Sonnenschutz aktiviert wird
local sunProTempOff = 24 -- Temperatur ab der der Sonnenschutz deaktiviert wird
local sunProChkOff = "20:00" -- (+) Ab dieser Zeit wird nicht mehr auf Sonnenschutz geprüft
local sunProTimeOff = "19:30" -- (+) Zeit um der der Sonnenschutz auf alle Fälle beendet Wird.
local sunProPos = 15 -- Rollläden nicht ganz schließen, Schlitze verhindern
-- Hitzestau und Schäden an den Lamellen.
local sunProtectActiv -- = false
local debug = true -- debug ausgaben ja | nein
---------------End user defined variables ---------------------
local checkTime = "03:15" -- Uhrzeit zur Feststellug des Sonnenauf- und untergangs für den nächsten Tag
local checkDay = false -- Die Variable stellt sich um 'checktime' auf true
local version = "1.3.5"
temperatur = tonumber(string.format("%.2f",fibaro:getValue(TempSensorID, "value")));
if (sunProChkOff <= sunProTimeOff) then
SUN_Protect = false
Debug('red', 'SunProChkoff muss groesser als sunProTimeOff sein.')
Debug('orange', 'Sonnenschutz wurde deaktiviert!')
end
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
-- Korrektur des Sonnenauf und -untergangs über die Monate
-- 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] = "-20", [2] = "-5", [3] ="5", [4] = "15", [5] = "20", [6] = "25",
[7] = "45", [8] = "30", [9] ="8", [10] = "5", [11] = "-5", [12] = "-20" }
return tonumber(tabm[month])
end
local function offSetE() -- offset evening
local month = tonumber(os.date('%m'))
local tabm = { [1] = "5", [2] = "12", [3] ="15", [4] = "10", [5] = "15", [6] = "10",
[7] = "10", [8] = "15", [9] ="20", [10] = "15", [11] = "5", [12] = "2" }
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
-- Neuen Sonnenaufgang berechnen
local function calcTime( timeString, random )
-- Zeit nach Minuten umwandeln + Zufallszeit addieren
local HtimeString = string.sub(timeString,1,2)
local MtimeString = string.sub(timeString,4,5)
local timeStringMIN = tonumber(HtimeString * 60) + tonumber(MtimeString);
local timeStringMIN = timeStringMIN + random
local laterCloseMIN = timeStringMIN + (minuteslater + random) --
-- Neue SunRise Zeit wieder nach String hh:mm umwandeln
local timeStringHnew = math.floor(timeStringMIN / 60)
local timeStringMnew = timeStringMIN - (timeStringHnew * 60)
local laterCloseH = math.floor(laterCloseMIN /60)
local latercloseM = laterCloseMIN - (laterCloseH *60)
local newtimeString = string.format("%02d", timeStringHnew) .. ":" .. string.format("%02d", timeStringMnew)
local laterClose = string.format("%02d", laterCloseH) .. ":" .. string.format("%02d", latercloseM)
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
if debug then print('Temperatur: '.. temperatur) end
if debug then print('Helligkeit: '.. brightness) end
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')
if debug then print('Temperatur: '.. temperatur) end
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
or (os.date("%H:%M") >= sunProTimeOff and sunProtectActiv == true ) then
print('Sonnenschutz aus.')
sunProtectActiv = false
sunProtect("OFF")
end
end
-- Funktion 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:call(lamp1ID, "turnOn");
if (rollerIDsM[1] ~= nil) then
for r=1, #rollerIDsM do
if rollerIDsM[r] ~= nil then
rollerStat = tonumber(fibaro:getValue(rollerIDsM[r], 'value'))
if debug then print('Rollerstat :'.. rollerStat) end
if (rollerStat == 0) then
if debug then print(rollerIDsM[r]..' ist noch geschlossen') end
fibaro:call(rollerIDsM[r],'setValue', posHalf )
end
end
fibaro:sleep(math.random(4000,10000)) ; --4 bis 10 Sek. warten
end --for
end
Debug('orange','Rolllaeden ' ..posQuarter..'% geoeffnet - ' .. os.date("%c"));
end -- function earlymorning
local function goodmorningSun()
Debug('yellow', 'Funktion goodmorning gestartet.')
--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;
end -- function goodmorningSun
local function highNoon()
--Ersatzfunction falls man die Sonnenschutzfunktion nicht nutzt.
--Ausschlafen wird wieder deaktiviert
Debug('yellow', 'Funktion highNoon gestartet.')
Debug('yellow','Mittagshitze. Schließe Rollladen bis bis auf n% ' .. 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');
Debug('darkorange','Lange ausschlafen ist abgeschaltet.');
end -- function highnoon
local function goodEvening() --Abenddaemmerung/twilight
Debug('darkorange', 'Funktion goodevening gestartet.')
-- 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');
end --end function goodEvening
local function goodNight()
Debug('green', 'Funktion goodNight gestartet.')
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.');
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'))
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.');
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')
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.');
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() )
local sleepin = tonumber(fibaro:getGlobalValue("Ausschlafen")) or 0;
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")));
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(randomMinValue, randomMaxValue) -- Spaeteres Oeffnen oder Schliessen
--local minuteslater = randomValue(4,8) -- Spaeteres Oeffnen oder Schliessen
local holiday = tonumber(fibaro:getGlobalValue("Feiertag_heute"));
if (holiday == nil) then holiday = 0 end
if ( checkDay == 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() )
sleepin = tonumber(fibaro:getGlobalValue("Ausschlafen")) or 0; -- wird über ein VD aktiviert
randomMorning = addrandom(notbeforeM,randomValue(4, 9)) -- morgens nicht vorher + Zufall
temperatur = tonumber(string.format("%.2f",fibaro:getValue(TempSensorID, "value")));
checkDay = 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'));
Debug('skyblue','Helligkeit: ' ..brightness.. 'Lux')
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 >= notbeforeM and actionTime <= notafterM) and runEarly == false
or (actionTime == newsunriseHour) and runEarly == false )
then --Morgenroete
earlymorning() --früh morgens, egal ob Werktag oder Feiertag
runEarly = true
--elseif (actionTime >= notbeforeM and holiday == 1
-- and runEarly == false )
-- then --Morgenröte
-- earlymorning() -- es ist Feiertag, deshalb um notbeforM oeffnen
-- runEarly = true
elseif (actionTime == laterOpen and sleepin == 0
and runMorning == false )
then --es ist schon hell
goodmorningSun()
runMorning = true
-- elseif (actionTime == "12:00")
-- and temperatur >= 25) -- zusaetzlicher Check um die Mittgaszeit falls man
-- then -- keinen Sonnenschutz verwendet
-- highNoon()
elseif ((actionTime == newsunsetHour) )
then --Abenddaemmeung
goodEvening()
runEvening = true
elseif (actionTime == laterClose )
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 )
then -- Tuer zu, dann auch Rollladen zu.
-- Bitte diese Funktion mit Bedacht aktivieren. Nicht ohne Smartphone
-- oder FB hinausgehen.
closeAllNC()
runcloseAll = true
elseif (actionTime == checkTime) then
checkDay = false
end -- Ende der elseif Bedingungen
if (actionTime > newsunriseHour and actionTime < sunProChkOff -- 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