Page 1 of 16
Is it gonna rain within the next X minutes?
Posted: Friday 27 March 2015 14:40
by Hansbit
I wrote a function to predict if it gonna rain within the next X minutes. The function may be very handy for controlling sunscreens etcetera. The script uses the dutch weather website Buienradar.nl, so this script will only work for The Netherlands.
One may use the Buienradar's free service for non-commercial purposes.
Put your local lat/lon in the configuration part of the script. Calling the function IsItGonnaRain( 10) will return the average rain fall for the next 10 minutes. 0 is no rain, 255 is very heavy rain. When needed, mm/h is calculated by 10^((value -109)/32) (example: 77 = 0.1 mm/hour)
Please mail of PM your changes or suggestions, I'll update the script here.
Regards, Hans
Code: Select all
----------------------------------------------------------------------------------------------------------------
-- IsItGonnaRain( int minutesinfuture)
-- returns: int avarage rainfall for the next minutesinfuture
--
-- Function to get rain prediction from Buienradar.nl (dutch)
--
-- http://gratisweerdata.buienradar.nl/#Buienradar You may use their free service for non-commercial purposes.
--
-- Written in LUA by Hans van der Heijden (h4nsie @ gmail.com)
-- Spring 2015
-- 28-03-2015 v0.3 bug: quotes around url added.
-- 27-03-2015 v0.2 return value is now average for next time
-- 26-03-2015 v0.1 Initial release
-- todo: some error checking on http and file handling (tmp file)
----------------------------------------------------------------------------------------------------------------
function IsItGonnaRain( minutesinfuture )
-- config ---------------------------------------------------------
lat='52.09' -- example lat/lon for Utrecht
lon='5.12' -- use MAX 2 decimals behind comma. (Requirement Buienrader)
debug=false
tempfilename = '/var/tmp/rain.tmp' -- can be anywhere writeable
-- config ---------------------------------------------------------
url='http://gps.buienradar.nl/getrr.php?lat='..lat..'&lon='..lon
if debug then print(url) end
read = os.execute('curl -s -o '..tempfilename..' "'..url..'"')
file = io.open(tempfilename, "r")
totalrain=0
rainlines=0
-- now analyse the received lines, format is like 000|15:30 per line.
while true do
line = file:read("*line")
if not line then break end
if debug then print('Line:'..line) end
linetime=string.sub(tostring(line), 5, 9)
if debug then print('Linetime: '..linetime) end
-- Linetime2 holds the full date calculated from the time on a line
linetime2 = os.time{year=os.date('%Y'), month=os.date('%m'), day=os.date('%d'), hour=string.sub(linetime,1,2), min=string.sub(linetime,4,5), sec=os.date('%S')}
difference = os.difftime (linetime2,os.time())
-- When a line entry has a time in the future AND is in the given range, then totalize the rainfall
if ((difference > 0) and (difference<=minutesinfuture*60)) then
if debug then print('Line in time range found') end
rain=tonumber(string.sub(tostring(line), 0, 3))
totalrain = totalrain+rain
rainlines=rainlines+1
if debug then print('Rain in timerange: '..rain) end
if debug then print('Total rain now: '..totalrain) end
end
end
file:close()
-- Returned value is average rain fall for next time
-- 0 is no rain, 255 is very heavy rain
-- When needed, mm/h is calculated by 10^((value -109)/32) (example: 77 = 0.1 mm/hour)
averagerain=totalrain/rainlines
return(averagerain)
end
Example implementation in Domoticz:
Code: Select all
----- REGEN ------
minuten=10
regen = IsItGonnaRain(minuten)
print('Regen verwacht: '..regen..' binnen '..minuten..' minuten.')
if regen > 70 then
commandArray['SendNotification']='Sunscreens#Regen verwacht'
end
Is it gonna rain within the next X minutes?
Posted: Friday 27 March 2015 16:05
by xces
Hi Hans,
Looking good! Can you post an example how to implement also? I have never done anything in Lua, only in C#. Do you run this script in a loop?
Re: Is it gonna rain within the next X minutes?
Posted: Friday 27 March 2015 16:34
by tlpeter
I am curious too.
I just installed a Fibaro roller/shutter for my sunscreen.
It would be nice to prevent it getting wet if i forget it

