[LUA] Vacances scolaires
Publié : 05 août 2017, 00:54
Bonjour
Ci dessous je vous propose un script que j'ai réalisé pour savoir si nous sommes en vacances scolaires suivant une zone paramétré.
Il faut copier le code suivant dans un fichier nommer "script_time_vacances.lua" à placer dans le répertoire d'installation de domoticz\scripts\lua
Je remercie papoo, j'ai eu l'idée du script en tombant sur son script de vigilance météo qui m'a servi de base.
Dans domoticz, il faut créer 2 switchs que vous nommez comme vous le souhaité. Ensuite il faut renseigner les noms des switchs dans le script.
Edit
Mise à jour du script, Retourne si aujourd'hui ou demain est en vacances scolaires.
Edit 12/01/2018 : Mise à jour du script, corrige un problème de téléchargement du fichier vacances.xms
Edit 23/01/2018 : Mise à jour du script, gere les 2 switchs aujourd'hui & demain indépendamment
Edit 22/10/2019 : La source XML n'est plus mis à jour, passage sur une source json
Dernière version source JSON
Ancienne version source XML
Ci dessous je vous propose un script que j'ai réalisé pour savoir si nous sommes en vacances scolaires suivant une zone paramétré.
Il faut copier le code suivant dans un fichier nommer "script_time_vacances.lua" à placer dans le répertoire d'installation de domoticz\scripts\lua
Je remercie papoo, j'ai eu l'idée du script en tombant sur son script de vigilance météo qui m'a servi de base.
Dans domoticz, il faut créer 2 switchs que vous nommez comme vous le souhaité. Ensuite il faut renseigner les noms des switchs dans le script.
Edit
Mise à jour du script, Retourne si aujourd'hui ou demain est en vacances scolaires.
Edit 12/01/2018 : Mise à jour du script, corrige un problème de téléchargement du fichier vacances.xms
Edit 23/01/2018 : Mise à jour du script, gere les 2 switchs aujourd'hui & demain indépendamment
Edit 22/10/2019 : La source XML n'est plus mis à jour, passage sur une source json
Dernière version source JSON
Code : Tout sélectionner
--[[
auteur : DreamL
date de création : 28/07/2017
Principe : Retourne si la date est comprise dans une période de vacances pour une zone
Le 24/09/17, ajout si le lendemain est compris dans une période de vacances
Le 12/01/18 : Correction d'un bug qui bloquer le téléchargement du fichier xml
Le 22/01/2018 : Gere les 2 switchs indépendamment, Correction d'un bug sur la récupération du libellé des vacances
Le 22/10/2019 : La source XML n'est plus mis à jour. Utilisatation d'une autre source en json.
Necessite le module json = JSON.lua"
]]--
--Variables nécessaires au script
local tmpIdLibelle --Pour stocker temporairement l'id du libellé des vacances
local tmpFichierXml
local libelleVac --Libelle des vacances si vacances
local debutVac --Début des vacances scolaires
local finVac --Fin des vacances scolaires
local timenow = os.date("%H:%M")
local startClock = os.clock()
local flgdzVacancesScolaires = false
local flgdzVacancesScolairesDemain = false
--Variables a éditer
local debug = false --Permet d afficher des messages pour voir l'exécution du script
local forceExecution = false --Permet de forcer l'exécution sans tenir compte de l heure
-- Liste des jours pour récupérer le fichier xml
-- pour éviter de le télécharger tous les jours
--Mot clé possible :
-- /j = tous les jours
-- /m = toute les minutes
local listeJourTelechargementXml={}
listeJourTelechargementXml['30/03'] = '12:20'
listeJourTelechargementXml['30/06'] = '12:20'
listeJourTelechargementXml['30/09'] = '12:20'
listeJourTelechargementXml['30/12'] = '12:20'
--listeJourTelechargementXml['/j'] = '/m' --Pour test éventuel
local heureExecution = "00:03" --Format = HH:MM ex 02:04 ou 12:36, C'est l'heure à laquelle vous voulez que le switch domoticz soit mis a jour
local fname = "/home/ced/domoticz/scripts/lua/vacances.json" --Renseigner ici le répertoire destination du téléchargement
local fichierSource = "https://www.data.gouv.fr/fr/datasets/r/000ae493-9fa8-4088-9f53-76d375204036"
local DateDuJour = os.date("%Y-%m-%d")
local DateDemain = os.date("%Y-%m-%d",tonumber(os.time(t))+24*60*60)
local academie = "Nancy-Metz" --Indiquer ici l'académie
--Nom des dispositifs dans domoticz
local dzVacancesScolaires = "Aujourd hui vacances scolaires" --Renseigner ici le nom du switch a mettre a jour dans domoticz
local dzVacancesScolairesDemain = "Demain vacances scolaires" --Renseigner ici le nom du switch a mettre a jour dans domoticz
json = (loadfile "/home/ced/domoticz/scripts/lua/JSON.lua")() -- For Linux
--Télécharge le fichier json
function telechargeFile (url,dest)
retour=os.execute("wget -O "..dest.." "..url)
--Si erreur de téléchargement
if (debug) then print("Retour telechargement = "..tostring(retour)) end
if ( retour == false ) then
print("Impossible de télécharger le fichier "..url)
end
end
--Pour tester si le fichier est présent sur le disque
function ExisteFile (chemin)
if ( debug ) then print ('Fonction ExisteXML parametre = '..chemin) end
--Ouvre le fichier en lecture
local tmpExiste = false
local tmpFichier = io.open(chemin, "r")
--Verifie l'ouverture du fichier sur le disque
if ( tmpFichier == nil ) then
print("Erreur d'ouverture du fichier '" .. fname .. "'.")
else
tmpExiste = true
tmpFichier:close()
end
return tmpExiste
end
function rangeDate (Date,DateMin,DateMax)
--if ( debug ) then print('Appel fonction rangeDate '..Date..' '..DateMin..' '..DateMax) end
return ( Date >= DateMin and Date < DateMax)
end
commandArray = {}
if ( debug ) then print('Timenow = '..tostring(timenow) ) end
--Mise à jour du fichier vacances.xml
for jour, heure in pairs(listeJourTelechargementXml) do
tmpDate = os.date("%d/%m")
if ( debug ) then print('listeJourTelechargementXml = '..tostring(jour).." "..tostring(heure).." date du jour = "..tostring(tmpDate) ) end
if ( (tostring(jour) == tostring(tmpDate) or tostring(jour) == '/j') and
(tostring(heure) == timenow or tostring(heure) == '/m') ) then
if (debug) then print("C est le moment de telecharger = "..tostring(retour)) end
--Supprime le fichier apres le traitement
retour=os.execute("rm "..fname)
if ( retour == false ) then
print("Impossible de supprimer le fichier "..fname)
end
telechargeFile(fichierSource,fname)
end
end
if ( debug ) then print('heureExecution = '..tostring(heureExecution) ) end
if ( tostring(timenow) == tostring(heureExecution) or forceExecution) then
if ( debug ) then print(' DEBUT SCRIPT VACANCES SCOLAIRES') end
--Test si le fichier est présent sur le disque
if ( ExisteFile (fname ) ) then
if ( debug ) then print('Le fichier json est présent') end
else
--Si le fichier n'existe pas on le telecharge
if ( debug ) then print('Le fichier xml non présent') end
telechargeFile(fichierSource,fname)
end
local f = io.open(fname, "r")
--Verifie l'ouverture du fichier sur le disque
if ( f == nil ) then
print("Erreur d'ouverture du fichier '" .. fname .. "'.")
os.exit(1)
end
if ( debug ) then print('Ouverture du fichier json') end
local json_block = f:read('*all')
print('json_block = '..json_block)
local json_valeur = json:decode(json_block)
--Fermeture du fichier
f:close()
if ( debug ) then print("Date de mise a jour = ") end
if ( debug ) then print(tostring(DateDuJour)) end
if ( debug ) then print('Académie sélectionnée = '..academie) end
for i in pairs(json_valeur) do
if ( json_valeur[i].fields.location == academie and json_valeur[i].fields.end_date ~= nil ) then
--Test la date du jour
if ( rangeDate(DateDuJour,json_valeur[i].fields.start_date,json_valeur[i].fields.end_date) ) then
flgdzVacancesScolaires = true
if ( debug ) then print('i= '..tostring(i)..' '..json_valeur[i].fields.description) end
if ( debug ) then print('Début '..json_valeur[i].fields.start_date..' '..'Fin '..json_valeur[i].fields.end_date..' ') end
if ( debug ) then print('Date du jour : '..DateDuJour..' en vacances') end
end
--Test le lendemain
if ( rangeDate(DateDemain,json_valeur[i].fields.start_date,json_valeur[i].fields.end_date) ) then
flgdzVacancesScolairesDemain = true
if ( debug ) then print('i= '..tostring(i)..' '..json_valeur[i].fields.description) end
if ( debug ) then print('Début '..json_valeur[i].fields.start_date..' '..'Fin '..json_valeur[i].fields.end_date..' ') end
if ( debug ) then print('Date du jour : '..DateDemain..' en vacances') end
end
end
end
if ( flgdzVacancesScolaires ) then
print( tostring(DateDuJour)..' en vacances' )
commandArray[dzVacancesScolaires] = 'On'
else
print( tostring(DateDuJour)..' pas en vacances' )
commandArray[dzVacancesScolaires] = 'Off'
end
if ( flgdzVacancesScolairesDemain ) then
print( tostring(DateDemain)..' en vacances' )
commandArray[dzVacancesScolairesDemain] = 'On'
else
commandArray[dzVacancesScolairesDemain] = 'Off'
print( tostring(DateDemain)..' pas en vacances' )
end
end
if ( debug ) then print(' FIN SCRIPT VACANCES SCOLAIRES '..string.format('elapsed time: %.4f\n', os.clock() - startClock)..' seconde') end
return commandArray
Ancienne version source XML
Code : Tout sélectionner
--[[
auteur : DreamL
date de création : 28/07/2017
Principe : Retourne si la date est comprise dans une période de vacances pour une zone
Le 24/09/17, ajout si le lendemain est compris dans une période de vacances
Le 12/01/18 : Correction d'un bug qui bloquer le téléchargement du fichier xml
Le 22/01/2018 : Gere les 2 switchs indépendamment, Correction d'un bug sur la récupération du libellé des vacances
]]--
--Variables nécessaires au script
local tmpIdLibelle --Pour stocker temporairement l'id du libellé des vacances
local tmpFichierXml
local libelleVac --Libelle des vacances si vacances
local debutVac --Début des vacances scolaires
local finVac --Fin des vacances scolaires
local timenow = os.date("%H:%M")
local startClock = os.clock()
local flgdzVacancesScolaires = false
local flgdzVacancesScolairesDemain = false
--Variables a éditer
local debug = false --Permet d'afficher des messages pour voir l'exécution du script
local forceExecution = false --Permet de forcer l'exécution sans tenir compte de l'heure
-- Liste des jours pour récupérer le fichier xml
-- pour éviter de le télécharger tous les jours
--Mot clé possible :
-- /j = tous les jours
-- /m = toute les minutes
local listeJourTelechargementXml={}
listeJourTelechargementXml['30/03'] = '12:20'
listeJourTelechargementXml['30/06'] = '12:20'
listeJourTelechargementXml['30/09'] = '12:20'
listeJourTelechargementXml['30/12'] = '12:20'
--listeJourTelechargementXml['/j'] = '/m' --Pour test éventuel
local heureExecution = "00:03" --Format = HH:MM ex 02:04 ou 12:36, C'est l'heure à laquelle vous voulez que le switch domoticz soit mis a jour
local fname = "/home/pi/domoticz/scripts/lua/vacances.xml" --Renseigner ici le répertoire destination du téléchargement
local fichierSource = "http://telechargement.index-education.com/vacances.xml"
local DateDuJour = os.date("%Y/%m/%d")
local DateDemain = os.date("%Y/%m/%d",tonumber(os.time(t))+24*60*60)
local zoneSelect = "B" --Indiquer ici la zone
--Nom des dispositifs dans domoticz
local dzVacancesScolaires = "Aujourd hui vacances scolaires" --Renseigner ici le nom du switch a mettre a jour dans domoticz
local dzVacancesScolairesDemain = "Demain vacances scolaires" --Renseigner ici le nom du switch a mettre a jour dans domoticz
---------------------------------------------------------------------------------
-- Lua-Simple-XML-Parser
---------------------------------------------------------------------------------
XmlParser = {};
self = {};
function XmlParser:ToXmlString(value)
value = string.gsub(value, "&", "&"); -- '&' -> "&"
value = string.gsub(value, "<", "<"); -- '<' -> "<"
value = string.gsub(value, ">", ">"); -- '>' -> ">"
value = string.gsub(value, "\"", """); -- '"' -> """
value = string.gsub(value, "([^%w%&%;%p%\t% ])",
function(c)
return string.format("&#x%X;", string.byte(c))
end);
return value;
end
function XmlParser:FromXmlString(value)
value = string.gsub(value, "&#x([%x]+)%;",
function(h)
return string.char(tonumber(h, 16))
end);
value = string.gsub(value, "&#([0-9]+)%;",
function(h)
return string.char(tonumber(h, 10))
end);
value = string.gsub(value, """, "\"");
value = string.gsub(value, "'", "'");
value = string.gsub(value, ">", ">");
value = string.gsub(value, "<", "<");
value = string.gsub(value, "&", "&");
return value;
end
function XmlParser:ParseArgs(node, s)
string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a)
node:addProperty(w, self:FromXmlString(a))
end)
end
function XmlParser:ParseXmlText(xmlText)
local stack = {}
local top = newNode()
table.insert(stack, top)
local ni, c, label, xarg, empty
local i, j = 1, 1
while true do
ni, j, c, label, xarg, empty = string.find(xmlText, "<(%/?)([%w_:]+)(.-)(%/?)>", i)
if not ni then break end
local text = string.sub(xmlText, i, ni - 1);
if not string.find(text, "^%s*$") then
local lVal = (top:value() or "") .. self:FromXmlString(text)
stack[#stack]:setValue(lVal)
end
if empty == "/" then -- empty element tag
local lNode = newNode(label)
self:ParseArgs(lNode, xarg)
top:addChild(lNode)
elseif c == "" then -- start tag
local lNode = newNode(label)
self:ParseArgs(lNode, xarg)
table.insert(stack, lNode)
top = lNode
else -- end tag
local toclose = table.remove(stack) -- remove top
top = stack[#stack]
if #stack < 1 then
error("XmlParser: nothing to close with " .. label)
end
if toclose:name() ~= label then
error("XmlParser: trying to close " .. toclose.name .. " with " .. label)
end
top:addChild(toclose)
end
i = j + 1
end
local text = string.sub(xmlText, i);
if #stack > 1 then
error("XmlParser: unclosed " .. stack[#stack]:name())
end
return top
end
function XmlParser:loadFile(xmlFilename, base)
if not base then
base = system.ResourceDirectory
end
local path = system.pathForFile(xmlFilename, base)
local hFile, err = io.open(path, "r");
if hFile and not err then
local xmlText = hFile:read("*a"); -- read file content
io.close(hFile);
return self:ParseXmlText(xmlText), nil;
else
print(err)
return nil
end
end
function newNode(name)
local node = {}
node.___value = nil
node.___name = name
node.___children = {}
node.___props = {}
function node:value() return self.___value end
function node:setValue(val) self.___value = val end
function node:name() return self.___name end
function node:setName(name) self.___name = name end
function node:children() return self.___children end
function node:numChildren() return #self.___children end
function node:addChild(child)
if self[child:name()] ~= nil then
if type(self[child:name()].name) == "function" then
local tempTable = {}
table.insert(tempTable, self[child:name()])
self[child:name()] = tempTable
end
table.insert(self[child:name()], child)
else
self[child:name()] = child
end
table.insert(self.___children, child)
end
function node:properties() return self.___props end
function node:numProperties() return #self.___props end
function node:addProperty(name, value)
local lName = "@" .. name
if self[lName] ~= nil then
if type(self[lName]) == "string" then
local tempTable = {}
table.insert(tempTable, self[lName])
self[lName] = tempTable
end
table.insert(self[lName], value)
else
self[lName] = value
end
table.insert(self.___props, { name = name, value = self[name] })
end
return node
end
---------------------------------------------------------------------------
-- Lua-Simple-XML-Parser
---------------------------------------------------------------------------
--Télécharge le fichier xml
function telechargeXml (url,dest)
retour=os.execute("wget -O "..dest.." "..url)
--Si erreur de téléchargement
if (debug) then print("Retour telechargement = "..tostring(retour)) end
if ( retour == false ) then
print("Impossible de télécharger le fichier "..url)
end
end
--Pour tester si le fichier est présent sur le disque
function ExisteXml (chemin)
if ( debug ) then print ('Fonction ExisteXML parametre = '..chemin) end
--Ouvre le fichier en lecture
local tmpExiste = false
local tmpFichier = io.open(chemin, "r")
--Verifie l'ouverture du fichier sur le disque
if ( tmpFichier == nil ) then
print("Erreur d'ouverture du fichier '" .. fname .. "'.")
else
tmpExiste = true
tmpFichier:close()
end
return tmpExiste
end
commandArray = {}
if ( debug ) then print('Timenow = '..tostring(timenow) ) end
--Mise à jour du fichier vacances.xml
for jour, heure in pairs(listeJourTelechargementXml) do
tmpDate = os.date("%d/%m")
if ( debug ) then print('listeJourTelechargementXml = '..tostring(jour).." "..tostring(heure).." date du jour = "..tostring(tmpDate) ) end
if ( (tostring(jour) == tostring(tmpDate) or tostring(jour) == '/j') and
(tostring(heure) == timenow or tostring(heure) == '/m') ) then
if (debug) then print("C est le moment de telecharger = "..tostring(retour)) end
--Supprime le fichier apres le traitement
retour=os.execute("rm "..fname)
if ( retour == false ) then
print("Impossible de supprimer le fichier "..fname)
end
telechargeXml(fichierSource,fname)
end
end
if ( debug ) then print('heureExecution = '..tostring(heureExecution) ) end
if ( tostring(timenow) == tostring(heureExecution) or forceExecution) then
if ( debug ) then print(' DEBUT SCRIPT VACANCES SCOLAIRES') end
--Test si le fichier est présent sur le disque
if ( ExisteXml (fname ) ) then
if ( debug ) then print('Le fichier xml est présent') end
else
--Si le fichier n'existe pas on le telecharge
if ( debug ) then print('Le fichier xml non présent') end
telechargeXml(fichierSource,fname)
end
local f = io.open(fname, "r")
--Verifie l'ouverture du fichier sur le disque
if ( f == nil ) then
print("Erreur d'ouverture du fichier '" .. fname .. "'.")
os.exit(1)
end
--Recopie le fichier dans la variable
local testXml = f:read("*all")
--Fermeture du fichier
f:close()
--local parsedXml = xml:ParseXmlText(testXml)
local parsedXml = XmlParser:ParseXmlText(testXml)
if ( debug ) then print("Date de mise a jour = "..parsedXml.root["@miseajour"]) end
if ( debug ) then print(tostring(DateDuJour)) end
--La fonction est défini ici sinon erreur parseXml non défini
function libelleVacances(P_idLibelle)
if ( debug ) then print("Paramètre d'entrée libelleVacances = "..tostring(P_idLibelle)) end
for i in pairs(parsedXml.root:children()[3]:children() ) do
if ( debug ) then print ( 'i='..tostring(i)..' '..parsedXml.root:children()[3]:children()[i]:value() ) end
id = tostring(parsedXml.root:children()[3]:children()[i]["@id"])
if ( debug ) then print("id = "..tostring(id) ) end
if ( tostring(P_idLibelle) == id ) then
if ( debug ) then print ( parsedXml.root:children()[3]:children()[i]:value() ) end
return parsedXml.root:children()[3]:children()[i]:value()
end
end
end
for i in pairs(parsedXml.root.calendrier:children()) do
--Liste les zones
--Selectionne une zone
--Exemple zone A
--if ( debug ) then print(parsedXml.root.calendrier:children()[i]["@libelle"]) end
if (parsedXml.root.calendrier:children()[i]["@libelle"] == zoneSelect ) then
if ( debug ) then print("Zone "..zoneSelect.." trouvée") end
--if ( debug ) then print("Liste les périodes de vacances") end
for j in pairs(parsedXml.root.calendrier:children()[i]:children() ) do
--Verifie si la date est dans la période de vacances
if ( debug ) then print(parsedXml.root.calendrier:children()[i]:children()[j]["@debut"].." "..parsedXml.root.calendrier:children()[i]:children()[j]["@fin"].." "..parsedXml.root.calendrier:children()[i]:children()[j]["@libelle"]) end
if (tostring(DateDuJour) >= tostring(parsedXml.root.calendrier:children()[i]:children()[j]["@debut"]) and
tostring(DateDuJour) < tostring(parsedXml.root.calendrier:children()[i]:children()[j]["@fin"]) and
not(flgdzVacancesScolaires)
) then
if ( debug ) then print(parsedXml.root.calendrier:children()[i]:children()[j]["@debut"].." "..parsedXml.root.calendrier:children()[i]:children()[j]["@fin"].." "..parsedXml.root.calendrier:children()[i]:children()[j]["@libelle"]) end
if ( debug ) then print('La journéee est pendant des vacances scolaires, passe le switch a On') end
flgdzVacancesScolaires = true
tmpIdLibelle = parsedXml.root.calendrier:children()[i]:children()[j]["@libelle"]
debutVac = parsedXml.root.calendrier:children()[i]:children()[j]["@debut"]
finVac = parsedXml.root.calendrier:children()[i]:children()[j]["@fin"]
end
if (tostring(DateDemain) >= tostring(parsedXml.root.calendrier:children()[i]:children()[j]["@debut"]) and
tostring(DateDemain) < tostring(parsedXml.root.calendrier:children()[i]:children()[j]["@fin"]) and
not(flgdzVacancesScolairesDemain) ) then
if ( debug ) then print ('Demain est pendant les vacances scolaires') end
flgdzVacancesScolairesDemain = true
if ( not(flgdzVacancesScolaires) ) then
tmpIdLibelle = parsedXml.root.calendrier:children()[i]:children()[j]["@libelle"]
debutVac = parsedXml.root.calendrier:children()[i]:children()[j]["@debut"]
finVac = parsedXml.root.calendrier:children()[i]:children()[j]["@fin"]
end
end
end
end
end
if ( flgdzVacancesScolaires ) then
print( tostring(DateDuJour)..' en vacances' )
commandArray[dzVacancesScolaires] = 'On'
else
print( tostring(DateDuJour)..' pas en vacances' )
commandArray[dzVacancesScolaires] = 'Off'
end
if ( flgdzVacancesScolairesDemain ) then
print( tostring(DateDemain)..' en vacances' )
commandArray[dzVacancesScolairesDemain] = 'On'
else
commandArray[dzVacancesScolairesDemain] = 'Off'
print( tostring(DateDemain)..' pas en vacances' )
end
if ( libelleVac ~= nil ) then
libelleVac = libelleVacances(tmpIdLibelle)
end
if ( debug ) then print(" libellé des vacances = "..tostring(libelleVac) ) end
if ( debug ) then print(" Début des vacances le = "..tostring(debutVac) ) end
if ( debug ) then print(" Fin des vacances le = "..tostring(finVac) ) end
else
if ( debug ) then print(" pas encore le moment d executer !" ) end
end
if ( debug ) then print(' FIN SCRIPT VACANCES SCOLAIRES '..string.format('elapsed time: %.4f\n', os.clock() - startClock)..' seconde') end
return commandArray