Licht bei Abwesenheit

Hallo zusammen
Nachdem mir Jeep so super beim Alarmpanel weiter geholfen hat, taucht in einer weiteren Szene ein ähnliches Problem auf. Die Szene schaltet bei Abwesenheit das Licht zufällig ein und aus, klappt sehr gut! Nun mein Anliegen, wenn ich nach Hause komme und der Global Status auf Anwesend schaltet, geht das Zufallslicht aus.
Was im Grunde genommen auch richtig ist, blöd ist nur wenn das Licht im Wohnzimmer brennt geht es aus und dann durch BM wieder an.
Super wäre wenn die Lampe 128 (Wohnzimmer) leuchtet und der Status auf Anwesenheit wechselt, dass diese nicht aus- und wieder eingeschaltet wird.

Habe mal eine “unschöne” Lösung gefunden, bin mir aber sicher dass der Profi dies besser lösen kann…
Bin für jede Hilfe dankbar…
Gruss fastsnake


--[[
%% properties
%% globals
AnwesenheitsCheck
--]]

local currentDate   = os.date("*t");
local nachtstart    = 1600
local nachtende     = 0200
local handy_willi   = 189
---------------------------------------------------
--------- Schleifenschutz -------------------------

if (fibaro:countScenes()>1) then
--fibaro:debug('Kill the second scene!');
fibaro:abort();
end

-----------------------------------
---------- Einstellungen ----------
varDebug 			 = true 									-- Debug logs true oder false

gVarPresentState	 = 'AnwesenheitsCheck' 						-- Name der globalen Variable für An- und Abwesenheit
gVarLightOfDay		 = 'Tageslicht'							-- Name der globalen Variable für Tageslicht
gVarLightOfDayValues = {'Dunkel'}	-- Zu welchen Tageszeiten sollen Lichtquellen geschaltet werden
randomTimeMin		 = {3,55}									-- Zufallsminuten von bis {1,2} min, max
secondsNext			 = 90									-- x Sekunden warten bis das nächste Gerät geschaltet wird
simDevices 			 = {10,14,128, {}, {},} -- Geräteauswahl (Mitte Virtuell)
version				 = '1.0'

--------------------------------
---------- Funktionen ----------

---------------------------------------------------
--------- Farbiges Debug --------------------------
       function debug(color, message) 
	   if (varDebug) then 
	   --fibaro:debug(message) 
	   fibaro:debug(string.format('<%s style="color:%s;">%s</%s>', "span", color, message, "span"));
end
end

       ---------------------------------------------------
       ------------- waitFunction ------------------------
       -- Warte x Sekunden
       ---------------------------------------------------
       function waitFunction(sec, text)
	   while sec > 0 do
	   if sec % 10 == 0 then debug('cyan','Noch '..sec..' Sekunden '..text) end
	    sec = sec -1
	   if fibaro:getGlobal(gVarPresentState) ~= 'Abwesend'    
       then
       break;
end
	   fibaro:sleep(1000)
