vigilance météoFrance

La météo des derniers mois a souvent généré des états de vigilance jaune, orange, voir rouge abondamment relayé par les médias.
Mais cette information de vigilance provient d’où?
La réponse est bien sur de météo France.
la question suivante est : comment récupérer ces informations dans notre système domotique pour être averti rapidement d’un changement dans l’état de vigilance, et éventuellement planifier des scénarios en conséquence.
Météo France fourni une API diffusant plusieurs informations pour un département donné :
Ces informations sont :
– couleur vigilance météo (Rouge, Orange, Jaune, Vert)
– risque associé : vent violent, pluie-inondation, orages, inondations, neige-verglas, canicule, grand-froid, avalanche, vagues-submersion
Une vigilance peut ne pas être associée à un risque. dans ce cas, affichage de la mention « risque non défini ».
– Conseils météo
– commentaires météo
– couleur vigilance crue avec 4 niveaux d’alerte
Niveau 4 Rouge : Risque de crue majeure. Menace directe et généralisée de la sécurité des personnes et des biens.
Niveau 3 Orange : Risque de crue génératrice de débordements importants susceptibles d’avoir un impact significatif sur la vie collective et la sécurité des biens et des personnes.
Niveau 2 Jaune : Risque de crue génératrice de débordements et de dommages localisés ou de montée rapide et dangereuse des eaux, nécessitant une vigilance particulière notamment dans le cas d’activités exposées et/ou saisonnières.
Niveau 1 Vert : Pas de vigilance particulière requise.

2016-05-29 11_40_33-Domoticz

pour ne pas surcharger l’APi offerte, nous releverons ces informations 3 fois par jour, à 07H10 13H10 et 18H10
-possibilité de ne remonter que les informations souhaitées (en déclarant les devicess non utilisés en nil)
-possibilité de régler le niveau de notification pour la vigilance météo et la vigilance crue(0: aucune notification, 1: toutes (meme verte), 2: vigilances jaune, orange et rouge, 3: vigilances orange et rouge 4: seulement vigilance rouge)
N’hésitez pas à proposer ici votre utilisation de ce script voir vos améliorations.

--[[
name : script_time_vigilance_meteofrance.lua
auteur : papoo
version : 1.20
date : 11/06/2016
Principe : Ce script a pour but de remonter toutes les informations de vigilance de météoFrance 3 fois par jour à 07H10 13H10 et 18H10 
Les informations disponibles sont :
- couleur vigilance météo (Rouge, Orange, Jaune, Vert)
- risque associé : vent violent, pluie-inondation, orages, inondations, neige-verglas, canicule, grand-froid, avalanche, vagues-submersion
Une vigilance peut ne pas être associée à un risque. dans ce cas, affichage de la mention "risque non défini".
- Conseils météo 
- commentaires météo
- couleur vigilance crue avec 4 niveaux d'alerte
Niveau 4 Rouge : Risque de crue majeure. Menace directe et généralisée de la sécurité des personnes et des biens.
Niveau 3 Orange : Risque de crue génératrice de débordements importants susceptibles d'avoir un impact significatif sur la vie collective et la sécurité des biens et des personnes.
Niveau 2 Jaune : Risque de crue génératrice de débordements et de dommages localisés ou de montée rapide et dangereuse des eaux, nécessitant une vigilance particulière notamment dans le cas d'activités exposées et/ou saisonnières.
Niveau 1 Vert : Pas de vigilance particulière requise.
Ce script utilise Lua-Simple-XML-Parser https://github.com/Cluain/Lua-Simple-XML-Parser
]]--
-- ========================================================================
-- Variables à éditer
-- ========================================================================
local departement = 87            -- renseigner votre numéro de département sur 2 chiffres exemples : 01 ou 07 ou 87 
local dz_vigilance_alert = 392      -- renseigner l'id du device alert vigilance meteo associé (dummy - alert)
local dz_alert_crue = 708         -- renseigner l'id du device alert vigilance crue associé (dummy - alert)
local dz_conseil_meteo = 706      -- renseigner l'id du device texte Conseils Météo associé si souhaité, sinon nil 
local dz_commentaire_meteo = 707   -- renseigner l'id du device texte Commentaire Météo associé si souhaité, sinon nil
local send_notification = 3       -- 0: aucune notification, 1: toutes (meme verte), 2: vigilances jaune, orange et rouge, 3: vigilances orange et rouge 4: seulement vigilance rouge
local send_notification_crue = 3       -- 0: aucune notification, 1: toutes (meme verte), 2: vigilances jaune, orange et rouge, 3: vigilances orange et rouge 4: seulement vigilance rouge
local debugging = false           -- true pour voir les logs dans la console log Dz ou false pour ne pas les voir

