Due to time constraints I must plan in advance.
So I suggested DeepSeek to write me a script with a 10 day forecast.
To prepare:
- get yourself a key for the API at meteoserver.nl
- Make a dummy device type TEXT and name it 'Er op uit'
- change the script according to where you live (my_home_town) and replace the abcdef1234 with you API key
That's all.
Code: Select all
--[[
ErOpUit Weather Display Script
Fetches weather forecast from Meteoserver.nl API and displays in Domoticz text sensor
API Information:
- Source: Meteoserver.nl (https://www.meteoserver.nl)
- Free plan: 500 calls per month
- API documentation: https://www.meteoserver.nl/API.html
Weather data fields explanation:
-- dag → forecast date (dd-mm-yyyy)
-- avg_temp → average temperature (°C)
-- min_temp → minimum temperature (°C)
-- max_temp → maximum temperature (°C)
-- windr → wind direction in degrees (0 = North, 90 = East, 180 = South, 270 = West)
-- windrltr → wind direction in letters (N, E, S, W)
-- winds → wind speed (Beaufort scale)
-- windb → wind force (Beaufort, rounded)
-- windkmh → wind speed in kilometers per hour (km/h)
-- windknp → wind speed in knots (knots)
-- tot_neersl → total precipitation in millimeters (mm)
-- neersl_perc_dag → chance of precipitation during the day (%)
-- tot_zond → total sunshine duration in minutes
-- zond_perc_dag → percentage of the day with sunshine (%)
-- sup → sunrise (hour:minute)
-- sunder → sunset (hour:minute)
-- toestand → general weather condition (e.g., rain, cloudy, sunny)
Display format for each day:
DD-MM 🌫️ ☀️ 🌦️ 😊 10-15-20°C
Where:
- DD-MM: Date (day-month)
- 🌫️: Wind indicator (🌫️=calm, 🍃=light, 🌬️=moderate, 💨=strong, 🌪️=stormy)
- ☀️: Cloud cover (☀️=sunny, 🌤️=mostly sunny, ⛅=partly cloudy, 🌥️=cloudy, ☁️=overcast)
- 🌦️: Precipitation (☀️=dry, 🌤️=light clouds, ⛅=cloudy, 🌦️=light rain, 🌧️=rain, ⛈️=heavy rain/thunder)
- 😊: Temperature feeling (🥶=freezing, 😰=cold, 🤔=chilly, 😊=pleasant, 😎=perfect, 🔥=warm, 🥵=hot)
- 10-15-20°C: Min-Avg-Max temperatures
Script triggers: 07:45, 12:45, 18:45 (Meteoserver updates at 7:30, 12:30, 18:30)
]]--
return {
active = true,
on = {
timer = { 'at 07:45', 'at 12:45', 'at 18:45', }, -- Meteoserver publishes at 7:30, 12:30 and 18:30
httpResponses = { 'erOpUitCallback' }
},
logging = {
level = domoticz.LOG_DEBUG,
marker = 'ErOpUit',
},
execute = function(domoticz, item)
if item.isTimer then
local url = 'https://data.meteoserver.nl/api/dagverwachting.php?locatie=my_home_town&key=abcdef1234'
domoticz.log('Start ophalen weerdata van: ' .. url, domoticz.LOG_INFO)
domoticz.openURL({
url = url,
method = 'GET',
callback = 'erOpUitCallback'
})
elseif item.isHTTPResponse then
domoticz.log('HTTP callback ontvangen: ' .. item.callback, domoticz.LOG_INFO)
domoticz.log('HTTP Status: ' .. tostring(item.statusCode), domoticz.LOG_INFO)
if item.statusCode ~= 200 then
domoticz.log('Fout bij ophalen weerdata: status ' .. tostring(item.statusCode), domoticz.LOG_ERROR)
return
end
local success, data = pcall(domoticz.utils.fromJSON, item.data)
if not success or not data then
domoticz.log('Kon JSON niet parsen', domoticz.LOG_ERROR)
return
end
-- Compacte logging van de data structuur
domoticz.log('Data structuur - plaatsnaam: ' .. tostring(data.plaatsnaam and data.plaatsnaam[1] and data.plaatsnaam[1].plaats), domoticz.LOG_DEBUG)
domoticz.log('Aantal dagen in data: ' .. tostring(data.data and #data.data), domoticz.LOG_DEBUG)
if not data.data or type(data.data) ~= 'table' then
domoticz.log('Ongeldige data structuur: data.data niet gevonden', domoticz.LOG_ERROR)
return
end
local weatherData = data.data
domoticz.log('Aantal dagen ontvangen: ' .. tostring(#weatherData), domoticz.LOG_INFO)
-- Compacte logging per dag (3 items per regel)
domoticz.log('Detail informatie per dag:', domoticz.LOG_DEBUG)
for i, dayData in ipairs(weatherData) do
if i >= 2 and i <= 10 then -- Alleen de relevante dagen loggen
local dag = dayData.dag or 'onbekend'
local max_temp = tonumber(dayData.max_temp or 0)
local rain = tonumber(dayData.tot_neersl or 0)
local zon = tonumber(dayData.zond_perc_dag or 0)
local wind = tonumber(dayData.winds or 0) -- windkracht (0-12)
domoticz.log(string.format('Dag %d: %s - max: %d°C - regen: %dmm - zon: %d%% - windkracht: %d',
i, dag, max_temp, rain, zon, wind), domoticz.LOG_DEBUG)
end
end
local output = ''
-- Wind-emoji mapping based on wind force (Beaufort scale 0-12)
local windEmoji = {
[1] = '🌫️', -- 0-2 Beaufort - calm/light
[2] = '🍃', -- 3-4 Beaufort - gentle breeze
[3] = '🌬️', -- 5-6 Beaufort - moderate wind
[4] = '💨', -- 7-8 Beaufort - strong wind
[5] = '🌪️' -- 9+ Beaufort - stormy
}
-- Process days 2 to 10 (9-day forecast starting from tomorrow)
for i = 2, 10 do
if not weatherData[i] then
domoticz.log('Geen data voor dag ' .. i, domoticz.LOG_WARNING)
break
end
local datum = weatherData[i].dag:sub(1, 5) -- Extract "dd-mm" from "dd-mm-yyyy"
local min_temp = tonumber(weatherData[i].min_temp or 0)
local avg_temp = tonumber(weatherData[i].avg_temp or 0)
local max_temp = tonumber(weatherData[i].max_temp or 0)
local rain = tonumber(weatherData[i].tot_neersl or 0)
local zon = tonumber(weatherData[i].zond_perc_dag or 0)
local wind = tonumber(weatherData[i].winds or 0) -- wind force (Beaufort 0-12)
-- Format temperatures as 2 digits
local min_str = string.format("%02d", min_temp)
local avg_str = string.format("%02d", avg_temp)
local max_str = string.format("%02d", max_temp)
-- Determine wind emoji based on Beaufort scale
local wind_emoji = windEmoji[1] -- default calm
if wind >= 9 then wind_emoji = windEmoji[5]
elseif wind >= 7 then wind_emoji = windEmoji[4]
elseif wind >= 5 then wind_emoji = windEmoji[3]
elseif wind >= 3 then wind_emoji = windEmoji[2]
end
-- Cloud cover emoji (based on sunshine percentage)
local wolk = '☀️' -- >80% sunshine
if zon <= 20 then wolk = '☁️' -- <20% sunshine - overcast
elseif zon <= 40 then wolk = '🌥️' -- 20-40% sunshine - cloudy
elseif zon <= 60 then wolk = '⛅' -- 40-60% sunshine - partly cloudy
elseif zon <= 80 then wolk = '🌤️' -- 60-80% sunshine - mostly sunny
end
-- Precipitation emoji
local regen_emoji = '☀️' -- 0mm - sunny/dry
if rain > 20 then regen_emoji = '⛈️' -- >20mm - heavy rain/thunder
elseif rain > 10 then regen_emoji = '🌧️' -- 10-20mm - rain
elseif rain > 5 then regen_emoji = '🌦️' -- 5-10mm - light rain
elseif rain > 2 then regen_emoji = '⛅' -- 2-5mm - cloudy/showers
elseif rain > 0.5 then regen_emoji = '🌤️' -- 0.5-2mm - light clouds
end
-- Temperature feeling emoji (based on max temperature)
local temp_emoji = '🥶' -- <10°C: freezing
if max_temp >= 10 and max_temp <= 12 then temp_emoji = '😰' -- 10-12°C: cold
elseif max_temp >= 13 and max_temp <= 15 then temp_emoji = '🤔' -- 13-15°C: chilly
elseif max_temp >= 16 and max_temp <= 18 then temp_emoji = '😊' -- 16-18°C: pleasant
elseif max_temp >= 19 and max_temp <= 22 then temp_emoji = '😎' -- 19-22°C: perfect
elseif max_temp >= 23 and max_temp <= 26 then temp_emoji = '🔥' -- 23-26°C: warm
elseif max_temp > 26 then temp_emoji = '🥵' -- >26°C: hot
end
-- Build output line: date WIND clouds precipitation temperature_feeling min-avg-max°C
output = output .. datum .. ' ' .. wind_emoji .. ' ' .. wolk .. ' ' .. regen_emoji .. ' ' .. temp_emoji .. ' ' .. min_str .. '-' .. avg_str .. '-' .. max_str .. '°C\n'
domoticz.log(string.format('Dag %d: %s - windkracht:%d %s %s %s %s-%s-%s°C',
i, datum, wind, wind_emoji, wolk, regen_emoji, min_str, avg_str, max_str), domoticz.LOG_INFO)
end
domoticz.log('Opgebouwde output: ' .. output, domoticz.LOG_INFO)
local device = domoticz.devices('Er op uit')
if device then
device.updateText(output)
domoticz.log('Device "Er op uit" bijgewerkt', domoticz.LOG_INFO)
else
domoticz.log('Device "Er op uit" niet gevonden!', domoticz.LOG_ERROR)
end
end
end
}