Page 1 sur 11

[DzVents] Données Météo Weather Visual Crossing

Publié : 10 avr. 2023, 12:51
par BernardC
Bonjour,
Etant à la recherche d’une solution pour remplacer » Darksky API « suite à la disparition le 1/4/2023, j’ai attiré par deux post sur ce forum :
Celui de Gilles avec le script DZ pour l’API openweathermap
Et celui de Lost pour Weather Visual Crossing

Je me suis dit que serai judicieux d’adapter le script de Gilles pour « Weather Visual Crossing » qui offre de nombreuses possibilités avec 1000 consultations par jour gratuit.
Je me suis lancé dans l’aventure. L’exercice fut pour moi très pédagogique et j’ai réussi l’adaptions de mes devices Darksky .

1°) J’ai modifié dans Domoticz ,Materiel, le type de ma station météo Darksky par le type « Dummy (Does nothing, use for virtual switches only) »
Cela permet de conserver l’historique de DarKsy
2°) il est ensuite préférable de redémarrer Domoticz pour que la base de données prenne en compte la modification (j’ai des soucis pour la « update » du premier device que j’ai testé, il ni avais pas accès à la data. J’ai pour ma part solutionné le problème par la modif de la description du device….)
3°) dans le script j’utilise les mnémoniques et non l’ID pour les devices :
Barometre, Couverture nuageuse ,UV ,Visibilite ,Vent ,Pluie
!!!Pas accents pour les noms des mnemos !!!
Je n’ai pas trouvé d’infos pour le capteur d’Ozone..
4°) je me suis inscris chez https://www.visualcrossing.com/sign-up
5°) j’ai récupérer ma clé API https://www.visualcrossing.com/account
6°)j’ai testé ma clé sur le navigateur avec la requête suivante, sur « FireFox » les infos JSON sont mis en forme.
requête type pour remplacer DarkSky API pour La localitée "Le Mans" dans Sarthe:
https://weather.visualcrossing.com/Visu ... key=<votre cle API>&options=nonulls&contentType=json
7°) J’ai chargé le script suivant a l’emplacement /home/pi/domoticz/scripts/dzVents/scripts/weathervisualcrossing.lua, suivant la machine il faut adapter ‘PI’

Code : Tout sélectionner

