Netatmo
Publié : 01 mai 2020, 15:19
Bonjour,
Je propose ce petit script à ceux qui possèdent un équipement Netatmo et qui voudraient récupérer les données des stations météo Netatmo.
Tout d'abord, il faut s’inscrire sur leur site pour créer une application.
On récupère alors les identifiants nécessaires à la connexion:
Le script ci-après va lire les données des stations météo Netatmo comprises dans un carré définit par les coordonnées
de ses angles opposés en latitude et longitude.
Je propose ce petit script à ceux qui possèdent un équipement Netatmo et qui voudraient récupérer les données des stations météo Netatmo.
Tout d'abord, il faut s’inscrire sur leur site pour créer une application.
On récupère alors les identifiants nécessaires à la connexion:
- L'identifiant du client: client_id
- La clé secrète: client_secret
Code : Tout sélectionner
--[[
Developpé par Didier3164, version du 20/05/2020
--]]
------------------------------------------------------------------------
-- ELEMENTS D'AUTHENTIFICATION
------------------------------------------------------------------------
local client_id = 'xxxxxxxxxxxxxxxxxxxxxx'
local client_secret = 'xxxxxxxxxxxxxxxxxxxxxx'
local username = 'xxxxxxxxxx@xxxxxx.com'
local password = '################'
local scope = 'read_thermostat write_thermostat read_station read_camera'
------------------------------------------------------------------------
--[[
Les données d'authentification sont stoquées dans des variables partagées accessibles par d'autre scripts
dz.globalData.refresh_token = refresh_token
dz.globalData.access_token = access_token
--]]
return {
active = true,
logging = {
-- level = domoticz.LOG_DEBUG, -- Seulement un niveau peut être actif; commenter les autres
-- level = domoticz.LOG_INFO,
-- level = domoticz.LOG_ERROR,
-- level = domoticz.LOG_DEBUG,
-- level = domoticz.LOG_MODULE_EXEC_INFO,
marker = 'Netatmo Token'
},
on = {
httpResponses = {'Netatmo_getToken'},
system = {'start'}
},
execute = function(dz, item)
if item.isSystemEvent then
-- Initialisation du token
dz.openURL({
url = 'https://api.netatmo.com/oauth2/token',
method = 'POST',
callback = 'Netatmo_getToken',
headers = { ['Content-Type']='application/x-www-form-urlencoded' },
postData = 'grant_type=password&username='..username
..'&password='..password
..'&client_id='..client_id
..'&client_secret='..client_secret
..'&scope='..scope
})
elseif item.isHTTPResponse then
if item.ok then
if item.isJSON then
if item.callback == 'Netatmo_getToken' then
dz.globalData.refresh_token = item.json.refresh_token
dz.globalData.access_token = item.json.access_token
local Time = require('Time')
local currentTime = Time()
local expireTime = dz.time.addSeconds(item.json.expires_in)
-- Refresh du token
dz.openURL({
url = 'https://api.netatmo.com/oauth2/token',
method = 'POST',
callback = 'Netatmo_getToken',
headers = { ['Content-Type']='application/x-www-form-urlencoded' },
postData = 'grant_type=refresh_token&refresh_token='..dz.globalData.refresh_token
..'&client_id='..client_id
..'&client_secret='..client_secret
}).afterSec(item.json.expire_in)
end
end
end
end
end
}
de ses angles opposés en latitude et longitude.
Code : Tout sélectionner
--[[
Developpé par Didier3164, version du 01/05/2020
La latitude et la longitude doivent avoir été saisies dans les paramètres de Domoticz et les dispositifs créés
--]]
local meteo_idx = 1 -- Température Humidité Pression
local vent_idx = 2 -- Vent
local pluie_idx = 3 -- précipitation
return {
active = true,
logging = {
-- level = domoticz.LOG_DEBUG, -- Seulement un niveau peut être actif; commenter les autres
-- level = domoticz.LOG_INFO,
-- level = domoticz.LOG_ERROR,
-- level = domoticz.LOG_DEBUG,
-- level = domoticz.LOG_MODULE_EXEC_INFO,
marker = 'Météo Netatmo'
},
on = {
timer = { 'every 10 minutes' },
httpResponses = { 'meteoNetatmo' }
},
data = {
dist = { initial = 0 }
},
execute = function(dz, item)
if (item.isTimer) then
dz.data.dist = 0
-- Lecture des températures extérieures
-- lat_ne, lon_ne, lat_sw, lon_sw définissent les coordonneés (ne: Nord-Est, sw: Sud-Ouest) du carré englobant les stations à lire
dz.openURL({url = 'https://api.netatmo.com/api/getpublicdata',
method = 'POST',
callback = 'meteoNetatmo',
postData = {
access_token = dz.globalData.access_token,
lat_ne = 43.673631,
lon_ne = 1.39071,
lat_sw = 43.625647,
lon_sw = 1.36653,
filter = true
}
})
end
if (item.isHTTPResponse) then
if (item.ok) then
if (item.isJSON) then
if (item.json.body.errors == nil) then
if (item.callback == 'meteoNetatmo') then
local mesures = {}
local nbr_mesures = {}
for stationId,station in pairs(item.json.body) do
for measureId,measure in pairs(station.measures) do
if measure.type ~= nil then
for resId,res in pairs(measure.res) do
for i,valeur in pairs(res) do
if mesures[measure.type[i]] == nil then
mesures[measure.type[i]] = 0
nbr_mesures[measure.type[i]] = 0
end
mesures[measure.type[i]] = mesures[measure.type[i]] + valeur
nbr_mesures[measure.type[i]] = nbr_mesures[measure.type[i]] + 1
end
end
end
if measure.rain_timeutc ~= nil then
dz.log('Données pluie: '..measure.rain_live, dz.LOG_INFO)
--rain_60min, rain_24h, rain_live
if mesures['rain_60min'] == nil then
--Initialisation du tableau
mesures['rain_60min'] = 0
nbr_mesures['rain_60min'] = 0
mesures['rain_24h'] = 0
nbr_mesures['rain_24h'] = 0
mesures['rain_live'] = 0
nbr_mesures['rain_live'] = 0
end
if measure.rain_60min >= 0 then
mesures['rain_60min'] = mesures['rain_60min'] + measure.rain_60min
nbr_mesures['rain_60min'] = nbr_mesures['rain_60min'] + 1
end
if measure.rain_24h == nil then measure.rain_24h = 0 end
if measure.rain_24h >= 0 then
mesures['rain_24h'] = mesures['rain_24h'] + measure.rain_24h
nbr_mesures['rain_24h'] = nbr_mesures['rain_24h'] + 1
end
if measure.rain_live == nil then measure.rain_live = 0 end
if measure.rain_live >= 0 then
mesures['rain_live'] = mesures['rain_live'] + measure.rain_live
nbr_mesures['rain_live'] = nbr_mesures['rain_live'] + 1
end
end
if measure.wind_timeutc ~= nil then
-- Latitude: station.place.location[1]
-- Longitude: station.place.location[2]
x = (station.place.location[2] - dz.settings.location.longitude) * math.cos((station.place.location[1] + dz.settings.location.latitude)/2)
y = station.place.location[1] - dz.settings.location.latitude
distance = 1.852 * 60 * math.sqrt(x^2 + y^2)
if dz.data.dist == 0 then dz.data.dist = distance end
if distance <= dz.data.dist then
-- Station la plus proche
dz.data.dist = distance
mesures['wind_strength'] = measure.wind_strength
mesures['wind_angle'] = measure.wind_angle
mesures['gust_strength'] = measure.gust_strength
mesures['gust_angle'] = measure.gust_angle
end
end
end
end
local meteoPluie = 0
if nbr_mesures['rain_live'] ~= nil then
dz.globalData.meteoPluie = mesures['rain_live'] / nbr_mesures['rain_live']
local rate = mesures['rain_60min'] / nbr_mesures['rain_60min']
dz.devices(pluie_idx).updateRain(rate, meteoPluie)
else
dz.log('Aucune donnée de pluie.', dz.LOG_INFO)
end
local meteoTemp = 0
if nbr_mesures['temperature'] ~= nil then
meteoTemp = mesures['temperature'] / nbr_mesures['temperature']
else
dz.log('Aucune donnée de température.', dz.LOG_INFO)
end
local meteoPression = 0
if nbr_mesures['pressure'] ~= nil then
meteoPression = mesures['pressure'] / nbr_mesures['pressure']
else
dz.log('Aucune donnée de pression.', dz.LOG_INFO)
end
local meteoHumid = 0
if nbr_mesures['humidity'] ~= nil then
meteoHumid = mesures['humidity'] / nbr_mesures['humidity']
else
dz.log("Aucune donnée d'humidite.", dz.LOG_INFO)
end
if mesures['wind_strength'] ~= nil then
local speed = mesures['wind_strength']
local bearing = mesures['wind_angle']
local gust = mesures['gust_strength']
local Sector = {"N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW","N"}
local direction = Sector[dz.utils.round((bearing%360)/ 22.5,0)+1]
dz.devices(vent_idx).updateWind(dz.utils.round(bearing,0), direction, speed, gust, dz.utils.round(meteoTemp,1), chill)
end
dz.devices(meteo_idx).updateTempHumBaro(dz.utils.round(meteoTemp,1), dz.utils.round(meteoHumid,1),0, dz.utils.round(meteoPression,0), dz.BARO_NOINFO)
end
end
end
end
end
end
}