Re: Is it gonna rain within the next X minutes?
Posted: Saturday 28 March 2015 8:52
by pvm
Did you put the lua script in the domoticz scripts/lua folder? This is automatically executed every minute when choosing the correct name
Re: Is it gonna rain within the next X minutes?
Posted: Saturday 28 March 2015 13:31
by johnwulp
Thanks for your effort! I implemented it in my sunscreen script. Does is also spit out a value > 0 if it is raining?
Re: Is it gonna rain within the next X minutes?
Posted: Saturday 28 March 2015 14:05
by tlpeter
John, can you share your script?
Re: Is it gonna rain within the next X minutes?
Posted: Saturday 28 March 2015 14:50
by johnwulp
tlpeter wrote:John, can you share your script?
Offcourse. It's still 'in progress...'
Code: Select all
function IsItGonnaRain( minutesinfuture )
-- config ---------------------------------------------------------
lat='51.818930' -- example lat/lon for Utrecht
lon='4.427236'
debug=false
tempfilename = '/var/tmp/rain.tmp' -- can be anywhere writeable
-- config ---------------------------------------------------------
url='http://gps.buienradar.nl/getrr.php?lat='..lat..'&lon='..lon
if debug then print(url) end
read = os.execute('curl -s -o '..tempfilename..' "'..url..'"')
file = io.open(tempfilename, "r")
totalrain=0
rainlines=0
-- now analyse the received lines, format is like 000|15:30 per line.
while true do
line = file:read("*line")
if not line then break end
if debug then print('Line:'..line) end
linetime=string.sub(tostring(line), 5, 9)
if debug then print('Linetime: '..linetime) end
-- Linetime2 holds the full date calculated from the time on a line
linetime2 = os.time{year=os.date('%Y'), month=os.date('%m'), day=os.date('%d'), hour=string.sub(linetime,1,2), min=string.sub(linetime,4,5), sec=os.date('%S')}
difference = os.difftime (linetime2,os.time())
-- When a line entry has a time in the future AND is in the given range, then totalize the rainfall
if ((difference > 0) and (difference<=minutesinfuture*60)) then
if debug then print('Line in time range found') end
rain=tonumber(string.sub(tostring(line), 0, 3))
totalrain = totalrain+rain
rainlines=rainlines+1
if debug then print('Rain in timerange: '..rain) end
if debug then print('Total rain now: '..totalrain) end
end
end
file:close()
averagerain=totalrain/rainlines
return(averagerain)
end
commandArray = {}
time = os.date("*t")
--Extract Wind Gust speed from SValue Wind
wind = otherdevices_svalues['Wind']
--print("Wind: "..wind)
--Filter the third digitsequence from SValue
a = string.sub(wind,1,string.find(wind,';',1,true)-1)
--print("a: "..a)
b = string.sub(wind,string.find(wind,';',1,true)+1)
--print("b: "..b)
d = string.sub(b,string.find(b,';',1,true)+1)
--print("d: "..d)
windspeed = string.sub(d,1,string.find(d,';',1,true)-1)
f = string.sub(d,string.find(d,';',1,true)+1)
--print("f: "..f)
g = string.sub(f,string.find(f,';',1,true)+1)
--print("g: "..g)
--Extract Temp
tempstring = otherdevices_svalues['Temperatuur']
--print("Temp: "..tempstring)
temperature = string.sub(tempstring,1,string.find(tempstring,';',1,true)-1)
--Extract UV radiation from SValue Wind
-- solar = otherdevices_svalues['UV']
-- print("Solar Radiation: "..solar)
--Filter the first digit from SValue
-- uv = string.sub(solar,1,string.find(solar,';',1,true)-1)
-- print("UV: "..uv)
--Extract actual rainfall from Rain_SValue
rain = otherdevices_svalues['Regen']
--print("Rain: "..rain)
--Filter the first digit from SValue
currentrain = string.sub(rain,1,string.find(rain,';',1,true)-1)
--Filter the last digit from SValue
--totalrain = string.sub(rain,string.find(rain,';',1,true)+1)
--print("Total rain: "..totalrain)
print("Uur: " ..time.hour)
minuten=5
regen = IsItGonnaRain(minuten)
print('Regen verwacht: '..regen..' binnen '..minuten..' minuten.')
--Sunscreen thresholds:
-- Windspeed = 50 (value is multiplied by 10)
-- Rain = 0.0
-- UV = 2.0
-- Temperature = 10.0
-- Closed = Down = On
-- Open = Up = Off
if (timeofday['Daytime'] and time.hour > 11)
then
print('It is past sunrise, and after 11. monitoring variables for sunscreen')
if (otherdevices['Zonnescherm_virtual'] == 'Open' ) then
print ('Zonnescherm is up')
else
print ('Zonnescherm is down')
end
print("currentrain: "..currentrain)
print("temperature: "..temperature)
print("windspeed: "..windspeed)
currentrain = tonumber(currentrain)
temperature = tonumber(temperature)
windspeed = tonumber(windspeed)
if (otherdevices['Zonnescherm_virtual'] == 'Open'
and regen == 0
and temperature > 15
and windspeed < 50
and time.hour > 11)
--and otherdevices['IemandThuis'] == 'On')
then
print ('Sun is shining, all thresholds OK, lowering sunscreen')
commandArray['SendNotification']='Zonnescherm#Zonnescherm gaat uit! --> De zon schijnt! Joepie!!! \rRegen: '..currentrain..'\rTemp: '..temperature..'\rWind: '..windspeed
commandArray['Zonnescherm_virtual']='On'
--elseif (otherdevices['Zonnescherm_virtual'] == 'Closed' and otherdevices['IemandThuis'] == 'Off') then
-- print ('Nobody at home, raising sunscreen')
-- commandArray['SendNotification']='Zonnescherm#Zonnescherm gaat naar binnen --> Niemand thuis!'
-- commandArray['Zonnescherm_virtual']='Off'
elseif (otherdevices['Zonnescherm_virtual'] == 'Closed' and regen > 0) then
print ('It is raining, raising sunscreen')
commandArray['SendNotification']='Zonnescherm#Zonnescherm gaat naar binnen --> Het gaat regenen!'
commandArray['Zonnescherm_virtual']='Off'
elseif (otherdevices['Zonnescherm_virtual'] == 'Closed' and temperature <= 15) then
print ('Temperature too low, raising sunscreen')
commandArray['SendNotification']='Zonnescherm#Zonnescherm gaat naar binnen --> Te koud'
commandArray['Zonnescherm_virtual']='Off'
--elseif (otherdevices['Zonnescherm_virtual'] == 'Closed' and uv < '1.0') then
-- print ('Sun not shining too bright, raising sunscreen')
-- commandArray['SendNotification']='Zonnescherm#Zonnescherm gaat naar binnen --> Zon schijnt niet voldoende'
-- commandArray['Zonnescherm_virtual']='Off'
elseif (otherdevices['Zonnescherm_virtual'] == 'Closed' and windspeed > 49) then
print ('Windspeed too high, raising sunscreen')
commandArray['SendNotification']='Zonnescherm#Zonnescherm gaat naar binnen --> Teveel wind'
commandArray['Zonnescherm_virtual']='Off'
else
print('Zonnescherm status OK --> No action')
end
elseif (timeofday['Nighttime']
and otherdevices['Zonnescherm_virtual'] == 'Closed')
then
print('It is night, raising sunscreen')
commandArray['SendNotification']='Zonnescherm#Zonnescherm naar binnen --> Zon gaat onder!'
commandArray['Zonnescherm_virtual']='Off'
else
print('Zonnescherm already up --> No action')
end
return CommandArray
Re: Is it gonna rain within the next X minutes?
Posted: Saturday 28 March 2015 14:54
by johnwulp
It also depends on several other devices:
The Wind, Temperatuur, Regen devices are from Forecast IO.
The IemandThuis device is a virtual one that i intend to use in the future. It switches on and off based on two bluetooth devices and a motion sensor.
The Zonnescherm_virtual device should be the actual sunscreen. In my case it's still a virtual one, when i'm happy with the code, i'll change it to the real sunscreen.
Re: Is it gonna rain within the next X minutes?
Posted: Saturday 28 March 2015 15:19
by tlpeter
Thanks.
I do not have a weather station at the moment but I use weather underground at the moment.
There is a nice station near by but you will know that the weather can change quickly around the haringvliet.
I live on the other site of the water.
PS born and raised in spijkenisse.
Re: Is it gonna rain within the next X minutes?
Posted: Saturday 28 March 2015 15:44
by johnwulp
Funny dat you live on the other side