--[[ --[[ ~/home/pi/domoticz/scripts/dzVents/scripts/weathervisualcrossing.lua

author : gso
       : modifié pour weathervisualcrossing par BernardC
MAJ : 10/06/2023
création : 24/03/2023
Principe :
lien pour inscription à  weather visual crossing:
https://www.visualcrossing.com/sign-up
lien pour récupérer la clé:
https://www.visualcrossing.com/account
requête type pour remplacer DarkSky API pour La localitée "Le Mans" dans Sarthe
https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Le%20Mans/today?unitGroup=metric&include=fcst%2Ccurrent&key=<votre cle API>&options=nonulls&contentType=json
}

]]--

local scriptName = 'weather.visualcrossing'
local scriptVersion = '1.21'

--[[**********************************************
--      les 2 variables à renseigner 
--       suivant utilisateur
--**********************************************]]--
local Localite = 'Le%Mans'
local apiKey = '<votre clé API>' 
--**********************************************
--**********************************************
-- MAJ le8/6/2023  enlevé "unitGroup=metric&maxDistance=20000" de la requête
local uri = 'https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/'..Localite..'?&include=days%2Ccurrent%2Chours&key='..apiKey..'&contentType=json'
local prefix = 'WVC'
--======================Probabilité Pluie MAJ le 4/5/2023==============================
local function lectProb(duree,v)
    -- duree--durée en H de la probabilité 
    -- V données JSON 
    local Time = require('Time')
    local now = Time()
    local Heure = now.hour+1 -- heure de debut + 1 pour index
    local J = 1 --init jour
    local Prob,ResulProb =0,0
    for i = Heure,Heure + duree - 1 do -- 1 à 24 -> durée -1
        H= i
        if i > 24 then J =2 H = i-24 end
        if i > 48 then J =3 H = i-48 end
        Prob= v.days[J].hours[H].precipprob
       if Prob> ResulProb then ResulProb = Prob end
    end
    return (ResulProb )

    return (ResulProb )
end
--================================================================================

--=================================================================================================================================================================
--=                  -- devices idx (à modifier en conséquence), fonction de maj donnée devices domoticz 
--=================================================================================================================================================================
local StMeteo = { 

    --Temp=Humidity+Baro  Barométre
    {idx = 'Barometre', cde = function (dz, idx, v) 
        local clouds = v.currentConditions.cloudcover
        local baro = dz.BARO_NOINFO
        if v.currentConditions.precipprob >= 0.3 then baro = dz.BARO_RAIN-- probability of precipitation for tomorrow
            elseif clouds >= 75 then baro = dz.BARO_CLOUDY
            elseif clouds >= 25 then baro = dz.BARO_PARTLYCLOUDY   -- et pas  BARO_PARTLY_CLOUDY comme dans le wiki ??
            else baro = dz.BARO_SUNNY
        end
        dz.devices(idx).updateTempHumBaro(v.currentConditions.temp,v.currentConditions.humidity,dz.HUM_COMPUTE,v.currentConditions.pressure,baro)
        -- test print('user var'..dz.uservariables('Mem_Debit_Eau').value)
    end },
   
    -- UV corrigé erreur "dz.devices(198)" en "dz.devices(idx)" le 8/6/2023
    {idx = 'UV', cde = function (dz, idx, v) dz.devices(idx).updateUV(v.currentConditions.uvindex) end },
    
    -- Couverture nuageuse
    {idx = 'Couverture nuageuse', cde = function (dz, idx, v) dz.devices(idx).updatePercentage(v.currentConditions.cloudcover) end },
    
    -- Visibilité en (km) 
    {idx = 'Visibilite', cde = function (dz, idx, v) dz.devices(idx).updateVisibility(v.currentConditions.visibility) end }, 

     -- Pluie MAJ le 25/04/2023
    {idx = 'Pluie',  cde = function (dz, idx, v)
        --lecture des dernieres valeurs rainRate et compteur rain à partir de sValue
        --devices(idx).rain fournit la pluie réelle d'aujourd'hui (pas le compteur ) 
        local f_rainValTable = dz.utils.stringSplit(dz.devices(idx).sValue,';')
        local rain = f_rainValTable[2]
        if v.currentConditions.precip == nil then v.currentConditions.precip = f_rainValTable[1]/100 end 
        local Time = require('Time')
        local  now = Time()
        if dz.devices(idx).lastUpdate.secondsAgo <= now.secondsSinceMidnight then --incrémentation compteur pluie
            rain = rain + ( v.currentConditions.precip * dz.devices(idx).lastUpdate.secondsAgo / 3600 )
        else -- la dernière mise à jour date d'hier
            rain =  v.currentConditions.precip * dz.devices(idx).lastUpdate.secondsAgo/ 3600  
        end

        --(hauteur en mm * 100 par heure, le compteur est total en mm) 
        dz.devices(idx).updateRain(v.currentConditions.precip*100, rain)   
    end }, 

   
    -- Vent en m/s
    {idx = 'Vent', cde = function (dz, idx, v)   
        if v.currentConditions.windgust == nil then v.currentConditions.windgust = v.days[1].windgust end
        degrees = v.currentConditions.winddir
        local quadrants = {"NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"}
        local quad = 'N'
        if degrees <= 348.75 and degrees > 11.25 then quad = quadrants[tonumber(math.floor((degrees - 11.25) / 22.5)+1)] end
        dz.devices(idx).updateWind(degrees, quad, v.currentConditions.windspeed/3.6, v.currentConditions.windgust/3.6, v.currentConditions.temp, v.currentConditions.feelslike)
        -- bearing(°), direction(N S NNW..), speed(m/s), gust(m/s), temperature(°C), chill(°C) 287.00;WNW;78;135;10.5;9.8
        -- vitesse vent/3,6 pour adapter l'affichage, les données reçu sont en Km/H
    end },
    
    --quantité d'énergie solaire reçue  en W/m²  ajout d'un capteur virtuel "rayonnement solaire" le 35/04/2023
    {idx = 'Soleil',   cde = function (dz, idx, v) dz.devices(idx).updateRadiation(v.currentConditions.solarradiation) end }, 
  
    --Proba Pluie 2 Jours  ajout d'un capteur virtuel "Poucentage le 2/05/2023           lectProb(Nbre H proba pluie,JSON)
    {idx = 'Proba Pluie 2J', cde = function (dz, idx, v) dz.devices(idx).updatePercentage(lectProb(48,v)) end },   

--[[  -- devices à modifier pour l'ajout 
   
    -- Snow
    {idx = 0,    cde = function (dz, idx, v) 
        if v.current.snow ~= nil  then dz.devices(idx).updateRain(v.current.snow['1h']*100, v.daily[1].snow)
        elseif v.daily[1] ~= nil then dz.devices(idx).updateRain(0, v.daily[1].snow) 
        else dz.devices(idx).updateRain(0, 0) end
    end }, --rate in mm * 100 per hour, counter is total in mm)
    
    -- Meteo
    {idx = 979,  cde = function (dz, idx, v)
        local txt = v.current.weather[1].description..' ('..v.current.weather[1].main..' - '..v.current.weather[1].id..')'
        dz.devices(idx).updateText(txt)
    end },
    
    -- Moon
    {idx = 989,  cde = function (dz, idx, v)
        -- local dt  = os.date("%a %d %b à %X", v.daily[1].dt) -- UTC
        local moonrise  = os.date("%Hh%M", v.daily[1].moonrise) -- UTC
        local moonset   = os.date("%Hh%M", v.daily[1].moonset) -- UTC
        local p = v.daily[1].moon_phase*100 -- 0 and 1 are 'new moon', 0.25 is 'first quarter moon', 0.5 is 'full moon' and 0.75 is 'last quarter moon'.
        if p==0 or p==100 then phase = "Nouvelle Lune ?"
        elseif p<25     then phase = "Premier Croissant ?"
        elseif p==25    then phase = "Premier Quartier ?"
        elseif p<50     then phase = "Gibeuse Croissante ?"
        elseif p==50    then phase = "Pleine Lune  ?"
        elseif p<75     then phase = "Gibeuse Décroissante  ?"
        elseif p==75    then phase = "Dernier Quartier  ?"
        elseif p<100    then phase = "Dernier Croissant  ?"
        end
        -- luminosity
        p = 2*p 
        if p>100 then p = 200-p end
        local txt = "Lever à "..moonrise.."\nCoucher à  "..moonset.."\nPhase : "..phase.."  ("..p.."%)"
        dz.devices(idx).updateText(txt)
    end },
    
    -- Moon Phase (%)
    {idx = 988,  cde = function (dz, idx, v)
        dz.devices(idx).updatePercentage(v.daily[1].moon_phase*100)
    end },
    
    -- Alerts
    --,"alerts":[{"sender_name":"METEO-FRANCE","event":"Moderate thunderstorm warning","start":1680321640,"end":1680386400,"description":"Moderate damages may occur, especially in vulnerable or in exposed areas and to people who carry out weather-related activities.","tags":["Thunderstorm"]}]}	

    {idx = 987, cde = function (dz, idx, v)
        if v.alerts ~= nil then
            local txt = ''
            for k, alert in ipairs(v.alerts) do
                local from  = os.date("%a %d %b à %X", alert['start'])
                local to    = os.date("%a %d %b à %X", alert['end'])
                txt = txt..k..'. '..alert.event.."\n"
                txt = txt..'   du '..from.."\n"
                txt = txt..'   au '..to.."\n"
                txt = txt..alert.description.."\n"
                -- txt = txt..alert.sender_name -- Meteo France
                txt = txt..'  tags : '..table.concat(alert.tags, ', ')..'\n\n'
            end
            -- updateAlertSensor(level, text): Function. Level can be domoticz.ALERTLEVEL_GREY, ALERTLEVEL_GREEN, ALERTLEVEL_YELLOW, ALERTLEVEL_ORANGE, ALERTLEVEL_RED. Supports command options.
            dz.devices(idx).updateAlertSensor(dz.ALERTLEVEL_RED, txt)
            dz.notify('Alerte Météo', txt, dz.PRIORITY_HIGH) -- notify(subject, message, priority, sound) domoticz.PRIORITY_LOW, PRIORITY_MODERATE, PRIORITY_NORMAL, PRIORITY_HIGH, PRIORITY_EMERGENCY
        else
            dz.devices(idx).updateAlertSensor(dz.ALERTLEVEL_GREEN, "Pas d'alerte")
        end 
    end },
]]--
}--==============================================================Fin de déclaration des devices météo =====================================================================