-- ========================================================================
-- Fin Variables à éditer
-- ========================================================================

local indexArray=0   
--------------------------------------------------------------------------- 
--Fonctions
---------------------------------------------------------------------------
function voir_les_logs (s)
    if (debugging) then 
        print ("".. s .."");
    end
end   

function risqueTxt(nombre)
      if nombre == 1 then return "vent violent" 
      elseif nombre == 2 then return "pluie-inondation" 
      elseif nombre == 3 then return "orages" 
      elseif nombre == 4 then return "inondations" 
      elseif nombre == 5 then return "neige-verglas" 
      elseif nombre == 6 then return "canicule" 
      elseif nombre == 7 then return "grand-froid" 
      elseif nombre == 8 then return "avalanche"
      elseif nombre == 9 then return "vagues-submersion"     
     else return "risque non defini" 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 == 10 and ((now.hour == 7) or (now.hour == 13) or (now.hour == 18))) then -- 3 éxecutions du script par jour à 7H10, 13h10 et 18H10
--if now.min % 56 == 0 then -- éxécution du script toutes les X minutes
print("script_time_vigilance_meteofrance.lua")

-- deux methodes pour récupérer les informations xml,  WGET ou CURL si vous décommentez la methode curl pensez à commenter la methode wget
      -- début methode wget
      local fname ="vigilance.xml"
      os.execute("wget -q -O " .. fname .. " http://vigilance.meteofrance.com/data/NXFR34_LFPW_.xml") 
      -- fin methode wget
      
      -- début methode curl
       --local fname ="/tmp/vigilance.xml"
       --os.execute("curl http://vigilance.meteofrance.com/data/NXFR34_LFPW_.xml > ".. fname .." && chmod 777 " .. fname)
      -- fin methode curl
      
      
       voir_les_logs("Fichier local : " ..fname,debugging)
      local f = io.open(fname, "r")

          if f == nil then
          print("Error opening file '" .. fname .. "'.")
          os.exit(1)
          end
 
      local testXml = f:read("*all")
               f:close()