end
end

       ---------------------------------------------------
       ------------- radomDevice -------------------------
       -- Zufallsgerät ermitteln
       ---------------------------------------------------
       function switchRandDevice()
	   --Zufallsgerät aus deviceIDs ermitteln
       math.randomseed(os.time ())
	   randomLight = math.random(1,#simDevices)
	   randomTime = math.random(randomTimeMin[1],randomTimeMin[2]) * 60
	   deviceID = simDevices[randomLight]
	
	   if type(deviceID) == 'table' then		
	   if #deviceID == 3 then
	   debug('green','Virtuelles Device: '..fibaro:getName(deviceID[1])..' in '..fibaro:getRoomNameByDeviceID(deviceID[1])..'. Drücke Button für '..randomTime..' Sekunden.')
	   fibaro:call(deviceID[1], "pressButton", deviceID[2])
	   waitFunction(randomTime, 'bis '..fibaro:getName(deviceID[1])..' ausgeschaltet wird')
	   fibaro:call(deviceID[1], "pressButton", deviceID[3])
		
elseif 
       #deviceID == 4 then
	   debug('green','Virtuelles Device: '..fibaro:getName(deviceID[1])..' in '..fibaro:getRoomNameByDeviceID(deviceID[1])..'. Setze Slider für '..randomTime..' Sekunden.')
	   fibaro:call(deviceID[1], "setSlider", deviceID[2], deviceID[3])
	   waitFunction(randomTime, 'bis '..fibaro:getName(deviceID[1])..' ausgeschaltet wird')
	   fibaro:call(deviceID[1], "setSlider", deviceID[2], deviceID[4])
end
else        
       function DT(DATETIME)
       local WD = {'Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'}
       local M = {'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'}
       local tableDT= (os.date('*t', tonumber(DATETIME))) 
       tableDT.month = M[tonumber(tableDT.month)]
       tableDT.wday =  WD[tonumber(tableDT.wday)]
       return ""..tableDT.wday ..', ' ..tableDT.day ..'. ' ..tableDT.month ..' ' ..tableDT.year ..' '..os.date " / %H:%M Uhr" 
       end 
       x= DT(os.date())
       fibaro:debug (x)
    
	   debug('yellow',''..fibaro:getName(deviceID)..' in '..fibaro:getRoomNameByDeviceID(deviceID)..'. Schalte es für '..randomTime..' Sekunden ein.')
	   fibaro:call(deviceID, "turnOn")
       debug("yellow","Licht eingeschaltet...");   

	   waitFunction(randomTime, 'bis '..fibaro:getName(deviceID)..' ausgeschaltet wird')

       function DT(DATETIME)
       local WD = {'Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'}
       local M = {'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'}
       local tableDT= (os.date('*t', tonumber(DATETIME))) 
       tableDT.month = M[tonumber(tableDT.month)]
       tableDT.wday =  WD[tonumber(tableDT.wday)]
       return ""..tableDT.wday ..', ' ..tableDT.day ..'. ' ..tableDT.month ..' ' ..tableDT.year ..' '..os.date " / %H:%M Uhr" 
       end 
       x= DT(os.date())
       fibaro:debug (x) 
    
       if fibaro:getGlobal(gVarPresentState) == 'Abwesend'    
       then 
       fibaro:call(deviceID, "turnOff") -- Alle Lichter aus
       debug("gray","Licht ausgeschaltet...");
else
       -- Licht Wohnzimmer wird NICHT ausgeschaltet!
       fibaro:call(10, "turnOff") 
       fibaro:call(14, "turnOff") 
       debug("lime","Ankunft zu Hause...");
       debug("yellow","Wohnzimmer Licht bleibt eingeschaltet...");
end
end
end  
       ---------------------------------------------------
       ------------- Funktion checkDaytime ---------------
       function checkDaytime(tab, val)
       for index, value in ipairs (tab) do
	   if value == val then
	   return true
end
end
       return false
end
       ---------------------------------------------------
       ------------- START -----------------------------

       sourceTrigger = fibaro:getSourceTrigger()
       PresentState  = fibaro:getGlobalValue(gVarPresentState)
       function DT(DATETIME)
       local WD = {'Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'}
       local M = {'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'}
       local tableDT= (os.date('*t', tonumber(DATETIME))) 
       tableDT.month = M[tonumber(tableDT.month)]
       tableDT.wday =  WD[tonumber(tableDT.wday)]
       return ""..tableDT.wday ..', ' ..tableDT.day ..'. ' ..tableDT.month ..' ' ..tableDT.year ..' '..os.date " / %H:%M Uhr" 
       end 
       x= DT(os.date())
       fibaro:debug (x)

       debug("green","--------------------START--------------------------------")
       debug('green','Anwesenheitssimulator')
       fibaro:call(handy_willi, "sendPush",os.date("(%d.%m.%Y) Zufallslicht Abwesenheit um %H:%M Uhr AKTIVIERT!"));  

       if sourceTrigger["type"] == "autostart" then
	   debug('red','Dies ist keine Autostart-Szene. Bitte Autostart entfernen')
    
elseif 
  
       sourceTrigger["type"] == "global" then
	   debug('orange','Getriggert durch '..sourceTrigger['name'])

       if PresentState == 'Abwesend' --or PresentState == 'Holiday'
       then
	   --Start PresentSim
	   debug('green','Starte Simulation...')
	   while fibaro:getGlobal(gVarPresentState) == 'Abwesend' do
	   gVarDaytime = checkDaytime(gVarLightOfDayValues, fibaro:getGlobalValue('Tageslicht'))
        
      
	   if gVarDaytime 
       and (tonumber(os.date("%H%M")) >= nachtstart or tonumber(os.date("%H%M")) <= nachtende) then
       waitFunction(secondsNext, 'bis zum nächsten Schaltvorgang')
	   switchRandDevice()
            
else
	   debug('cyan','Tageszeit = '..fibaro:getGlobalValue('Tageszeit')..'')
       debug('gray','Lichtsensor meldet '..fibaro:getGlobalValue('Tageslicht')..'')
       debug('tan','Nicht alle Bedingungen erfüllt, Szene gestoppt!')
	   debug('red','Abwesenheitsimulation wird NICHT aktiviert!')
       waitFunction(secondsNext, 'bis zum nächsten Check')
end			
end
       function DT(DATETIME)
       local WD = {'Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'}
       local M = {'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'}
       local tableDT= (os.date('*t', tonumber(DATETIME))) 
       tableDT.month = M[tonumber(tableDT.month)]
       tableDT.wday =  WD[tonumber(tableDT.wday)]
       return ""..tableDT.wday ..', ' ..tableDT.day ..'. ' ..tableDT.month ..' ' ..tableDT.year ..' '..os.date " / %H:%M Uhr" 
       end 
       x= DT(os.date())
       fibaro:debug (x)     
    
	   debug('red','Simulation beendet.')  
else    
       function DT(DATETIME)
       local WD = {'Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'}
       local M = {'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'}
       local tableDT= (os.date('*t', tonumber(DATETIME))) 
       tableDT.month = M[tonumber(tableDT.month)]
       tableDT.wday =  WD[tonumber(tableDT.wday)]
       return ""..tableDT.wday ..', ' ..tableDT.day ..'. ' ..tableDT.month ..' ' ..tableDT.year ..' '..os.date " / %H:%M Uhr" 
       end 
       x= DT(os.date())
       fibaro:debug (x)  
    
	   --Stop PresentSim
       debug('orange','Anwesenheit festgestellt!')
	   debug('red','Ende der Simulation...')
end
    
elseif  
       sourceTrigger["type"] == "other" then
	   debug('yellow','Szene manuell gestartet')
end


Meine “unschöne” Lösung, Zeile 114 -124.

@fastsnake,
auf jeden Fall hast Du an der richtigen Stelle was versucht.
Ich habe den Code ein wenig umformatiert und optimiert und die DT Function die mindestens 5 mal vorhanden war, gibts jetzt nur einmal.
Testen konnte ich es nicht da es sehr spezifisch ist und ich weder die Variablen noch die IDs hatte.
Ich denke das ich keine Fehler beim umformatieren eingebaut habe. Auf alle Fälle ist das jetzt
viel lesbarer und um ca. 50 Zeilen kürzer. :wink:
Was ich gemacht habe beginnt bei Zeile 92 bis 99.
Sollten Fehler auftreten, bitte melden.

--[[
%% properties
%% globals
AnwesenheitsCheck
--]]
 
local currentDate   = os.date("*t");
local nachtstart    = 1600
local nachtende     = 0200
local handy_willi   = 189
---------------------------------------------------
--------- Schleifenschutz -------------------------
 
if (fibaro:countScenes()>1) then
   --fibaro:debug('Kill the second scene!');
   fibaro:abort();
end
 
-----------------------------------
---------- Einstellungen ----------
local varDebug             = true -- Debug logs true oder false
local gVarPresentState     = 'AnwesenheitsCheck' -- Name der globalen Variable für An- und Abwesenheit
local gVarLightOfDay       = 'Tageslicht'  -- Name der globalen Variable für Tageslicht
local gVarLightOfDayValues = {'Dunkel'}    -- Zu welchen Tageszeiten sollen Lichtquellen geschaltet werden
local randomTimeMin        = {3,55}	       -- Zufallsminuten von bis {1,2} min, max
local secondsNext          = 90            -- x Sekunden warten bis das nächste Gerät geschaltet wird
local simDevices           = {10,14,128, {}, {},} -- Geräteauswahl (Mitte Virtuell)
local version              = '1.1'
 
---------- Funktionen ----------
---------------------------------------------------
--------- Farbiges Debug --------------------------
 local function debug(color, message) 
  if (varDebug) then 
	  --fibaro:debug(message) 
	  fibaro:debug(string.format('<%s style="color:%s;">%s</%s>', "span", color, message, "span")); 
  end
end
 
 local function DT(DATETIME)
   local WD = {'Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'}
   local M = {'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'}
   local tableDT= (os.date('*t', tonumber(DATETIME))) 
   tableDT.month = M[tonumber(tableDT.month)]
   tableDT.wday =  WD[tonumber(tableDT.wday)]
   return ""..tableDT.wday ..', ' ..tableDT.day ..'. ' ..tableDT.month ..' ' ..tableDT.year ..' '..os.date " / %H:%M Uhr" 
 end  
       ---------------------------------------------------
       ------- waitFunction - Warte x Sekunden -----------
       ---------------------------------------------------
local function waitFunction(sec, text)
  while sec > 0 do
	if sec % 10 == 0 then debug('cyan','Noch '..sec..' Sekunden '..text) end
	   sec = sec -1
	  if fibaro:getGlobal(gVarPresentState) ~= 'Abwesend'  then
         break;
      end
	  fibaro:sleep(1000)
    end
end
       --------------------------------------------------- 
       ------------- radomDevice -------------------------
       -- Zufallsgerät ermitteln
       ---------------------------------------------------
 local function switchRandDevice() --Zufallsgerät aus deviceIDs ermitteln
   math.randomseed(os.time ())
   randomLight = math.random(1,#simDevices)
   randomTime = math.random(randomTimeMin[1],randomTimeMin[2]) * 60
   deviceID = simDevices[randomLight]
   if type(deviceID) == 'table' then		
      if #deviceID == 3 then
         debug('green','Virtuelles Device: '..fibaro:getName(deviceID[1])..' in '..fibaro:getRoomNameByDeviceID(deviceID[1])..'. Drücke Button für '..randomTime..' Sekunden.')
         fibaro:call(deviceID[1], "pressButton", deviceID[2])
         waitFunction(randomTime, 'bis '..fibaro:getName(deviceID[1])..' ausgeschaltet wird')
         fibaro:call(deviceID[1], "pressButton", deviceID[3])
      elseif 
         #deviceID == 4 then
         debug('green','Virtuelles Device: '..fibaro:getName(deviceID[1])..' in '..fibaro:getRoomNameByDeviceID(deviceID[1])..'. Setze Slider für '..randomTime..' Sekunden.')
         fibaro:call(deviceID[1], "setSlider", deviceID[2], deviceID[3])
         waitFunction(randomTime, 'bis '..fibaro:getName(deviceID[1])..' ausgeschaltet wird')
         fibaro:call(deviceID[1], "setSlider", deviceID[2], deviceID[4])
      end
   else        
      x= DT(os.date())
      fibaro:debug (x)
      debug('yellow',''..fibaro:getName(deviceID)..' in '..fibaro:getRoomNameByDeviceID(deviceID)..'. Schalte es für '..randomTime..' Sekunden ein.')
      fibaro:call(deviceID, "turnOn")
      debug("yellow","Licht eingeschaltet...");   
      waitFunction(randomTime, 'bis '..fibaro:getName(deviceID)..' ausgeschaltet wird')
      x= DT(os.date())
      fibaro:debug (x) 
      --jeep
      if PresentState == 'Anwesend' and tonumber(fibaro:getValue(128,'value')) == 1 then
         debug('green','Wohnzimmer nicht auschalten')
      else 
        fibaro:call(deviceID, "turnOff") -- Alle Lichter aus
        debug("gray","Licht ausgeschaltet...");  
      end
  --jeep
   end
end
       ---------------------------------------------------
       ------------- Funktion checkDaytime ---------------
local function checkDaytime(tab, val)
  for index, value in ipairs (tab) do
     if value == val then
        return true
     end
  end
  return false
end
       ---------------------------------------------------
       ------------- START -----------------------------
sourceTrigger = fibaro:getSourceTrigger()
PresentState  = fibaro:getGlobalValue(gVarPresentState)
x= DT(os.date())
fibaro:debug (x)
 
debug("green","--------------------START--------------------------------")
debug('green','Anwesenheitssimulator')
fibaro:call(handy_willi, "sendPush",os.date("(%d.%m.%Y) Zufallslicht Abwesenheit um %H:%M Uhr AKTIVIERT!"));  
 
if sourceTrigger["type"] == "autostart" then
   debug('red','Dies ist keine Autostart-Szene. Bitte Autostart entfernen')
elseif 
   sourceTrigger["type"] == "global" then
   debug('orange','Getriggert durch '..sourceTrigger['name'])
   if PresentState == 'Abwesend' then --or PresentState == 'Holiday' then
      --Start PresentSim
      debug('green','Starte Simulation...')
      while fibaro:getGlobal(gVarPresentState) == 'Abwesend' do
         gVarDaytime = checkDaytime(gVarLightOfDayValues, fibaro:getGlobalValue('Tageslicht'))
         if gVarDaytime 
            and (tonumber(os.date("%H%M")) >= nachtstart or tonumber(os.date("%H%M")) <= nachtende) then
            waitFunction(secondsNext, 'bis zum nächsten Schaltvorgang')
            switchRandDevice()
         else
            debug('cyan','Tageszeit = '..fibaro:getGlobalValue('Tageszeit')..'')
            debug('gray','Lichtsensor meldet '..fibaro:getGlobalValue('Tageslicht')..'')
            debug('tan','Nicht alle Bedingungen erfüllt, Szene gestoppt!')
            debug('red','Abwesenheitsimulation wird NICHT aktiviert!')
            waitFunction(secondsNext, 'bis zum nächsten Check')
         end
      end
      x= DT(os.date())
      fibaro:debug (x)     
      debug('red','Simulation beendet.')  
   else 
      x= DT(os.date())
      fibaro:debug (x)  
    
      --Stop PresentSim
      debug('orange','Anwesenheit festgestellt!')
      debug('red','Ende der Simulation...')
   end
elseif  
   sourceTrigger["type"] == "other" then
   debug('yellow','Szene manuell gestartet')
end

Hi Jeep
Vielen Dank für Deine rasche Antwort und für das optimieren der Szene. Nach Anfangs Schwierigkeiten((128) schaltete immer noch aus) habe ich die Zeile 93
abgeändert. Jetzt läuft das Script dank Deiner Hilfe tadellos.
if fibaro:getGlobal(gVarPresentState) ~= 'Abwesend' and tonumber(fibaro:getValue(128,'value')) == 1 then
Danke für Deinen unermüdlichen Einsatz!!
Gruss fastsnake

Ja das passt so. Kann sein das das Script die Variable “PresentState” zu dem Zeitpunkt noch nicht mitbekommt,
deshalb ist es OK wie Du es gemacht hast.

Hallo Leute,Ïch benötige Eure Hilfe.
Ich möchte eine Szene erstellen und ich bin absilut kein LUA Profi.
Würde es gerne über eine BlockSzene erledigen.
Folgendes möchte ich tun.
Wenn der Bewegungsmelder länger als 4 Stunden keine Bewegung erkannt hat, schaltet das Licht im Flur und Wohnzimmer ein (1h nach Sonnenuntergang). Danach schalten die Lichter wieder aus vo gegen 23:55h.
Das heisst wenn ich am Weekend verreise oder in den Urlaub fahre, geht am Abend das Licht automatisch an.
Wenn ich zu Hause bin, ist die Szene nicht aktiv und ich schalte das Licht manuell an, wenn ich Licht will.
Ist das überhaupt möglich und sinnvoll.
Wenn das mit den Bewegungsmelder nicht möglich ist, kann ich auch einen Buzzer/Schalter einrichten, wo ich auf Abwesend schalten kann (manuell) und dann läuft die Szene bis ich sie wieder abschalte…
Danke für Euer Feedback und Hilfe