-- LOOP
return {

    active =  true, -- false,
    on = {
        timer           = { "every 5 minutes" },
        httpResponses   = { "OWMcallback" }, -- correspond au caractère générique de rappel
    },

    logging = {   
        level  =   domoticz.LOG_ERROR, domoticz.LOG_INFO, --, domoticz.LOG_DEBUG, domoticz.LOG_MODULE_EXEC_INFO
        marker = '-- '..scriptName..' v'..scriptVersion
    },

    -- LOOP
    execute = function(dz, triggerItem)
        
        
        
        local function errorMessage(message,notify)   -- Ajouter une entrée au journal et notifier à tous les sous-systèmes
            dz.log(message, dz.LOG_ERROR)
            if notify then
                -- dz.notify(message) -- notify(subject, message, priority, sound): Fonction. Envoi d’une notification (Prowl). La priorité sera choisie entre  domoticz.PRIORITY_LOW, PRIORITY_MODERATE, PRIORITY_NORMAL, PRIORITY_HIGH, PRIORITY_EMERGENCY
            end
         end

        -- MAIN
        if triggerItem.isTimer then
            local url = uri
            dz.openURL({
                url     = url,
                method  = "GET",
                callback= 'OWMcallback'
            }).afterSec(1)
        end

        if triggerItem.isHTTPResponse then
            if triggerItem.ok and triggerItem.isJSON then
                local resultsTable = triggerItem.json
                print('reception de weathervisualcrossing')
                if resultsTable ~= nil and resultsTable.currentConditions ~= nil then
                    for k, d in ipairs(StMeteo) do
                        if d['idx'] ~= 0 then --0
                            d.cde(dz, d['idx'], resultsTable) 
                        end
                    end
                end
            else
                errorMessage("Probleme avec la reponse de weathervisualcrossing", false)
            end
        end
    
    end --execute
}
Et voila, je pense qu'il doit avoir des amateurs pour ce type de solution..
Cordialement,
Bernard