. I also don't have a weather station, that's why i use the forecast io. I've seen that rain is not very accurate. That's why this buienradar script comes in very handy!
Re: Is it gonna rain within the next X minutes?
Posted: Sunday 29 March 2015 12:06
by Mediacj
Thanks Hansbit for this nice script!!
I have implemented it on this way:
1. made a virtual humidity sensor (didn't know a better type)
2. made a time based lua script of it: script_time_rain.lua with both scripts together (see code below) within the code I update the virtual humidity device with the rain value, I also forward the humidity status which changes from dry to wet when the rain value is bigger then 0
3. change in the script the idx 125 of mine virtual device (in the update_device command) with your virtual humidity device idx
4. placed the lua script in the lua directory: /home/pi/domoticz/scripts/lua
Now you can use the value of this virtual humidity device to react on it in scripts or in blockly
Code: Select all
----------------------------------------------------------------------------------------------------------------
-- IsItGonnaRain( int minutesinfuture)
-- returns: int avarage rainfall for the next minutesinfuture
--
-- Function to get rain prediction from Buienradar.nl (dutch)
--
-- http://gratisweerdata.buienradar.nl/#Buienradar You may use their free service for non-commercial purposes.
--
-- Written in LUA by Hans van der Heijden (h4nsie @ gmail.com)
-- Spring 2015
-- 28-03-2015 v0.3 bug: quotes around url added.
-- 27-03-2015 v0.2 return value is now average for next time
-- 26-03-2015 v0.1 Initial release
-- todo: some error checking on http and file handling (tmp file)
----------------------------------------------------------------------------------------------------------------
function IsItGonnaRain( minutesinfuture )
-- config ---------------------------------------------------------
lat='51.687895' -- example lat/lon for Utrecht
lon='5.057482'
debug=false
tempfilename = '/var/tmp/rain.tmp' -- can be anywhere writeable
-- config ---------------------------------------------------------
url='http://gps.buienradar.nl/getrr.php?lat='..lat..'&lon='..lon
if debug then print(url) end
read = os.execute('curl -s -o '..tempfilename..' "'..url..'"')
file = io.open(tempfilename, "r")
totalrain=0
rainlines=0
-- now analyse the received lines, format is like 000|15:30 per line.
while true do
line = file:read("*line")
if not line then break end
if debug then print('Line:'..line) end
linetime=string.sub(tostring(line), 5, 9)
if debug then print('Linetime: '..linetime) end
-- Linetime2 holds the full date calculated from the time on a line
linetime2 = os.time{year=os.date('%Y'), month=os.date('%m'), day=os.date('%d'), hour=string.sub(linetime,1,2), min=string.sub(linetime,4,5), sec=os.date('%S')}
difference = os.difftime (linetime2,os.time())
-- When a line entry has a time in the future AND is in the given range, then totalize the rainfall
if ((difference > 0) and (difference<=minutesinfuture*60)) then
if debug then print('Line in time range found') end
rain=tonumber(string.sub(tostring(line), 0, 3))
totalrain = totalrain+rain
rainlines=rainlines+1
if debug then print('Rain in timerange: '..rain) end
if debug then print('Total rain now: '..totalrain) end
end
end
file:close()
-- Returned value is average rain fall for next time
-- 0 is no rain, 255 is very heavy rain
-- When needed, mm/h is calculated by 10^((value -109)/32) (example: 77 = 0.1 mm/hour)
averagerain=totalrain/rainlines
return(averagerain)
end
----- REGEN ------
commandArray = {}
minuten=15
regen = IsItGonnaRain(minuten)
print('Regen verwacht(0-255 hoe hoger hoe meer regen): '..regen..' binnen '..minuten..' minuten.')
if (regen > 0 ) then verw = 3 else verw = 2 end
commandArray['UpdateDevice'] = '125|'..tostring(regen)..'|'..tostring(verw)
return commandArray
Is it gonna rain within the next X minutes?
Posted: Sunday 29 March 2015 18:48
by Hansbit
Thanks all for the positive feedback on my script.
It's today a nice day to test this function..

rainfall 15mm!
Re: Is it gonna rain within the next X minutes?
Posted: Wednesday 01 April 2015 21:41
by niki_lauda
Mediacj wrote:Thanks Hansbit for this nice script!!
I have implemented it on this way:
1. made a virtual humidity sensor (didn't know a better type)
2. made a time based lua script of it: script_time_rain.lua with both scripts together (see code below) within the code I update the virtual humidity device with the rain value, I also forward the humidity status which changes from dry to wet when the rain value is bigger then 0
3. change in the script the idx 125 of mine virtual device (in the update_device command) with your virtual humidity device idx
4. placed the lua script in the lua directory: /home/pi/domoticz/scripts/lua
Now you can use the value of this virtual humidity device to react on it in scripts or in blockly
How do I create a virtual humidity device?
Re: Is it gonna rain within the next X minutes?
Posted: Thursday 02 April 2015 14:55
by Mediacj
1. go to setup tab
2. choose hardware
3. name: give it a name
4. type: Dummy (Does nothing, use for virtual switches only)
5. click on Add
6. now you have a new hardware device with the given name
7. choose 'Create Virtual Sensors' on the line of your new hardware device you just created
8. Sensor type: 'Humidity' and click OK
9. Go to the Setup tab again and now choose 'Devices'
10. there will be a new device with a green arrow on the end, click on the arrow and give your device a name
11. now you have the humidity device under the temperature tab
Re: Is it gonna rain within the next X minutes?
Posted: Thursday 02 April 2015 22:03
by niki_lauda
THX
Re: Is it gonna rain within the next X minutes?
Posted: Saturday 04 April 2015 17:34
by tlpeter
Hansbit wrote:Thanks all for the positive feedback on my script.
It's today a nice day to test this function..

rainfall 15mm!
Hi Hans,
I am running a Windows system with Domoticz.
Your script isn't working an i think because of some Linux commands.
The location /var/.... i have changed already.
What else needs to be changed?
Re: Is it gonna rain within the next X minutes?
Posted: Monday 06 April 2015 22:38
by Hansbit
tlpeter wrote:Hansbit wrote:
I am running a Windows system with Domoticz.
Your script isn't working an i think because of some Linux commands.
The location /var/.... i have changed already.
What else needs to be changed?
Hello tlpeter,
The 'curl' command is executed to get the url. That is not available in Windows.
Hans
Re: Is it gonna rain within the next X minutes?
Posted: Tuesday 07 April 2015 7:34
by tlpeter
Hi Hans i know, that is the problem
I use a different script now and i have it working.
But thanks anyway.
Re: Is it gonna rain within the next X minutes?
Posted: Sunday 12 April 2015 14:20
by roblom
I added also a text device and filled it with the text from this script.
Code: Select all
function round(num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
----------------------------------------------------------------------------------------------------------
-- CommandArray
----------------------------------------------------------------------------------------------------------
commandArray = {}
minuten=15
RainPrediction = IsItGonnaRain(minuten)
RainmmHour=10^((RainPrediction-109)/32)
if (RainPrediction > 0 ) then
verw = 3
RainPredictionText=('Regen verwacht binnen '..minuten..' minuten, met ' ..round(RainmmHour, 1).. ' mm/uur')
else
verw = 2
RainPredictionText=('Geen regen verwacht binnen '..minuten..' minuten.')
end
commandArray[1] = {['UpdateDevice'] = RainDeviceIDX .. '|'..tostring(RainPrediction)..'|'..tostring(verw)}
commandArray[2] = {['UpdateDevice'] = RainTextIDX .. '|0|' .. tostring(RainPredictionText)}
print('-- Regen verwacht(0-255 hoe hoger hoe meer regen): '..RainPrediction..' binnen '..minuten..' minuten.')
print('-- ' .. RainPredictionText )
return commandArray
RainTextIDX = the IDX of the text device.
And added a round function to display only 1 digit.
Re: Is it gonna rain within the next X minutes?
Posted: Monday 13 April 2015 23:32
by markk
tlpeter wrote:Hi Hans i know, that is the problem
I use a different script now and i have it working.
But thanks anyway.
Hi Tlpeter
Would you mind sharing your windows script please?
Thanks
Mark