-------------------------------------------------------------------------------- -- Probabilite pluie neige -------------------------------------------------------------------------------- --[[ name : script_time_probabilite_pluie.lua auteur : papoo version : 1.11 date de création : 08/08/2016 Date de mise à jour : 10/08/16 Principe : Ce script a pour but d'interroger l'API du site https://www.wunderground.com/ toutes les heures afin de récuperer les calculs de probabilités de pluie et de neige sur 36 heures pour une ville donnée. Cette API utilise une clé gratuite pour 500 requetes par heure Il faut donc s’inscrire sur weatherunderground pour avoir accès à cette API URL post : http://easydomoticz.com/forum/viewtopic.php?f=17&t=2301 Ce script utilise Lua-Simple-XML-Parser https://github.com/Cluain/Lua-Simple-XML-Parser ]]-- -- ======================================================================== -- Variables à éditer -- ======================================================================== local debugging = true -- true pour voir les logs dans la console log Dz ou false pour ne pas les voir local countryCode="FRANCE" -- Votre countryCode, nécessaire pour l'API local APIKEY="48a08328a93a18a1" -- Votre Key API Weather Underground de 16 caractères local ville="Redon" -- Votre ville ou commune nécessaire pour l'API -- L'api fournie 36 probabilités de pluie, 1 par heure. local proba_pluie_h = {} -- Ajoutez, modifiez ou supprimez les variables proba_pluie_h[] -- en changeant le N° entre [] correspondant à l'heure souhaitée pour l'associer au device concerné dans dz proba_pluie_h[1]=328 -- renseigner l'id du device % probabilité pluie à 1 heure associé, nil si non utilisé proba_pluie_h[2]=329 -- renseigner l'id du device % probabilité pluie à 2 heures associé, nil si non utilisé proba_pluie_h[4]=nil -- renseigner l'id du device % probabilité pluie à 4 heures associé, nil si non utilisé proba_pluie_h[6]=nil -- renseigner l'id du device % probabilité pluie à 6 heures associé, nil si non utilisé proba_pluie_h[12]=nil -- renseigner l'id du device % probabilité pluie à 12 heures associé, nil si non utilisé proba_pluie_h[24]=nil -- renseigner l'id du device % probabilité pluie à 24 heures associé, nil si non utilisé -- L'api fournie 36 probabilités de neige, 1 par heure. local proba_neige_h={} -- comme pour la pluie Ajoutez, modifiez ou supprimez les variables proba_neige_h[] -- en changeant le N° entre [] correspondant à l'heure souhaitée pour l'associer au device concerné dans dz proba_neige_h[1]=nil -- renseigner l'id du device % probabilité neige à 1 heure associé, nil si non utilisé proba_neige_h[3]=nil -- renseigner l'id du device % probabilité neige à 2 heures associé, nil si non utilisé proba_neige_h[6]=nil -- renseigner l'id du device % probabilité neige à 4 heures associé, nil si non utilisé proba_neige_h[12]=nil -- renseigner l'id du device % probabilité neige à 6 heures associé, nil si non utilisé proba_neige_h[24]=nil -- renseigner l'id du device % probabilité neige à 12 heures associé, nil si non utilisé proba_neige_h[36]=nil -- renseigner l'id du device % probabilité neige à 24 heures associé, nil si non utilisé local seuil_notification=80 -- pourcentage au delà duquel vous souhaitez être notifié, nil si non utilisé -- ======================================================================== -- Fin Variables à éditer -- ======================================================================== local pluie = nil local neige = nil local indexArray=0 --------------------------------------------------------------------------- --Fonctions --------------------------------------------------------------------------- function voir_les_logs (s,debugging) if (debugging) then if s ~= nil then print ("--- --- --- ".. s .." --- --- ---"); else print ("aucune valeur affichable"); end end end --------------------------------------------------------------------------------- -- 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 --------------------------------------------------------------------------- -- Fin Fonctions --------------------------------------------------------------------------- commandArray = {} now=os.date("*t") if now.min == 15 and ((now.hour >= 11 and now.hour <= 13) or (now.hour >= 17 and now.hour <= 20)) then -- éxécution du script toutes les heures voir_les_logs("script_time_probabilite_pluie.lua",debugging) local fname ="/tmp/weather"..ville.."1.out" os.execute("wget -q -O " .. fname .. " http://api.wunderground.com/api/"..APIKEY.."/hourly/lang:FR/q/"..countryCode.."/"..ville..".xml") --voir_les_logs("Fichier local : " ..fname,debugging) local f = io.open(fname, "r") if f == nil then voir_les_logs("Error opening file '" .. fname .. "'.",debugging) os.exit(1) end local testXml = f:read("*all") f:close() local parsedXml = XmlParser:ParseXmlText(testXml) if (parsedXml) then local abr = parsedXml.response.hourly_forecast for i in pairs(abr:children()) do if proba_pluie_h[i] ~= nil then pluie = tonumber(abr:children()[i]:children()[19]:value()) voir_les_logs("Probabilite de pluie a ".. i .."h => " .. pluie,debugging) commandArray[indexArray] = {['UpdateDevice'] = proba_pluie_h[i]..'|0|'.. pluie} indexArray=indexArray+1 if seuil_notification ~= nil and pluie > seuil_notification then commandArray[indexArray] = {['SendNotification'] = 'Alerte : '.. pluie ..' % de probabilité de pluie dans '.. i ..'heure(s)'} indexArray=indexArray+1 end end if proba_neige_h[i] ~=nil then neige = tonumber(abr:children()[i]:children()[18]:children()[2]:value()) voir_les_logs("probabilite de neige a ".. i .."h => " .. neige,debugging) commandArray[indexArray] = {['UpdateDevice'] = proba_neige_h[i]..'|0|'.. neige} indexArray=indexArray+1 if seuil_notification ~= nil and neige > seuil_notification then commandArray[indexArray] = {['SendNotification'] = 'Alerte : '.. neige ..' % de probabilité de neige dans '.. i ..'heure(s)'} indexArray=indexArray+1 end end end end end -- if now return commandArray