When I see what you have achieved guys, I feel a bit lazy since VP Pro 2 delivers updated values every minutes and computes the accumulated month value. I ran Meteohub for more than 10 years and I just transitionned to Meteobridge Nano HD
, which is a terrific module. Thanks to the template functionnality
it is straightforward to get the desired values every minutes with a dzVents script. I just remembered that Custom sensor is at our disposal. I grabbed an icon on the Web, resized it and imported it in domoticz (pretty tricky process). Here is the result.
Basically here is my dzVents script to grab various meteo value, either directly from VP2 or thanks to wunderground API. Some code is deprecated I haven't removed yet. I wish Domitcz tick is one second instead of one minute in order to get gust value every, say, 5 seconds. This is achievable either with cron or the new emitEvent command. I may give a try some day.
I take this opportunity to thank waaren who is always reacting promptly to questions and give good advices.
Code: Select all
return {
active = true, -- optional
on = {
timer = {'every minute'},
httpResponses = {'wundergroundResponse', 'wundergroundResponseForecast1', 'wundergroundResponseForecast2', 'localMeteoResponse'}
},
-- logging = {
-- level = domoticz.LOG_INFO,
-- marker = "meteo script"
-- },
data = {
loop = { initial = 0 },
wheatherForecast1 = { initial = 'noinfo'},
wheatherForecast2 = { initial = 'noinfo'}
},
execute = function (dz, item)
local forecastNarrative
local daypartName
local _u = dz.utils
local _h = dz.helpers
local _d = dz.data
local _ = dz.utils._
-- best match with wunderground forecast unfortunately domoticz is way beyond wunderground capabilities
-- see https://docs.google.com/document/d/1eKCnKXI9xnoMGRRzOL1xPCBihNV2rOet08qpE_gArAY/edit
local wheatherForecastTHB = {
[0] = dz.BARO_CLOUDY,
[1] = dz.BARO_CLOUDY,
[2] = dz.BARO_CLOUDY,
[3] = dz.BARO_RAIN,
[4] = dz.BARO_RAIN,
[5] = dz.BARO_RAIN,
[6] = dz.BARO_RAIN,
[7] = dz.BARO_RAIN,
[8] = dz.BARO_RAIN,
[9] = dz.BARO_RAIN,
[10] = dz.BARO_RAIN,
[11] = dz.BARO_RAIN,
[12] = dz.BARO_RAIN,
[13] = dz.BARO_RAIN,
[14] = dz.BARO_RAIN,
[15] = dz.BARO_RAIN,
[16] = dz.BARO_RAIN,
[17] = dz.BARO_RAIN,
[18] = dz.BARO_RAIN,
[19] = dz.BARO_CLOUDY,
[20] = dz.BARO_CLOUDY,
[21] = dz.BARO_CLOUDY,
[22] = dz.BARO_CLOUDY,
[23] = dz.BARO_CLOUDY,
[24] = dz.BARO_CLOUDY,
[25] = dz.BARO_CLOUDY,
[26] = dz.BARO_CLOUDY,
[27] = dz.BARO_CLOUDY, -- shoud be BARO_PARTLY_CLOUDY (value not yey supported in this domoticz version?)
[28] = dz.BARO_CLOUDY, -- shoud be BARO_PARTLY_CLOUDY
[29] = dz.BARO_CLOUDY, -- shoud be BARO_PARTLY_CLOUDY
[30] = dz.BARO_CLOUDY, -- shoud be BARO_PARTLY_CLOUDY
[31] = dz.BARO_SUNNY,
[32] = dz.BARO_SUNNY,
[33] = dz.BARO_SUNNY,
[34] = dz.BARO_SUNNY,
[35] = dz.BARO_RAIN,
[36] = dz.BARO_SUNNY,
[37] = dz.BARO_RAIN,
[38] = dz.BARO_RAIN,
[39] = dz.BARO_RAIN,
[40] = dz.BARO_RAIN,
[41] = dz.BARO_RAIN,
[42] = dz.BARO_RAIN,
[43] = dz.BARO_RAIN,
[44] = dz.BARO_NOINFO,
[45] = dz.BARO_RAIN,
[46] = dz.BARO_RAIN,
[47] = dz.BARO_RAIN,
}
-- "fc" reports the station's weather forecast (0 = rainy, 1 = cloudy, 2 = some clouds, 3 = sunny, 4 = snowy, 5 = clouds at night, 6 = clear night)
-- domoticz BARO_CLOUDY, BARO_CLOUDY_RAIN, BARO_STABLE, BARO_SUNNY, BARO_THUNDERSTORM, BARO_NOINFO, BARO_UNSTABLE
local fc = {
["0"] = dz.BARO_CLOUDY_RAIN,
["1"] = dz.BARO_CLOUDY,
["2"] = dz.BARO_CLOUDY,
["3"] = dz.BARO_SUNNY,
["4"] = dz.BARO_CLOUDY_RAIN,
["5"] = dz.BARO_CLOUDY,
["6"] = dz.BARO_STABLE,
}
-- 0 = No info, 1 = Sunny, 2 = Partly cloudy, 3 = Cloudy, 4 = Rain
local wheaterForecastJSON = {
[dz.BARO_CLOUDY] = 3,
[dz.BARO_RAIN] = 4,
[dz.BARO_SUNNY] = 2,
[dz.BARO_NOINFO] = 0,
-- [dz.BARO_PARTLY_CLOUDY] = 1,
}
local forecastHomeIDX = {
[1] = 359,
[2] = 355,
[3] = 357,
[4] = 399,
[5] = 401,
[6] = 402,
[7] = 404,
[8] = 405,
[9] = 406,
[10] = 407,
}
local forecastSeaIDX = {
[1] = 356,
[2] = 358,
[3] = 400,
[4] = 403,
}
local meteohubIP = '192.168.21.100'
if (item.isTimer) then
local apiKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
dz.data.loop = dz.data.loop + 1
dz.log ('loop = ' .. dz.data.loop)
if dz.data.loop % 20 == 0 then -- call this station once every 20 minutes
local station = 'IPAYSDEL120' -- Ile d'Yeu
local wunderURL = 'https://api.weather.com/v2/pws/observations/current?stationId=' .. station .. '&format=json&units=m&numericPrecision=decimal&apiKey=' .. apiKey
dz.openURL({
url = wunderURL,
callback = 'wundergroundResponse'
})
end
if dz.data.loop %1 == 0 then
-- localMeteo = "http://" .. meteohubIP .. "/meteohtml.cgi?file=domoticz-template"
localMeteo = "http://" .. _h.meteobridgeUser .. ":" .. _h.meteobridgePass .. "@" .. _h.meteobridgeIP .."/cgi-bin/template.cgi?templatefile=domoticz.html"
-- dz.log (localMeteo)
dz.openURL({
url = localMeteo,
callback = 'localMeteoResponse'
})
end
dz.log ('loop number : ' .. tostring(dz.data.loop))
dz.log('dzVents version - '..dz.settings.dzVentsVersion)
if dz.data.loop >= 180 then -- was 60
dz.log ('calling forecast')
dz.data.loop = 0
wunderURL = 'https://api.weather.com/v3/wx/forecast/daily/5day?geocode=47.097,1.966&language=fr-FR&format=json&units=m&apiKey=' .. apiKey
dz.openURL({
url = wunderURL,
callback = 'wundergroundResponseForecast1'
})
-- wunderURL = 'https://api.weather.com/v3/wx/forecast/daily/5day?geocode=46.721,-2.347&language=fr-FR&format=json&units=m&numericPrecision=decimal&apiKey=' .. apiKey
wunderURL = 'https://api.weather.com/v3/wx/forecast/daily/5day?geocode=46.721,-2.347&language=fr-FR&format=json&units=m&apiKey=' .. apiKey
dz.openURL({
url = wunderURL,
callback = 'wundergroundResponseForecast2'
})
end
end
if (item.isHTTPResponse) then
if (item.ok) then
if item.trigger == 'wundergroundResponse' then
if item.json.observations[1].stationID == 'IPAYSDEL120' then
temp = item.json.observations[1].metric.temp
humidity = item.json.observations[1].humidity
pressure = item.json.observations[1].metric.pressure
wheatherForecast = wheaterForecastJSON[dz.data.wheatherForecast2]
local humStatus = dz.helpers.humidityStatus(dz, humidity)
dz.devices(334).updateTempHumBaro(temp,humidity,humStatus,pressure,dz.data.wheatherForecast2)
end
elseif item.trigger == 'wundergroundResponseForecast1' then
-- get icon code in order to retrieve forecast
icon = item.json.daypart[1]['iconCode'][2]
-- save forecast in a persistent variable. Device will be updated next round
dz.data.wheatherForecast1 = wheatherForecastTHB[icon]
for k, v in pairs(forecastHomeIDX) do
forecastNarrative = item.json.daypart[1]['narrative'][k]
if forecastNarrative == nil then forecastNarrative = '--' end
daypartName = item.json.daypart[1]['daypartName'][k]
if daypartName == nil then daypartName = '--' end
dz.devices(forecastHomeIDX[k]).rename("Chez nous - " .. daypartName)
dz.devices(forecastHomeIDX[k]).updateText(forecastNarrative)
end
elseif item.trigger == 'wundergroundResponseForecast2' then
-- get icon code in order to retrieve forecast
local icon = item.json.daypart[1]['iconCode'][2]
-- save forecast in a persistent variable. Device will be updated next round
dz.data.wheatherForecast2 = wheatherForecastTHB[icon]
for k, v in pairs(forecastSeaIDX) do
forecastNarrative = item.json.daypart[1]['narrative'][k]
if forecastNarrative == nil then forecastNarrative = '--' end
daypartName = item.json.daypart[1]['daypartName'][k]
if daypartName == nil then daypartName = '--' end
dz.devices(forecastSeaIDX[k]).rename("Ile d'Yeu - " .. daypartName)
dz.devices(forecastSeaIDX[k]).updateText(forecastNarrative)
end
elseif item.trigger == 'localMeteoResponse' then
local body = item.data:match('%b{}') -- extract part of item.data that is between {} ( including the outer {} )
local rt = dz.utils.fromJSON(body) -- convert the json string to rt ( Lua table )
-- dz.utils.dumpTable(rt) -- dump the contents of the table in your log
dz.log ('wheatherForecast1 -- ' .. dz.data.wheatherForecast1)
dz.log ('wheatherForecast2 -- ' .. wheaterForecastJSON[dz.data.wheatherForecast2])
local temp = tonumber(rt.realtime.temperature)
local windChill = tonumber(rt.realtime.temperature_au_vent)
local solarRadiation = tonumber(rt.ensoleillement.radiations_solaires_wlk)
local evapotranspirationDay = tonumber(rt.ensoleillement.evapotranspirationDay)
local evapotranspirationMonth = tonumber(rt.ensoleillement.evapotranspirationMonth)
local humidity = tonumber(rt.realtime.humidite)
local pressure = tonumber(rt.realtime.pression)
local pressureSea = tonumber(rt.realtime.pression_mer)
local precipRate = tonumber(rt.realtime.pluie_intensite)
local precipTotal = tonumber(rt.realtime.pluie_actu)
local windBearing = tonumber(rt.realtime.vent_dir_moy)
local windDirection = rt.realtime.vent_dir_txt
local dateReleve = rt.realtime.date_releve_local
local heureReleve = rt.realtime.heure_releve_local
local windSpeed = tonumber(rt.realtime.vent)
local windGust = tonumber(rt.realtime.vent_rafales)
local windGust15m = tonumber(rt.realtime.vent_rafales_15minutes)
local windGust60m = tonumber(rt.realtime.vent_rafales_60minutes)
local windGustH = tonumber(rt.realtime.vent_rafales_heure)
local windGustD = tonumber(rt.realtime.vent_rafales_jour)
local forecast = tonumber(rt.realtime.prevision)
-- local wheatherForecast = fc[(forecast)]
local wheatherForecastText = rt.realtime.previsionText
local windGust24h = tonumber(rt.historical.vent_rafales_24heures)
local windGustM = tonumber(rt.historical.vent_rafales_mois)
local windGustY = tonumber(rt.historical.vent_rafales_annee)
local windGustRecord = tonumber(rt.historical.vent_rafales_record)
local windGustRecordDate = tonumber(rt.historical.vent_rafales_record_date)
local ageOfData = tonumber(rt.realtime.ageOfData)
local ageOfData = tonumber(rt.realtime.ageOfData)
dz.log ('Ancienneté des données : ' .. tostring(ageOfData))
if ageOfData < 10 then
dz.devices(427).updateAlertSensor(dz.ALERTLEVEL_GREEN, "Fonctionnement normal")
else
dz.devices(427).updateAlertSensor(dz.ALERTLEVEL_RED, "Temps de réponse > 10 secondes")
end
-- to be finalized
local wheatherForecast
if _h.vantageFC[forecast].fr ~= "" then
wheatherForecast = _h.vantageFC[forecast].fr
else
wheatherForecast = _h.vantageFC[forecast].en
end
local humStatus = dz.helpers.humidityStatus(dz, humidity)
dz.devices(414).updateRain(precipRate*100,precipTotal)
dz.devices(415).updateTempHumBaro(temp,humidity,humidityStatus,pressureSea,wheatherForecast)
dz.devices(416).updateRadiation(solarRadiation)
dz.devices(432).updateCustomSensor(evapotranspirationDay)
dz.devices(433).updateCustomSensor(evapotranspirationMonth)
dz.devices(417).updateWind(windBearing,windDirection,windSpeed,windGust,temp,windChill)
if dz.data.loop % 60 == 0 then dz.devices(426).updateText(wheatherForecastText) end
end
end
end
end
}