Indispensable dans une box domotique
Il est souvent utile de savoir si le jour courant est un jour passé à la maison, ou pas, pour planifier la programmation des luminaires ou du thermostat. Ce billet présente un ensemble de fonctions permettant de déterminer si le jour courant est un jours chômé (c’est à dire un jour où au moins un membre de la famille reste à la maison).
Jours chômés
La fonction principale pourrait se résumer à celle-ci :
function josdJourChome() local jour=josdGetJourSemaine() return jour=="samedi" or jour=="dimanche" or josdJourFerie() or josdJourVacances() end |
Un jour chômé est donc un samedi, un dimanche (à adapter selon votre situation) un jour férié ou un jour de vacances scolaires. Cette fonction fait appel à d’autres fonctions (josdGetJourSemaine()
, josdJourFerie()
ou josdJourVacances()
) que nous détaillerons plus bas.
La fonction josdJourChome()
risque d’être appelée souvent au cours de la journée. Or, elle retourne toujours la même valeur booléenne pour une journée donnée. J’ai donc décidé de l’optimiser pour ne pas charger la Vera de calculs inutiles :
-- Retourne true si le jour courant est un jour chômé (passé à la maison) -- Le calcul effectif n'est fait qu'une fois par jour (ou si la Vera reboot) josdJourChomeToday="NULL" -- Variable globale (date du dernier calcul) pour ne pas recalculer le résultat à chaque appel josdJourChomeReturn=false -- Variable globale (résulat du dernier calcul) pour ne pas recalculer le résultat à chaque appel function josdJourChome() local today=os.date("%Y-%m-%d") if(today~=josdJourChomeToday) then -- Faut-il refaire le calcul ? local jour=josdGetJourSemaine() josdJourChomeToday=today josdJourChomeReturn=(jour=="samedi" or jour=="dimanche" or josdJourFerie() or josdJourVacances()) end return josdJourChomeReturn end |
Débarrassons-nous tous de suite de la fonction josdGetJourSemaine()
qui est toute simple :
-- Retourne le jour de la semaine (lundi...dimanche) josdGetJourSemaineTab={[0]="dimanche",[1]="lundi",[2]="mardi",[3]="mercredi",[4]="jeudi",[5]="vendredi",[6]="samedi"} function josdGetJourSemaine() return josdGetJourSemaineTab[tonumber(os.date("%w"))] end |
Jours de vacances
Pour la fonction josdJourVacances()
, je n’ai rien trouvé d’automatique. Chacun peut poser ses vacances quand il veut. De plus, les vacances scolaires varient en fonction des zones (A, B ou C), des années mais aussi des écoles (les vacances de l’Université ne sont pas les mêmes que celles du primaire par exemple). Bref, voici un modèle correspondant aux vacances scolaires de la zone C (Paris) en 2014 à adapter chaque année selon vos besoins particuliers :
-- Retourne true si le jour courant est un jour de vacances scolaires function josdJourVacances() local today=os.date("%Y-%m-%d") local vacances=false -- 2013-2014 if ("2013-10-19"<=today and today<"2013-11-04") then vacances=true -- Toussaint elseif ("2013-12-21"<=today and today<"2014-01-06") then vacances=true -- Noël elseif ("2014-02-15"<=today and today<"2014-03-03") then vacances=true -- Hiver Zone C elseif ("2014-04-12"<=today and today<"2014-04-28") then vacances=true -- Printemps Zone C elseif ("2014-07-05"<=today and today<"2014-09-01") then vacances=true -- Vacances d'été -- 2014-2015 elseif ("2014-10-18"<=today and today<"2014-11-03") then vacances=true -- Toussaint Zones elseif ("2014-12-20"<=today and today<"2015-01-05") then vacances=true -- Noël elseif ("2015-02-14"<=today and today<"2015-03-02") then vacances=true -- Hiver Zone C elseif ("2015-04-18"<=today and today<"2015-05-04") then vacances=true -- Printemps Zone C elseif ("2015-07-04"<=today and today<"2015-08-31") then vacances=true -- Vacances d'été -- 2015-2016 elseif ("2015-10-17"<=today and today<"2015-11-02") then vacances=true -- Toussaint elseif ("2015-12-19"<=today and today<"2016-01-04") then vacances=true -- Noël elseif ("2016-02-20"<=today and today<"2016-03-07") then vacances=true -- Hiver Zone C elseif ("2016-04-23"<=today and today<"2016-05-09") then vacances=true -- Printemps Zone C elseif ("2016-07-02"<=today and today<"2016-09-01") then vacances=true -- Vacances d'été -- 2016-2017 elseif ("2016-10-19"<=today and today<"2016-11-03") then vacances=true -- Toussaint elseif ("2016-12-17"<=today and today<"2017-01-03") then vacances=true -- Noël elseif ("2017-02-04"<=today and today<"2017-02-20") then vacances=true -- Hiver Zone C elseif ("2017-04-08"<=today and today<"2017-04-24") then vacances=true -- Printemps Zone C elseif ("2017-07-06"<=today and today<"2017-09-01") then vacances=true -- Vacances d'été end return vacances end |
Jours fériés
Là, c’est plus compliqué. Certains jours fériés ont une date fixe, mais d’autres sont calés sur la date de Pâques qui est complexe à déterminer. Voici une fonction qui calcule et retourne la date de Pâques au format epoch en fonction de l’année passée en paramètre. Cette fonction stocke le résultat du calcul pour pouvoir retourner immédiatement le résultat si elle est appelée une nouvelle fois avec la même année que l’appel précédent.
-- Retourne le jour de Pâques au format epoch -- annee : année (Integer) dont on désire connaître le jour de Pâques (ex : 2014) -- La fonction n'effectue le calcul que si l'année a changée depuis son dernier appel josdGetJourPaquesAnnee=0 -- Variable globale (année du dernier calcul) pour ne pas recalculer le jour de Pâques à chaque appel josdGetJourPaquesEpochPaque=0 -- Variable globale (jour de Pâques au format epoch) pour ne pas recalculer le jour de Pâques à chaque appel function josdGetJourPaques(annee) if(josdGetJourPaquesAnnee~=annee or josdGetJourPaquesEpochPaque==0) then local a=math.floor(annee/100) local b=math.fmod(annee,100) local c=math.floor((3*(a+25))/4) local d=math.fmod((3*(a+25)),4) local e=math.floor((8*(a+11))/25) local f=math.fmod((5*a+b),19) local g=math.fmod((19*f+c-e),30) local h=math.floor((f+11*g)/319) local j=math.floor((60*(5-d)+b)/4) local k=math.fmod((60*(5-d)+b),4) local m=math.fmod((2*j-k-g+h),7) local n=math.floor((g-h+m+114)/31) local p=math.fmod((g-h+m+114),31) local jour=p+1 local mois=n josdGetJourPaquesAnnee=annee josdGetJourPaquesEpochPaque=os.time{year=annee,month=mois,day=jour,hour=12,min=0} end return josdGetJourPaquesEpochPaque end |
Il est maintenant possible d’implémenter la fonction qui permet de déterminer si le jour courant est un jour férié.
-- Retourne true si le jour courant est un jour férié -- Le calcul des jours férié n'est fait qu'un fois par an (ou si la Vera reboot) josdJourFerieAnnee=0 -- Variable globale (année du dernier calcul) pour ne pas recalculer le tableau à chaque appel josdJourFerieTab = {} -- Variable globale (tableau des jours fériés) pour ne pas recalculer le tableau à chaque appel function josdJourFerie() local today=os.date("%m-%d") local annee=tonumber(os.date("%Y")) if(annee~=josdJourFerieAnnee) then josdJourFerieAnnee=annee -- Dates fixes josdJourFerieTab["01-01"] = true -- 1er janvier josdJourFerieTab["05-01"] = true -- Fête du travail josdJourFerieTab["05-08"] = true -- Victoire des alliés josdJourFerieTab["07-14"] = true -- Fête nationale josdJourFerieTab["08-15"] = true -- Assomption josdJourFerieTab["11-01"] = true -- Toussaint josdJourFerieTab["11-11"] = true -- Armistice josdJourFerieTab["12-25"] = true -- Noël -- Dates variables local epochPaques=josdGetJourPaques(annee) josdJourFerieTab[os.date("%m-%d",epochPaques)] = true -- Pâques josdJourFerieTab[os.date("%m-%d",epochPaques+24*60*60)] = true -- Lundi de Pâques = Pâques + 1 jour josdJourFerieTab[os.date("%m-%d",epochPaques+24*60*60*39)] = true -- Ascension = Pâques + 39 jours josdJourFerieTab[os.date("%m-%d",epochPaques+24*60*60*49)] = true -- Pentecôte = Ascension + 49 jours end return josdJourFerieTab[today] -- (nldr : Both nil and false make a condition false) end |
Produits
Shopping : Vera Lite – Contrôleur domotique Z-wave