Hallo zusammen,
hier noch mal die komplette Version in der die vorausgegangenen Fixes und Erweiterungen eingepflegt wurden.
Es besteht also nicht unbedingt der Zwang zum Update. Das PDF werde ich gelegentlich aktualisieren.
--[[
%% autostart
--]]
-- Shutter_control.lua
-- Section : EG
-- Version : 1.3.7
-- Release date : 20.06.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:00' -- nicht vorher Morgens
local notafterM = '08:10' -- nicht nach 08:10
local notbeforeE = '17: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,418} -- IDs der Rolllaeden für Sonnenschutz Suedseite
local rollerIDsNC = {418} -- 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 = 30000 -- 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.7"
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
-- Pruefung ob Rollladen in der Zwischenzeit bewegt wurde
if ( tonumber(fibaro:getValue(rollerIDsS[r], 'value')) == sunProPos ) then
fibaro:call(tdev[r][1],'setValue', tdev[r][2] )
end
end --for
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 (holiday == 1) then einORkein = 'ein' else einORkein = 'kein' 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('lightblue','Heute ist '..einORkein..' Feiertag oder Wochenende.')
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.
goodNightWdoorCheck() -- 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