Page 1 of 4

Arbetsdag idag / imorgon - Hur man räknar ut Påsken varje år

Posted: 30 Mar 2014, 19:57
by Bamsefar
Ursprungligen var denna tråd mera om hur man räknar ut Påsk varje år. För att klara av att beräkna alla helgdagar som rör på sig (de har alla beroende till just Påskafton). Nu har jag ändrat i koden, och lagt till möjligheten att också definiera fasta datum som t.ex. ledigheter med mera på ett enklare sätt.

Ni kan väl testa och se om jag missat något, koden är numera i full produktion hemma hos oss, så BETA status är passerat ;-)

Koden placeras lämpligen i en scen...

Code: Select all

    --[[
    %% properties

    %% globals
    --]]




function Vacation_Period(datumForCheck)

	-- Ange vilka datumperioder som skall anses som lediga datum
	-- OBS ange i formatet "startdatum;slutdatum" !!!!
	local LedigaPerioder = { "2014-12-19;2015-01-12", "2015-12-02;2015-12-21" }

	local datum

  	dateForCheck = os.time({year = datumForCheck.year, month = datumForCheck.month, day = datumForCheck.day})
  
	for z,datumpar in pairs(LedigaPerioder) do
		FromDatum = os.time({year = tonumber(string.sub(datumpar,1,4)), month = tonumber(string.sub(datumpar,6,7)), day = tonumber(string.sub(datumpar,9,10)), hour=0, min=0, sec=0})
		ToDatum = os.time({year = tonumber(string.sub(datumpar,12,15)), month = tonumber(string.sub(datumpar,17,18)), day = tonumber(string.sub(datumpar,20,21)), hour=23, min=59, sec=59})
    	if ( FromDatum <= dateForCheck and dateForCheck <= ToDatum) then
			return true
		end
	end
	return false
end  


      function Vacation_Days(dateForCheck)

      -- Ange vilka datum som skall anses som lediga datum
      local LedigaDatum = { "2014-05-02" , "2014-05-30" }

      local datum

       for z,datum in pairs(LedigaDatum) do
          TestDatum = os.date("*t", os.time({year = tonumber(string.sub(datum,1,4)), month = tonumber(string.sub(datum,6,7)), day = tonumber(string.sub(datum,9))}))
           if ( TestDatum.year == dateForCheck.year and TestDatum.month == dateForCheck.month and TestDatum.day == dateForCheck.day ) then
             return true
          end
       end
       return false
    end 

    function Holidays_CalculateEaster(year)
      golden = (year % 19) + 1
      c = math.floor(year/400) + math.floor(8*(math.floor(year/100)+11)/25) - math.floor(year/100)
      s = (11 * golden + c) % 30
      if (s < 0) then
        s = s + 30
      end
      pfm = os.time{year=year, month=4, day=19} - s * 24 * 60 * 60
      if (pfm == os.time{year=year, month=4, day=19}) then
        pfm = pfm - 24 * 60 * 60
      elseif (pfm == os.time{year=year, month=4, day=18} and golden > 11) then
        pfm = pfm - 24 * 60 * 60
      end
      sunday = pfm + (7 - tonumber(os.date("%w", pfm))) * 24 * 60 * 60
      friday = sunday - 2 * 24 * 60 * 60
     
      return {year, tonumber(os.date("%m", friday)), tonumber(os.date("%d", friday))} 
    end

    function WorkDay(dateToCheck)

            local easterDay
            local returnValue
     
          returnValue = true

           -- Indatum är en lördag eller Söndag
            if ( dateToCheck.wday == 1 or dateToCheck.wday == 7 ) then
               returnValue = false
            -- Indatum är nationaldag       
          elseif ( dateToCheck.month == 6 and dateToCheck.day == 6 ) then
               returnValue = false
            -- Indatum är Nyårsdag eller trettondag
            elseif ( dateToCheck.month == 1 and (dateToCheck.day == 1 or dateToCheck.day == 6 ) ) then
               returnValue = false
            -- Indatum är 1:a maj
            elseif ( dateToCheck.month == 5 and dateToCheck.day == 1 ) then
                 returnValue = false
            -- Indatum är Julafton,Juldag, Annandag eller Nyårsafton
            elseif ( dateToCheck.month == 12 and (dateToCheck.day == 24 or dateToCheck.day == 25 or dateToCheck.day == 26 or dateToCheck.day == 31) ) then
               returnValue = false
          end

          -- Långfredag
            easterDay = Holidays_CalculateEaster(dateToCheck.year)
             if ( easterDay[1] == dateToCheck.year and easterDay[2] == dateToCheck.month and easterDay[3] == dateToCheck.day ) then
               returnValue = false
          end
          -- AnnandagPåsk
            easterDay2 = os.date("*t", os.time({year = easterDay[1], month = easterDay[2], day = easterDay[3]})+3*24*60*60)
             if ( easterDay2.year == dateToCheck.year and easterDay2.month == dateToCheck.month and easterDay2.day == dateToCheck.day ) then
               returnValue = false
          end
          -- Kristihimmelfärdsdag? +41 dagar från Långfredag?
            datum3 = os.date("*t", os.time({year = easterDay[1], month = easterDay[2], day = easterDay[3]})+41*24*60*60)
          if ( datum3.year == dateToCheck.year and datum3.month == dateToCheck.month and datum3.day == dateToCheck.day ) then
               returnValue = false
          end
            -- hitta midsommardagen för att kunna kontrollera midsommarafton
            -- midsommardagen = den lördag som infaller under tiden den 20-26 juni -> midsommarafton bör vara den fredag som inträffar under tiden 19-25 juni
            if ( dateToCheck.month == 6 and (dateToCheck.day >= 19 and dateToCheck.day <= 25) and dateToCheck.wday == 6 ) then
               returnValue = false
          end
           
            if ( Vacation_Days(dateToCheck) ) then
               returnValue = false
          end

  	if ( Vacation_Period(dateToCheck) ) then
           returnValue = false
	end     

            return returnValue
    end

    if WorkDay(os.date("*t")) then
       fibaro:setGlobal("WorkToday","True");
    else
       fibaro:setGlobal("WorkToday","False");
    end

    if WorkDay(os.date("*t", os.time()+24*60*60)) then
       fibaro:setGlobal("WorkTomorrow","True");
    else
       fibaro:setGlobal("WorkTomorrow","False");
    end
