Und noch ein Rollladen Script

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