@lodi, geht klar. Bitte probieren…
Vielleicht sollte man noch explizit zu dem Skript sagen, dass man die Anzahl der Instanzen unbedingt auf 1 setzen sollte. Sonst kann es durchaus passieren, dass man durch Probieren usw. mehrere gleichzeitig am Laufen hat, was bestimmt nicht sinnvoll ist.
Hier also die Version, die Jahreszeiten und Sonnenstand zur Laufzeit berücksichtigt:
--[[
%% autostart
%% properties
%% globals
--]]
-- ------------- Skript setDayTime --------------------------------------------
-- Hier Debugmode auf true setzen und es wird ein Simulationstag (24 Std) durchlaufen,
-- der dir die moeglichen Ergebnisse zeigt jedoch keine Globale Variable ändert
-- und keinen Timeout setzt
local debugMode = false
-- Name der Globalen Variable im Home Center
local timeOfDayGlobalName = "TimeOfDay"
-- Mapping der TimeOfDay Eintraege in beliebiger Sprache
-- der globalen Variable TimeOfDay entsprechend
local timeOfDayLabelMap = {Morning="Morning", Day="Day", Evening="Evening", Night="Night"}
-- Name der Globalen Variable im Home Center
local SeasonGlobalName = "Jahreszeit"
-- Mapping der Jahreszeit Eintraege in beliebiger Sprache
-- der globalen Variable Jahreszeit entsprechend
local SeasonLabelMap = {Fruehling="Fruehling", Sommer="Sommer", Herbst="Herbst", Winter="Winter"}
local sourceTrigger = fibaro:getSourceTrigger()
local dayTimeList
--Color debugging
function ExtraDebug( color, message )
--if (debugMode) then
fibaro:debug(string.format('<%s style="color:%s;">%s</%s>', "span", color, message, "span"));
--end
end
-- Berechnet Uhrzeit in Sekunden (Differenz) ab 0:00 Uhr
function getTimeSecsDiff(s)
local hours, minutes = string.match(s, "(%d+):(%d+)")
-- Sekunden = Stunden * 60 (mins) * 60 (secs) + Minuten * 60 (secs)
local calcSecs = (hours-1) * 60 * 60 + minutes * 60
return calcSecs
end
--Start
function InitTimeOfDay()
-- Strings Sonnenauf/-untergang im Format Stunde:Minute von fibaro geliefert
local sunrise = fibaro:getValue(1, "sunriseHour") -- Sonnenaufgang
local sunset = fibaro:getValue(1, "sunsetHour") -- Sonnenuntergang
-- Auslesen der aktuellen Jahreszeit (Globale Variable)
local season = fibaro:getGlobal(SeasonGlobalName)
fibaro:debug(string.format("Globale Variable '%s' aktueller Wert: '%s'", "Jahreszeit", season))
-- Angaben der Bereichsgrenzen:
--
-- Hier koennen die Grenzen angeben werden, ab wann ein neuer Tagesbereich anfaengt.
-- Der Erste Wert ist die Uhrzeit im Format Stunde:Minute, der zweite Wert
-- entspricht einem Offset (Verzoegerung) in Minuten bezogen auf den ersten Wert.
-- Als ersten Wert koennen auch die Variablen sunset/sunrise genommen werden.
--
-- Beispiele:
--
-- globalMorning = { sunrise, 30 } => Morgen beginnt 30 Minuten nach Sonnenaufgang
-- globalMorning = { sunrise, -30 } => Morgen beginnt 30 Minuten vor Sonnenaufgang
-- globalEvening = { "18:00", 0 } => Abend beginnt um genau 18:00 Uhr
-- globalEvening = { sunset, 80 } => Abend beginnt 80 Minuten nach Sonnenaufgang
-- Allgemeine Zeiten; Gelten immer falls keine Zeiten angegeben wurden fuer die aktuelle Jahreszeit (Uebersteuerung)
local globalMorning = { sunrise, 0 }
local globalDay = { "10:00", 0 }
local globalEvening = { sunset, 0 }
local globalNight = { "22:00", 0 }
-- Hier koennen beliebige Zeiten eingegebn werden fuer die aktuelle Jahreszeit.
-- Der nil Wert bedeutet hier, das die globale Einstellung uebernommen werden soll
-- Die Werte muessen der Reihenfolge Morgen Tag Abend und Nacht entsprechen.
local seasonTimeTable = { Fruehling = { { sunrise, 0 },
{ "10:00", 0 },
{ sunset, 0 },
{ "23:00", 0 } },
Sommer = { { sunrise, 0 },
{ "09:00", 0 },
{ sunset, 0 },
{ "23:00", 0 } },
Herbst = { { sunrise, 0 },
{ "10:00", 0 },
{ sunset, 0 },
{ "23:00", 0 } },
Winter = { { sunrise, 0 },
{ "11:00", 0 },
{ sunset, 0 },
{ "23:00", 0 } }
}
--
-- =========> Ab hier sind keine Einstellungen noetig
--
-- hier werden die Werte der Jahreszeit entsprechend (falls angegeben) uebernommen
-- ansonsten gelten die globalen Angaben
morning = globalMorning
if (seasonTimeTable[season][1]) then
morning = seasonTimeTable[season][1]
end
day = globalDay
if (seasonTimeTable[season][2]) then
day = seasonTimeTable[season][2]
end
evening = globalEvening
if (seasonTimeTable[season][3]) then
evening = seasonTimeTable[season][3]
end
night = globalNight
if (seasonTimeTable[season][4]) then
night = seasonTimeTable[season][4]
end
-- Umrechnung der Bereichsgrenze in Sekunden ab 0:00 Uhr (Differenz)
morning = getTimeSecsDiff(morning[1]) + morning[2] * 60
day = getTimeSecsDiff(day[1]) + day[2] * 60
evening = getTimeSecsDiff(evening[1]) + evening[2] * 60
night = getTimeSecsDiff(night[1]) + night[2] * 60
if (debugMode) then
fibaro:debug("---------------- Voreinstellungen -----------------")
fibaro:debug(string.format("Es ist die Jahreszeit %s",season))
fibaro:debug(string.format("%s Uhr Sonnenaufgang",sunrise))
fibaro:debug(string.format("%s Uhr Sonnenuntergang",sunset))
fibaro:debug(string.format("%s Uhr Morgen",os.date("%H:%M", morning)))
fibaro:debug(string.format("%s Uhr Tag",os.date("%H:%M", day)))
fibaro:debug(string.format("%s Uhr Abend",os.date("%H:%M", evening)))
fibaro:debug(string.format("%s Uhr Nacht",os.date("%H:%M", night)))
end
-- Table der Bereichsgrenzen
dayTimeList = {
{label = timeOfDayLabelMap.Morning, secs = morning},
{label = timeOfDayLabelMap.Day, secs = day},
{label = timeOfDayLabelMap.Evening, secs = evening},
{label = timeOfDayLabelMap.Night, secs = night},
}
-- Sortierung der Bereichsgrenzen nach Zeit (secs)
local sort_func = function( a,b ) return a.secs < b.secs end
table.sort(dayTimeList, sort_func)
end
-- Hauptfunktion zum setzen der Globalen Variable TimeOfDay
function setTimeOfDay()
InitTimeOfDay() --Initialisierung in die Hauptfunktion mit rein! Sonst wird sunset, sunrise, season nicht aktualisiert.
local aktTime = 0;
local doLoop = true;
local loopHour = 0;
local timeout = 0
local setDayTime = nil
if (debugMode) then
fibaro:debug("---------------- Beginne Auswertung --------------")
end
repeat
local timeOfDayCur = fibaro:getGlobalValue(timeOfDayGlobalName)
fibaro:debug(string.format("Globale Variable '%s' aktueller Wert: '%s'", timeOfDayGlobalName, timeOfDayCur))
if (debugMode) then
-- Testzeit zur Simulation
aktTime = getTimeSecsDiff(string.format("%02d:00",loopHour))
if (loopHour == 24)then
doLoop = false
end
loopHour = loopHour + 1
else
-- aktuelle Zeit in Sekunden (Differenz)
aktTime = getTimeSecsDiff(os.date("%H:%M"))
doLoop = false
end
for i, record in ipairs( dayTimeList ) do
if (aktTime < record.secs) then
if (i == 1) then
-- falls match beim ersten Element nehme
-- den letzte Zeitbereich in der Liste
setDayTime = dayTimeList[#dayTimeList].label
else
setDayTime = dayTimeList[i-1].label
end
timeout = record.secs - aktTime;
break;
else
setDayTime = nil
end
lastDayTime = record.label
if (i == 1) then
firstSec = record.secs
end
end
-- Falls Zeitgrenze ueber Datumswechsel muss der Timeout extra berechnet werden
if ( setDayTime == nil ) then
setDayTime = lastDayTime
timeout = 86400 - aktTime + firstSec
end
fibaro:debug(string.format("Es ist '%s' Uhr => setze Globale Variable '%s' auf '%s'", os.date("%H:%M", aktTime), timeOfDayGlobalName, setDayTime))
-- setze globale Variable
if (not debugMode) then
fibaro:debug(string.format("Globale Variable '%s' auf den Wert '%s' gesetzt", timeOfDayGlobalName, setDayTime))
fibaro:setGlobal(timeOfDayGlobalName, setDayTime)
end;
-- Die Szene pausiert bis zum Wechsel in den naechsten Tagesbereich
fibaro:debug(string.format("Timeout für %.2f Minuten", timeout/60))
until not doLoop
if (not debugMode) then
-- Setze Timeout
--fibaro:debug( string.format("vor Timeeout:"));
setTimeout(setTimeOfDay, timeout*1000)
end;
end
--
-- ================ Main ( Aufruf Verarbeitung ) ==============================
--
setTimeOfDay()