Re: [DzVents] Données Météo Weather Visual Crossing

Publié : 10 avr. 2023, 13:01
par Keros
Bonjour BernardC et bienvenu sur le forum :)

Merci pour ton adaptation du script. Je viens néanmoins de le déplacer dans un nouveau sujet puisqu'il ne concerne pas OpenWeatherMap.

Re: [DzVents] Données Météo Weather Visual Crossing

Publié : 14 avr. 2023, 11:28
par Koala45
Bonjour merci bcp pour le script ! :)
Je galère juste avec le baromètre.... il m'affiche uniquement la pression... pourtant j'ai un device temp + hum + baro :( qq un a aussi eu ce problème ?

Re: [DzVents] Données Météo Weather Visual Crossing

Publié : 14 avr. 2023, 23:15
par MAidEN91
Hello,

Merci pour le coup de main, j'ai la meme problématique et je cherche a mettre à jour mon capteur météo.

Est ce que tu pourrais détailler les types de widgets pour chaque variable pour savoir le type exactement ? (baromètre, etc...)

merci !

Re: [DzVents] Données Météo Weather Visual Crossing

Publié : 15 avr. 2023, 08:08
par Keros
Normalement la fonction t'indique le device qu'elle met à jour.

Code : Tout sélectionner

dz.devices(idx).updateTempHumBaro()
Tout le détail est dans la documentation DzVents

Vous avez essayé de rajouter des lignes de débogage pour voir si les 5 infos étaient bien générées correctement ?

Re: [DzVents] Données Météo Weather Visual Crossing

Publié : 15 avr. 2023, 13:50
par MAidEN91
J'ai ca dans les erreurs pour l'instant:

Code : Tout sélectionner

2023-04-15 13:45:06.006 Error: dzVents: Error: (2.5.3) -- weather.visualcrossing v1.1: There is no device with that name or id: Barometre
2023-04-15 13:45:06.006 Error: dzVents: Error: (2.5.3) -- weather.visualcrossing v1.1: An error occurred when calling event handler weathervisualcrossing
2023-04-15 13:45:06.006 Error: dzVents: Error: (2.5.3) -- weather.visualcrossing v1.1: ...moticz/scripts/dzVents/scripts/weathervisualcrossing.lua:52: attempt to index a nil value
Et mes widgets ne se mettent pas à jour.

Non je n'ai pas activé de debug, comment faire?
Merci !

Re: [DzVents] Données Météo Weather Visual Crossing

Publié : 15 avr. 2023, 16:34
par Keros
La ligne d'erreur indique : "There is no device with that name or id: Barometre". Un coup de traduction : "Il n'y a pas d'appareil avec ce nom ou cet identifiant : Baromètre".

Question : Tu as créé un widget avec le nom Barometre ? Ou sinon, il faut remplacer "Barometre" par le nom du widget temp+hum+bar que tu as créé ou son numéro idx.

La dernière ligne d'erreur indique un souci de variable vide ligne 52.

Pour faire du débogage dans les scripts, je t'invite à regarder les liens dans ma signature.

Re: [DzVents] Données Météo Weather Visual Crossing

Publié : 15 avr. 2023, 18:19
par MAidEN91
Oui j'ai bien testé de créer des widgets avec ce nom et les autres noms de capteurs, mais cela ne fonctionne pas. Pour l'idx j'avais compris que ton script se basait sur le nom et non sur le numéro IDX donc peut importe le numéro non?

Re: [DzVents] Données Météo Weather Visual Crossing

Publié : 15 avr. 2023, 18:31
par MAidEN91
J'ai bien certains widget qui se mettent à jours (Visibilite, Pluie, Couverture nuageuse) mais pas Baromètre ni le reste (Vent, UV..)

Baromètre prend une valeur par défaut à la création j'ai l'impression

Re: [DzVents] Données Météo Weather Visual Crossing

Publié : 15 avr. 2023, 21:12
par Keros
Ah, mais ce n'est pas la même chose si plusieurs infos ne sont pas à jour.

C'est peut-être le paramétrage du Json qui ne donne pas les infos souhaitées. Est-ce que tu as vérifié que dans ton Json, tu voyais toutes les infos qui sont récupérées par le script ?