För den som vill importera en VD:
https://dl.dropboxusercontent.com/u/214 ... rkDay.vfib

Re: Påsk - och dess betydelse för kalendern...!

Posted: 08 Apr 2014, 20:02
by Johan71
Ok smart... men hur använder jag den ?
Skapa en scen ...ok men sen då ....ska det var variabler osv

Re: Påsk - och dess betydelse för kalendern...!

Posted: 08 Apr 2014, 21:51
by Bamsefar
Funktionen är i sig stabil - nu har jag testat den en längre tid.

Funktionen "WorkDay" svarar alltså True när det är en arbetsdags datum som man skickar in.

Exempel på att testa om dagens datum är en arbetsdag:

Code: Select all

if WorkDay(os.date("*t")) then
fibaro:debug("Arbetsdag: true");
else
fibaro:debug("Arbetsdag: false");
end
Men då man inte kan anropa funktioner från andra scener eller virtuella enheter utan enbart i samma virtuella enhet så måste man gå via Globala Variabler förslagsvis. Dvs istf fibaro:debug så får man låta en global variabel indikera att det är en arbetsdag idag. Och vill man testa på om imorgon är en arbetsdag eller helgdag:

Code: Select all

if WorkDay(os.date("*t", os.time()+24*60*60)) then
fibaro:debug("Arbetsdag imorgon: true");
else
fibaro:debug("Arbetsdag imorgon: false");
end
Jag kan säkert bidra med mera kod imorgon kväll - just nu lite hmm pressat...

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 09 Apr 2014, 18:32
by Bamsefar
Jag har ändrat första posten och uppdaterat koden med mera - hoppas att detta ger lite mera.

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 09 Apr 2014, 21:40
by Johan71
Ok är nu en bit på väg då jag lyckats få igång den med variabler som för i morgon är True.
Då ska jag "bara" ha in dom i mina scener för kvälls lyset.

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 10 Apr 2014, 00:22
by Bamsefar
Det kan ju vara bra att veta hur jag tänker på denna detalj inser jag:

WorkTomorrow styr om lamporna skall vara tända längre på kvällen, dvs om jag är ledig så lyser mina lampor någon timme extra.

WorkToday styr om lamporna skall tändas lite senare om jag är ledig idag.

Jag kör scriptet efter midnatt varje dygn för att sätta de globala variablerna. Och jag använder nästan jämt bara globala variabler för att trigga olika scener - jag tycker att det är snyggare och enklare att hantera på det sättet.

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 10 Apr 2014, 06:50
by Johan71
Ja men det är så jag har fattat det.
Hur ställer jag in när scenen ska köras dvs efter midnatt som du skrev?
När jag kollade nu på morgonen så va min variabel NaN inte True.
Men när jag körde min scen manuellt så ändrade den sig till True

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 10 Apr 2014, 09:42
by Bamsefar
Mja nu har jag en scen som rullar varje minut hela dygnet som efter midnatt anropar just detta script - så jag har lixom löst det lite annorlunda. Men du kan ju skapa en scen som kör ovanstående scen vid en fast tidpunkt eller?

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 11 Apr 2014, 07:36
by Johan71
Lyckades att få "kalender" scriptet så att mina lampor att slocknade igår, ska se i kväll om det släcker vid rätt tid, dvs 00:15.

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 11 Apr 2014, 22:24
by Johan71
Måste nog be någon kunnig om hjälp då det fast min variabel visar False så slocknade lamporna 2205

Code: Select all

--[[
%% autostart
%% properties
%% globals
WorkTomorrow
--]]

local sourceTrigger = fibaro:getSourceTrigger();
if (sourceTrigger["type"] == "autostart") then
while true do

