Aemet is a bit funny about their API. You have to access it using one URL in order to get another URL where the data is found. Most of the time (I think always) that second URL is the same, but you need to access it in order to 'activate' the data.
Second thing is: they have their headers wrong, instead as reporting as JSON the header says text/plain.
For that reason we need to user the dzvents Util fromJSON.
Requirements:
[*]dzVents > 2.4.0
[*]some sensors, they are explained in the code
[*]an API key from AEMET
[*]the identifier for the beach you want data for.
The descriptions (for wind, waves, feel temperature and sky) are returned in Spanish. If you want you can replace them in the script.
As a helping hand (if someone feels like translating):
Viento = wind. Possible values are flojo(weak),moderado(moderate/medium), fuerte(strong)
Cielo = Sky. Possible responses are despejado(clear), nuboso(cloudy), muy nuboso(very cloudy), chubascos(showers, the natural ones, not a beach shower), muy nuboso con lluvia(very cloudy with rain)
Oleaje = surf/waves. Responses can be: débil(weak), moderado(moderate, duh), fuerte(strong)
Sensación termica = feel temperature. Possible results are: muy frío(very cold, never seen that one), frío(cold), muy fresco(very chilly), fresco(chilly), suave(soft), calor agradable(enjoyably warm), calor moderado(moderate heat), calor fuerte(Hot!)
Code: Select all
--[[
You will need an API key, you can get it here for free: https://opendata.aemet.es/centrodedescargas/altaUsuario
To get the data for your selected beach you need its identifier. Go to http://www.aemet.es/es/eltiempo/prediccion/playas and
find the beach of your choice. Either on the map, in the selector or by name. Keep clicking until you are taken to the page with the results
for that beach. Look at the URL and get the digits at the end as identifier:
http://www.aemet.es/es/eltiempo/prediccion/playas/BEACHNAME-xxxxxx xxxxxx is the code for the beach
--]]
return {
on = {
timer = { 'at *:43', 'at *:24' },
httpResponses = { 'aemeturl', 'aemetInfo' } -- matches callback string below
},
data = {
alink = { initial = 0 }
},
execute = function(domoticz, triggerItem)
local miplaya = 'xxxxxx'
local miApi = 'YOURAPIKEY'
local posti = domoticz.devices('AguaPostiguet') -- Sensor for the water temperature. Virtual temperature sensor
local prevposti = tonumber(posti.temperature)
local waves = domoticz.devices('Oleaje') --wave sensor (intensity of the waves). text sensor
local prevwaves = tostring(waves.text)
local Cielo = domoticz.devices('Cielo') --cloud sensor (percentage), descriptive. Virtual text sensor
local prevCielo = tostring(Cielo.text)
local viento = domoticz.devices('Viento') --Wind description. text sensor
local prevviento = tostring(viento.text)
local sTermica = domoticz.devices('SensationTermica') -- Feel temperature descripcion. text sensor
local prevsTermica = tostring(sTermica.text)
if (triggerItem.isTimer) then
local miplaya = 'xxxxxx'
local miApi = 'YOURAPIKEY'
local geturl = 'https://opendata.aemet.es/opendata/api/prediccion/especifica/playa/'..miplaya..'/?api_key='..miApi..'&'
if (triggerItem.isTimer) then
domoticz.openURL({
url = geturl,
method = 'GET',
callback = 'aemeturl'
})
elseif (triggerItem.isHTTPResponse) and (triggerItem.callback == 'aemeturl') then --fetching the link
local response = triggerItem
local json = domoticz.utils.fromJSON(response.data)
if (response.ok) then
local Aemetlink = tostring(json.datos)
domoticz.openURL({
url = Aemetlink,
method = 'GET',
callback = 'aemetInfo'
})
else
print('**aemeturl failed to fetch info')
end
elseif (triggerItem.isHTTPResponse) and (triggerItem.callback == 'aemetInfo') then --check aquired link and get data
local response = triggerItem
if (response.ok) then
local json = domoticz.utils.fromJSON(response.data)
local tagua = domoticz.utils.round((tonumber(json[1].prediccion.dia[1].tagua.valor1)),1) --getting the temperature of the water
if tagua ~= nil and prevposti ~= tagua then --we will only update the sensor if a valid number is returned AND it is not the same as the previous value
posti.updateTemperature(tagua)
end
local wave = tostring(json[1].prediccion.dia[1].oleaje.descripcion2) --getting the state of the waves
wave = tostring(wave):gsub("?","é")
wave = string.gsub(" "..wave, "%W%l", string.upper):sub(2) --filter out 'funny' characters and capitalize the string
if wave ~= nil and prevwaves ~= wave then
waves.updateText(wave)
end
local estadoCielo = tostring(json[1].prediccion.dia[1].estadoCielo.descripcion1) --getting the state of the sky
estadoCielo = string.gsub(" "..estadoCielo, "%W%l", string.upper):sub(2)
if estadoCielo ~= nil and prevCielo ~= estadoCielo then
Cielo.updateText(estadoCielo)
end
local termica = tostring(json[1].prediccion.dia[1].stermica.descripcion1) ----getting the feel temperature
local termica = string.gsub(" "..termica, "%W%l", string.upper):sub(2)
if termica ~= nil and prevsTermica ~= termica then
sTermica.updateText(termica)
end
local vient = tostring(json[1].prediccion.dia[1].viento.descripcion1) -- --getting the state of the wind
vient = string.gsub(" "..vient, "%W%l", string.upper):sub(2)
if vient ~= nil and prevviento ~= vient then
viento.updateText(vient)
end
else
print('**aemetinfo failed to fetch info')
end
end
end
}