Code : Tout sélectionner
--[[ --[[ ~/home/pi/domoticz/scripts/dzVents/scripts/weathervisualcrossing.lua
author : gso
: modifié pour weathervisualcrossing par BernardC
MAJ : 8/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.2.1'
--[[**********************************************
-- les 2 variables à renseigner
-- suivant utilisateur
--**********************************************]]--
local Localite = 'Le%Mans'
local apiKey = '<votre clé API>'
--**********************************************
--**********************************************
-- MAJ le 8/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
}