local parsedXml = XmlParser:ParseXmlText(testXml)
   if (parsedXml) then local abr = parsedXml.cartevigilance    

      for i in pairs(abr:children()) do 
         if (abr:children()[i]:name() == "datavigilance") then 


            if (tonumber(abr:children()[i]["@dep"]) == departement) then 
            CouleurVigilance = tonumber(abr:children()[i]["@couleur"])
            voir_les_logs("--- --- --- Couleur Vigilance : ".. CouleurVigilance .. " pour le departement : ".. departement,debugging) 
                if (#abr:children()[i]:children() > 0) then 
                   for j = 1, #abr:children()[i]:children() do 
                      if (abr:children()[i]:children()[j]:name() == "crue") then 
                      crue = tonumber(abr:children()[i]:children()[j]["@valeur"]) 
                         if crue ~= nil then
                         voir_les_logs("--- --- --- Crue trouvée : ".. crue,debugging) 
                         else
                         voir_les_logs("--- --- --- pas d'information Crue trouvée",debugging)
                         end
                      elseif (abr:children()[i]:children()[j]:name() == "risque") then 
                      risque = tonumber(abr:children()[i]:children()[j]["@valeur"]) 
                      voir_les_logs("--- --- --- Risque trouvée : ".. risque,debugging) 
                      end 
                   end 
                end
            end
          elseif (abr:children()[i]:name() == "entetevigilance") then 
                for j in pairs(abr:children()[i]:children()) do 
                   if (abr:children()[i]:children()[j]:name() == "vigilancecommentaire") then 
                   commentaire = abr:children()[i]:children()[j]["@texte"] 
                     if commentaire ~= nil then
                  voir_les_logs("--- --- --- Commentaire : " ..commentaire,debugging)
                     else
                  voir_les_logs("--- --- --- pas de Commentaire",debugging)   
                     end
                   end
                   if (abr:children()[i]:children()[j]:name() == "vigilanceconseil") then 
                   conseil = abr:children()[i]:children()[j]["@texte"] 
                     if conseil ~= nil then
                  voir_les_logs("--- --- --- Conseils : ".. conseil,debugging)
                     end
                   end 
                end 
         end
      end   
   else
   print("erreur parsedXml")
   end   

risque = risqueTxt(risque)
    
   if CouleurVigilance == nil and dz_vigilance_alert ~= nil then
          commandArray[indexArray] = {['UpdateDevice'] = dz_vigilance_alert ..'|0|'.. risque}
         voir_les_logs("--- --- --- Aucune donnée disponible pour la departement : ".. departement,debugging) 
          indexArray=indexArray+1
   end   


   if CouleurVigilance   ~= nil then   
      voir_les_logs("--- --- --- CouleurVigilance : ".. CouleurVigilance,debugging)
      if tonumber(CouleurVigilance) == 1   then -- niveau 1
         if dz_vigilance_alert ~= nil then
             commandArray[indexArray] = {['UpdateDevice'] = dz_vigilance_alert..'|1|'.. risque}
             indexArray=indexArray+1
         end
         if send_notification > 0 and send_notification < 2 then
             commandArray[indexArray] = {['SendNotification'] = 'Alerte vigilance meteo#'.. risque}
             indexArray=indexArray+1
         end
           voir_les_logs("--- --- --- Pas de vigilance --- --- ---",debugging)
      elseif tonumber(CouleurVigilance) == 2   then -- niveau 2
         if dz_vigilance_alert ~= nil then
             commandArray[indexArray] = {['UpdateDevice'] = dz_vigilance_alert..'|2|'.. risque}
             indexArray=indexArray+1
         end
         if send_notification > 0 and send_notification < 3 then
             commandArray[indexArray] = {['SendNotification'] = 'Alerte vigilance meteo#'.. risque}
             indexArray=indexArray+1
         end
           voir_les_logs("--- --- --- vigilance faible ".. risque.. " --- --- ---",debugging)   
      elseif tonumber(CouleurVigilance) == 3   then -- niveau 3
         if dz_vigilance_alert ~= nil then
             commandArray[indexArray] = {['UpdateDevice'] = dz_vigilance_alert..'|3|'.. risque}
             indexArray=indexArray+1
         end
         if send_notification > 0 and send_notification < 4 then
             commandArray[indexArray] = {['SendNotification'] = 'Alerte vigilance meteo#'.. risque}
             indexArray=indexArray+1
         end
           voir_les_logs("--- --- --- vigilance Forte ".. risque.. " --- --- ---",debugging)      
      elseif tonumber(CouleurVigilance) > 3  then -- niveau 4
         if dz_vigilance_alert ~= nil then
             commandArray[indexArray] = {['UpdateDevice'] = dz_vigilance_alert..'|4|'.. risque}
             indexArray=indexArray+1
         end
         if send_notification > 0 and send_notification < 5 then
             commandArray[indexArray] = {['SendNotification'] = 'Alerte vigilance meteo#'.. risque}
             indexArray=indexArray+1
         end
           voir_les_logs("--- --- --- vigilance très forte ".. risque.. " --- --- ---",debugging)
      else
        print("niveau non defini")
      end
   end
      
-- ====================================================================================================================   
-- Conseil météo     
-- ====================================================================================================================         
         if dz_conseil_meteo ~= nil and conseil ~= nil then -- Mise à jour du devise texte conseil météo si il existe
          commandArray[indexArray] = {['UpdateDevice'] = dz_conseil_meteo..'|0|'.. conseil}
          indexArray=indexArray+1
         elseif dz_conseil_meteo ~= nil and conseil == nil then -- Mise à jour du devise texte conseil météo si il existe même s'il n'y a pas de conseil disponible
          commandArray[indexArray] = {['UpdateDevice'] = dz_conseil_meteo..'|0|Aucun conseil disponible'}
          indexArray=indexArray+1        
         end
-- ====================================================================================================================   
-- Commentaire météo     
-- ====================================================================================================================        
     
         if dz_commentaire_meteo ~= nil and commentaire ~= nil then -- Mise à jour du devise texte commentaire météo si il existe
          commandArray[indexArray] = {['UpdateDevice'] = dz_commentaire_meteo..'|0|'.. commentaire}
          indexArray=indexArray+1
         elseif dz_commentaire_meteo ~= nil and commentaire == nil then -- Mise à jour du devise texte commentaire météo si il existe même s'il n'y a pas de commentaire disponible
          commandArray[indexArray] = {['UpdateDevice'] = dz_commentaire_meteo..'|0|Aucun commentaire disponible'}
          indexArray=indexArray+1
         end
 
-- ====================================================================================================================   
-- vigilance crue     
-- ====================================================================================================================
   if dz_alert_crue ~= nil and crue ~= nil then   
      voir_les_logs("--- --- --- Vigilance Crue : ".. crue,debugging)


      if tonumber(crue) == 1   then -- niveau 1
           if dz_alert_crue ~= nil then
             commandArray[indexArray] = {['UpdateDevice'] = dz_alert_crue..'|1|Pas de vigilance Crue'}
             indexArray=indexArray+1
           end
           if send_notification_crue > 0 and send_notification_crue < 2 then
             commandArray[indexArray] = {['SendNotification'] = 'Alerte vigilance crue#Pas de vigilance Crue'}
             indexArray=indexArray+1
           end
           voir_les_logs("--- --- --- Pas de vigilance crue --- --- ---",debugging)
      elseif tonumber(crue) == 2   then -- niveau 2
           if dz_alert_crue ~= nil then
             commandArray[indexArray] = {['UpdateDevice'] = dz_alert_crue..'|2|Risque de crue génératrice de débordements localisés'}
             indexArray=indexArray+1
           end
           if send_notification_crue > 0 and send_notification_crue < 3 then
             commandArray[indexArray] = {['SendNotification'] = 'Alerte vigilance crue#Risque de crue génératrice de débordements localisés'}
             indexArray=indexArray+1
           end
           voir_les_logs("--- --- --- vigilance faible Crue --- --- ---",debugging)   
      elseif tonumber(crue) == 3   then -- niveau 3
           if dz_alert_crue ~= nil then
             commandArray[indexArray] = {['UpdateDevice'] = dz_alert_crue..'|3|Risque de crue génératrice de débordements importants'}
             indexArray=indexArray+1
           end
           if send_notification_crue > 0 and send_notification_crue < 4 then
             commandArray[indexArray] = {['SendNotification'] = 'Alerte vigilance crue#Risque de crue génératrice de débordements importants'}
             indexArray=indexArray+1
           end
           voir_les_logs("--- --- --- vigilance Forte Crue --- --- ---",debugging)      
      elseif tonumber(crue) > 3  then -- niveau 4
           if dz_alert_crue ~= nil then
             commandArray[indexArray] = {['UpdateDevice'] = dz_alert_crue..'|4|Risque de Crue majeure'}
             indexArray=indexArray+1
           end
           if send_notification_crue > 0 and send_notification_crue < 5 then
             commandArray[indexArray] = {['SendNotification'] = 'Alerte vigilance crue#Risque de crue majeure'}
             indexArray=indexArray+1
           end
           voir_les_logs("--- --- --- vigilance très forte Crue --- --- ---",debugging)
      else
        print("niveau non defini")
      end        
      if dz_alert_crue ~= nil and crue == nil then
      commandArray[indexArray] = {['UpdateDevice'] = dz_alert_crue..'|0|Pas d\'information vigilance Crue'}
      indexArray=indexArray+1
      end
    end         
-- ====================================================================================================================   
-- fin vigilance crue     
-- ====================================================================================================================   
end -- if now
return commandArray

One thought on “vigilance météoFrance

Laisser un commentaire