local currentDate = os.date("*t");
local startSource = fibaro:getSourceTrigger();
if (
 ( ((currentDate.wday == 1 or currentDate.wday == 2 or currentDate.wday == 3 or currentDate.wday == 4 or currentDate.wday == 5 or currentDate.wday == 6 or currentDate.wday == 7) and string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) == "22:05") )
and
 ( tonumber(fibaro:getGlobalValue("WorkTomorrow")) == tonumber("True") )
)
then
	fibaro:call(11, "turnOff");
	fibaro:call(48, "turnOff");
	fibaro:call(7, "turnOff");
	fibaro:call(8, "turnOff");
	fibaro:call(10, "turnOff");
	fibaro:call(9, "turnOff");
	fibaro:call(5, "turnOff");
	fibaro:call(4, "turnOff");
	fibaro:call(6, "turnOff");
end

fibaro:sleep(60*1000);
end
else

local currentDate = os.date("*t");
local startSource = fibaro:getSourceTrigger();
if (
 ( (currentDate.wday == 1 or currentDate.wday == 2 or currentDate.wday == 3 or currentDate.wday == 4 or currentDate.wday == 5 or currentDate.wday == 6 or currentDate.wday == 7) )
and
 ( tonumber(fibaro:getGlobalValue("WorkTomorrow")) == tonumber("True") )
or
startSource["type"] == "other"
)
then
	fibaro:call(11, "turnOff");
	fibaro:call(48, "turnOff");
	fibaro:call(7, "turnOff");
	fibaro:call(8, "turnOff");
	fibaro:call(10, "turnOff");
	fibaro:call(9, "turnOff");
	fibaro:call(5, "turnOff");
	fibaro:call(4, "turnOff");
	fibaro:call(6, "turnOff");
end

end


Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 13 Apr 2014, 04:43
by Bamsefar
Jag ser flera saker:

1) Varför finns det bara i arbetsdagsfallet en while true-end med fibaro:sleep?
2) Och om du kör while true-end, hur kommer du ut från den loopen? För just nu så är det så har du kommit in, så kommer du inte ut... Alltså kan du inte då komma in i den lägre delen av if strukturen...
3) Den övre IF satsen bli sann vid 22:05 - men den nedre IF är sann alla tider på dygnet
4) Du testar på currentDate.Wday 1-7 => ta bort dessa - du testar alla dagar i veckan så den delen är ointressant att testa på...

Jag tror det finns några logik fel i din scen (jag antar att det är en scen?).

För att förklara hur det kan se ut, så måste du ge mig lite mera kött på benen hur du tänker, eller kanske snarare ge mig förutsättningarna som du har som krav, så kanske jag kan knacka koden som du behöver. Men som det är skrivet just nu är det mer eller mindre omöjligt att förstå hur du tänker...

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 13 Apr 2014, 06:13
by Johan71
Det är en block scen som jag har gjort om till lua. Trodde faktiskt att jag skulle klara av att justera till den i lua.
Det enda ja vill är att lamporna ska släckas 22:05 om det är en jobbdag dagen efter, och är det en helgdag dagen efter så ska lamporna slockna 00:30
Hoppas du förstår.


Skickas från min iPad via Tapatalk

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 13 Apr 2014, 18:48
by Bamsefar
Okej, jag sitter vid fel dator, tar en titt imorgon. Hoppas det duger....

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 18 Apr 2014, 14:57
by Johan71
Har du hunnit titta på det

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 18 Apr 2014, 18:30
by Bamsefar
Oj - dåligt samvete kommer ikapp - glömt. Sorry mitt fel - tittar direkt....

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 18 Apr 2014, 18:38
by Bamsefar
Jag har medvetet raderat denna post då LUA koden hade en del fel i sig och därmed inte fungerar - rätt kod finns längre ned i denna tråd.

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 18 Apr 2014, 20:49
by Johan71
Tack så mycket
Ska prova i kväll.

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 20 Apr 2014, 09:42
by Johan71
Hmm det slocknade 2205 igår m.a.o. så stämmer det inte inte. Eller kanske måste ha den på ett dygn innan den kommer i fas?

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 20 Apr 2014, 10:50
by Bamsefar
Jag hittade en underlighet som uppenbarade sig när man har en scen som startar en annan scen, och det är att just globala variabler inte får med sig förändringen av värdet.

Jag har medvetet raderat denna post då LUA koden hade en del fel i sig och därmed inte fungerar - rätt kod finns längre ned i denna tråd.

Re: Arbetsdag idag / imorgon - Hur man räknar ut Påsken varj

Posted: 21 Apr 2014, 00:15
by Bamsefar
Jag inser nu att du troligen hamnat i samma läge som jag gjorde för en kort tid sedan. En redan startad scen verkar inte klara av att fånga förändringar i globala variabler (t.ex. genom att scen 1 ropar på scen 2 osv).

Jag har medvetet raderat denna post då LUA koden hade en del fel i sig och därmed inte fungerar - rätt kod finns längre ned i denna tråd.