Après pas mal de galères, j'ai enfin réussi à avoir quelque chose de fonctionnel.
J'explique un peu mes galères si ça peut en aider d'autres :
Chez moi je tourne sur un raspberry avec lequel je partage la connexion de mon smartphone.
Le raspberry me sert de box domotique et de box internet avec un switch branché derrière et quelques répéteurs wifi, cela me suffit amplement pour mes besoin.
Hier en testant j'ai eu quelques problèmes qui faisaient de gros freezes sur mon réseau, donc j'ai vachement galéré avec les histoire de bon et mauvais liens du json de l'API expliqués tout au long des post de ce sujet, finalement j'ai abandonné.
Ce matin j'ai fait une grosse analyse du pc (malwarebyte, antivirus, spybot, Ccleaner), tout s'est bien passé à part quelques erreurs de base de registre et finalement ça s'est mis à fonctionner. Donc est-ce L'API ou chez moi je sais pas, mais ça fonctionne.
Ensuite comme écrit dans le script, j'ai modifié les noms des devices en mettant les idx mais ça n'a pas fonctionné du tout, donc il faut laisser les noms de devices.
Puis la fonction lectProb posait problème en mettant des messages d'erreur, je l'ai désactivé, puis à la fin supprimé car j'avais trouvé d'autre choses qui m'allaient.
J'ai modifier un peu en prenant du code par ci par là de chacun, et j'ai enfin réussi à faire quelque chose qui fonctionne.
Autre petite modif, le script met à jour les données tout les 15 minutes (d'origine c'est 5mn), ce qui est largement suffisant pour la météo.
Code : Tout sélectionner
--[[
Dans mon cas j'utilise un raspberry pi 3, mais domoticz est installable sur d'autres matériels comme des systèmes android, nas synology ou autres... Donc l'emplacement du fichier peut varier selon la distrib(version de du système d'exploitation sous linux).
Attention il faudra changer user par votre nom d'utilisateur.(pi d'origine sur un raspberry, sauf si vous l'avez modifié.)
il faut le placer dans : /home/user/domoticz/scripts/dzVents/scripts/weathervisualcrossing.lua
Donc avec le user d'origine qui s'appelle pi : /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, /!\ les deux variables à renseigner vont être inséré dans une adresse url,
-- donc il faut remplacer tout les caractères spéciaux par leur équivalent web, évitez tout ce qui a des accente etc : exemple : un espace sera remplacé par %20
-- Comme vous pouvez voir dans mon cas j'ai testé : "ANZIN 59410 France"
--****************************************************************************************************************************************************************************************
local Localite = 'ANZIN%2059410%20France' --Remplacez ANZIN%2059410%20France par Votre ville Code postal, etc et laissez bien les %20 car ce sont des espace en Url UTF-8.
local apiKey = 'Clé_de_l_API' --Remplacez Clé_de_l_API par Votre clé de l'API.
local uri = 'https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/'..Localite..'?unitGroup=metric&include=days%2Ccurrent%2Chours&key='..apiKey..'&contentType=json'
local prefix = 'WVC'
--=================================================================================================================================================================
-- FONCTIONS
--=================================================================================================================================================================
--============================================Températures ====================================================
local function lectTemp(duree,v)
local Time = require('Time')
local now = Time()
local Heure = now.hour+1 -- heure de debut + 1 pour index
local J = 1 --init jour
H=Heure + duree
if H > 23 then
J = math.floor(H/24)+1
H = math.fmod(H,24)
end
Temp= v.days[J].hours[H].temp
return (Temp)
end
--============================================Probabilité Pluie====================================================
local function lectPluie(duree,v)
local Time = require('Time')
local now = Time()
local Heure = now.hour+1 -- heure de debut + 1 pour index
local J = 1 --init jour
H=Heure + duree
if H > 23 then
J = math.floor(H/24)+1
H = math.fmod(H,24)
end
Pluie= v.days[J].hours[H].precipprob
return (Pluie)
end
--=================================================================================================================================================================
--= /!\ ATTENTION : surtout ne pas mettre les devices idx mais mettre les noms des devices.
--= Par exemple, le premier capteur juste en dessous a le nom : "Barometre" et il est de type TempHumBarro (Température+Humidité+Baromètre).
--=
--= Le script a été modifié à l'origine par BernardC pour fonctionner avec les devices de Darksky.
--=
--=
--=
--= Si vous n'avez pas installé le matériel Darksky,
--= Vous pouvez simplement créer de nouveaux capteurs virtuels en respectant le nom du capteur et le type de capteur.
--= Pour créer ce device : Configuration --> Matériel --> Créer un capteur virtuel --> Le nom et le type.
--= Si vous ne trouver pas de bouton : "Créer un capteur virtuel", il faudra créer un matériel "Dummy".
--= Pour celà :
--= Configuration --> Matériel --> Sous le tableau --> Nom : Météo --> Type:Dummy (Does nothing, use for virtual switches only) --> Délai d'inactivité: Désactivé --> Ajouter
--=
--=
--=================================================================================================================================================================
local StMeteo = {
--Barométre sensor de type TempHumBarro.
{idx = 'Barometre', cde = function (dz, idx, v) --idx665
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)
end },
-- UV sensor de type UV.
{idx = 'UV', cde = function (dz, idx, v) dz.devices(idx).updateUV(v.currentConditions.uvindex) end }, --idx667
-- Couverture nuageuse ajout d'un capteur virtuel "Poucentage"
{idx = 'Couverture nuageuse', cde = function (dz, idx, v) dz.devices(idx).updatePercentage(v.currentConditions.cloudcover) end },
-- Visibilité sensor de type Visibility
{idx = 'Visibilite', cde = function (dz, idx, v) dz.devices(idx).updateVisibility(v.currentConditions.visibility) end },
--{idx = '669', cde = function (dz, idx, v) dz.devices(idx).updateVisibility(v.currentConditions.visibility) end },
-- Pluie sensor de type Rain
{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 sensor de type Wind.
{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² sensor de type "rayonnement solaire"
{idx = 'Soleil', cde = function (dz, idx, v) dz.devices(idx).updateRadiation(v.currentConditions.solarradiation) end },
--Temp dans 1 H sensor de type Temperature.
{idx = 'Temp dans 1H', cde = function (dz, idx, v) dz.devices(idx).updateTemperature(lectTemp(1,v)) end },
--Temp dans 2 H sensor de type Temperature.
{idx = 'Temp dans 2H', cde = function (dz, idx, v) dz.devices(idx).updateTemperature(lectTemp(2,v)) end },
--Temp dans 3 H sensor de type Temperature.
{idx = 'Temp dans 3H', cde = function (dz, idx, v) dz.devices(idx).updateTemperature(lectTemp(3,v)) end },
--Proba Pluie 1 H sensor de type "Poucentage".
{idx = 'Pluie dans 1H', cde = function (dz, idx, v) dz.devices(idx).updatePercentage(lectPluie(1,v)) end },
--Proba Pluie 2 H sensor de type "Poucentage".
{idx = 'Pluie dans 2H', cde = function (dz, idx, v) dz.devices(idx).updatePercentage(lectPluie(2,v)) end },
--Proba Pluie 3 H sensor de type "Poucentage".
{idx = 'Pluie dans 3H', cde = function (dz, idx, v) dz.devices(idx).updatePercentage(lectPluie(3,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 15 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
}Certains devices sont en double avec le même idx (créé par darksky), je les ai laissé volontairement car je suis en phase de test donc je préfère tout voir.
La raison de mon post :
D'ailleurs, si quelqu'un sait comment regrouper les autres capteurs dans la partie météo, je suis preneur, parce que là c'est pas top d'avoir tout de dispersé comme ça.
Je viens de voir qu'il y a un problème sur le device : "Pluie", c'est pas encore la mousson dans le nord de la france.
Je vais attendre un peu de temps avant de chercher à régler ça, comme j'ai utilisé l'Api avec le lien métrique et nom métrique, ça va peut être se régler tout seul.
A+++.