Bonjour Papoo,Dreaml,
@Papoo, en effet , étant donné l'heure avancée j'ai oublié le script
@Dreaml, c'est déjà bien de partager, et ces échanges serviront peut être à d'autres
Le script, seules modif: erreur sur la dernière date de modification (01 et non 10

)
le lien vers le fichier Xml et la Zone
Domoticz se plante si le script ne trouve pas le fichier xml sinon pas d'erreur signalée
J'avais du créer le fichier manuellement , les dispositifs se sont Mis à jour pour les vacances qui viennent de se finir (A on pendant les vacances, passage à off le dernier jour pour le dispositif du lendemain, et tous les deux à off le jour de la reprise.
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
]]--
--Variables nécessaires au script
local tmpIdLibelle --Pour stocker temporairement l'id du libellé des vacances
local tmpFichierXml
local vacancesScolaires --Booleen a vrai si vacances
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()
--Variables a éditer
local debug = true --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 -- false--true
-- 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 = "C:/Program Files (x86)/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 = "..tostring(P_idLibelle)) end
for i in pairs(parsedXml.root:children()[2]:children() ) do
id = parsedXml.root:children()[2]:children()[i]["@id"]
print("id = "..tostring(id) )
if ( tostring(P_idLibelle) == id ) then
return parsedXml.root:children()[2]: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"]) ) then
tmpIdLibelle = parsedXml.root.calendrier:children()[i]:children()[j]["@libelle"]
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
commandArray[dzVacancesScolaires] = 'On'
vacancesScolaires = true
debutVac = parsedXml.root.calendrier:children()[i]:children()[j]["@debut"]
finVac = parsedXml.root.calendrier:children()[i]:children()[j]["@fin"]
libelleVac = libelleVacances(tmpIdLibelle)
--si on trouve aujourd'hui, on test demain
if ( debug ) then print("Test pour demain = "..tostring(DateDemain)) 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"]) ) then
commandArray[dzVacancesScolairesDemain] = 'On'
else
commandArray[dzVacancesScolairesDemain] = 'Off'
end
break
else
--if ( debug ) then print('La journéee n est pas pendant des vacances scolaires, passe le switch a Off') end
commandArray[dzVacancesScolaires] = 'Off'
vacancesScolaires = false
end
end
end
end
if ( debug ) then print(" En vacances scolaires ?= "..tostring(vacancesScolaires) ) 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
Merci à vous pour votre aide bien venue
cdt
Bertrand
2024.6 PC Windows10 ; 2ème DEBIAN 10;DANFOSS LC13, Topp; Senseurs univ FIBARO FGBS001, Flood Sensor, ZMNHBD1 Flush 2 Relays ; FIBARO FGS222-FGS212;RFXCOM-RFXtrx433 USB 433.92MHz , Prises Phénix, Prises et Eclairage DI-O, SOMFY RTS,Sonoff ..