Page 4 of 16

Re: Is it gonna rain within the next X minutes?

Posted: Saturday 25 July 2015 12:20
by RayAmsterdam
Yes Jos. I already found it. The following line is missing in the script:

Code: Select all

commandArray = {}

Re: Is it gonna rain within the next X minutes?

Posted: Saturday 25 July 2015 12:29
by RayAmsterdam
Updated the wiki (repaired 2 faults)

Re: Is it gonna rain within the next X minutes?

Posted: Saturday 25 July 2015 14:27
by jjnj
Hansbit wrote:
jjnj wrote:Why a threshold for 70? Then it would already be raining right below 70? So that would be to late
With lower values to trigger for rain you'll get too many false positives. Even on sunny days with clear blue sky, Buienrader sometimes reports values like 35 or 40.
When checking today's weather with the severe storm we have right now the reported value is 74, I think 70 is way to high. But I will investigate what is best for my situation.

Re: Is it gonna rain within the next X minutes?

Posted: Saturday 25 July 2015 14:49
by RayAmsterdam
I also added the next line to the script on my pi to see the value in mm/hour:

Code: Select all

regenmm = 10 ^ ((regen - 109) / 32)

print('Regen verwacht: '..regenmm..' mm/uur binnen '..minuten..' minuten.')

Re: Is it gonna rain within the next X minutes?

Posted: Thursday 30 July 2015 13:34
by tlpeter
I use a combo with humidity too.
When the humidity is under or equal to 70 and no rain (threshold) than lower sunscreen.
The buienradar script only will not work.

Re: Is it gonna rain within the next X minutes?

Posted: Thursday 17 September 2015 12:00
by Deva
Being fairly new to LUA scripting, Ray could you perhaps help me to propagate the changes to display the mm/h within Domoticz?

At the moment I have connected an on/off button to the virtual device.

Re: Is it gonna rain within the next X minutes?

Posted: Friday 15 January 2016 12:56
by elmortero
Does anyone have this for other countries?
I would like this too, for Spain?

Re: Is it gonna rain within the next X minutes?

Posted: Monday 16 May 2016 12:56
by emke
I can't get the os.execute command working. I created an tempfile and chmod it to 777 but it won't get updated. If i execute the curl command in the shell it's working. I also can't find a way to get some logging why the os.execute isn't working. What can i try to get working?

Code: Select all

read = os.execute('curl -s -o '..tempfilename..' "'..url..'"')
print('curl -s -o '..tempfilename..' "'..url..'"');

Re: Is it gonna rain within the next X minutes?

Posted: Monday 16 May 2016 13:15
by mikeoo
emke wrote:I can't get the os.execute command working. I created an tempfile and chmod it to 777 but it won't get updated. If i execute the curl command in the shell it's working. I also can't find a way to get some logging why the os.execute isn't working. What can i try to get working?

Code: Select all

read = os.execute('curl -s -o '..tempfilename..' "'..url..'"')
print('curl -s -o '..tempfilename..' "'..url..'"');
You don't need te create the tempfile if the script is working.
Maby it have no rights to write in the folder of the temp file.

Did you give the script executable rights with chmod +x scriptname

Maybe better to place the whole script you use so we can see what you have now.

Re: Is it gonna rain within the next X minutes?

Posted: Monday 16 May 2016 17:34
by emke
I used the script as posted on page 1. The folder /var/tmp is 777 and the file rain.tmp is also 777. Is in necessary to give the LUA script chmod +x? None of my LUA scripts have executable rights.

Re: Is it gonna rain within the next X minutes?

Posted: Sunday 29 May 2016 15:24
by Robert
Hi jjnj. what i did to prevent Buienradar sending "Ghost" value's is a counter that Increase every time (+1) when buienradar detect rain in my area. When a certain level reach its threshold, It close my Sunscreen.
I was hoping to create a reliable way of detecting rain, until today. It rains now already 2 hours and the data I receive is still "Dry"
Checked the coordinates and buienradar itself. Anyone else that have the same issue?
000|14:45 000|14:50 000|14:55 000|15:00 000|15:05 000|15:10 000|15:15 000|15:20 000|15:25 000|15:30 000|15:35 000|15:40 000|15:45 000|15:50 000|15:55 000|16:00 000|16:05 000|16:10 000|16:15 000|16:20 000|16:25 000|16:30 000|16:35 000|16:40 000|16:45
After restart by Raspberry, the reading start working again...... and yes, indeed, it was raining and my soaked sunscreen wheeled in.

I also struggle with my UV readings from weather underground. No data for a few days isn't an exception. But probably it has something to do with my setup. because after starting the weather underground with a second RBpi and same API, suddenly the UV data on my original RBpi became alive.
Also for this question: Anyone else that have the same issue?



The credits for the Script below belongs partly to another (more) creative mind!
Add a User Variable in domoticz (Integer)

This script is a part of my Sunscreen script.


local bui_uservar = 'buienteller'

-- BEGIN BUIENRADAR TELLER nieuw VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV

buialarm = tonumber(uservariables[bui_uservar])
if (otherdevices['Zonnescherm'] == 'Open') and (sREGEN > 2)
then
buialarm = buialarm + 1
print ('<font color="red">Buienradar waarschuwd voor buien : ' ..buialarm.. ' minuten </font>')
else
buialarm = 0


commandArray['Variable:' .. bui_uservar] = tostring(buialarm)
if (otherdevices['Zonnescherm'] == 'Open' and buialarm > 15) then -- vul hier de aantal keren BUIALARMEN in voordat scherm dicht moet
print ('Zonnescherm omhoog, Regen volgens Buienradar na 15 pogingen')
commandArray['SendNotification']='Zonnescherm#Zonnescherm omhoog --> regen op komst volgens buienradar na 15 pogingen'
commandArray['Zonnescherm']='On'
end

Re: Is it gonna rain within the next X minutes?

Posted: Monday 13 June 2016 0:16
by rickwilleme
I've created a virtual rain device.
Is there a way to set the value via the lua script?
Tried several ways, but don't seem to get it working :roll:

Re: Is it gonna rain within the next X minutes?

Posted: Thursday 30 June 2016 11:54
by TinusExcentricus
I've added a little tweak in the last part. Maybe someone can use it.
I'm recalculation the rain number to a value in mm per hour for easy setting and comparison.

In this script I'm switching off my canopy, only if it's on and if rain expectancy is above the threshold set in the variables minutes and threshold.

Code: Select all

-- function to round numbers
function round(num, idp)
	return tonumber(string.format("%." .. (idp or 0) .. "f", num))
end

-- RAIN ACTION SCRIPT
commandArray = {}

-- time variables
interval_min = 5
 
time = os.date("*t")
if ((time.min % interval_min)==0) then
 
	----- rain variables ------
	minutes=5
	threshold=0.25

	----- rain calculations ------
	rain = IsItGonnaRain(minutes)
	rainavg = 10^((rain-109)/32)
	rainmmh = round(rainavg, 2)

	----- rain actions ------
	if rainmmh > threshold then
		if (otherdevices['Canopy'] ~= 'Open') then
			print(rainmmh..' mm/h rain expected in '..minutes..' minutes → switch canopy off!')
			commandArray['Canopy']='Off'
		else
			print(rainmmh..' mm/h rain expected in '..minutes..' minutes, canopy is already off → all clear and dry!')
		end
	else
		print(rainmmh..' mm/h rain expected in '..minutes..' minutes.')
	end	 
 
end 
 
return commandArray

Re: Is it gonna rain within the next X minutes?

Posted: Saturday 27 August 2016 16:43
by scheveningen
Mediacj wrote: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
I follow this list but I don't get it work. In the log I see that the script is working.
2016-08-27 13:27:43.463 (Rain expected) Lighting 1 (Rain expected)
2016-08-27 13:30:00.724 LUA: Regen verwacht: 0 mm binnen 20 minuten.
2016-08-27 13:45:00.438 LUA: Regen verwacht: 0 mm binnen 20 minuten.
2016-08-27 14:00:00.639 LUA: Regen verwacht: 0 mm binnen 20 minuten.
2016-08-27 14:15:00.289 LUA: Regen verwacht: 0 mm binnen 20 minuten.
2016-08-27 14:30:00.516 LUA: Regen verwacht: 0 mm binnen 20 minuten.
2016-08-27 14:45:00.704 LUA: Regen verwacht: 0 mm binnen 20 minuten
so that part is working fine. But now the virtual sensor is the part that goes wrong.
So this is what I do,

- Create Dummy (Does nothing, use for virtual switches only)
- Create Virtual Sensors with the name buienrader and sensor type, humanity
Indeed under temperature I find the humanity sensor with the name buienrader.
But I get nog info, so I changed the name to Rain expected, but the same, no forecast.


So just to be sure I made a new on/of switch with the name Rain expected but no luck.
For sure I made a small mistake, but I can not figure it out :(

Re: Is it gonna rain within the next X minutes?

Posted: Saturday 27 August 2016 17:01
by jvdz
Did you update the script with the proper Device to update?

Jos

Re: Is it gonna rain within the next X minutes?

Posted: Sunday 28 August 2016 15:36
by scheveningen
jvdz wrote:Did you update the script with the proper Device to update?

Jos
I'm not sure what you meen? If you meen lon/lat? Yes I change that.
And the device in domoticz is a humanity sensor ( dummy ) Is not, pleas give me a example?

Re: Is it gonna rain within the next X minutes?

Posted: Sunday 28 August 2016 16:00
by jvdz
That dummy device has an IDX number which needs to changed in the script as well!
Look at these lines:

Code: Select all

commandArray['UpdateDevice'] = '125|'..tostring(regen)..'|'..tostring(verw)
return commandArray
Change 125 for the IDX of your dummy device.

Jos

Re: Is it gonna rain within the next X minutes?

Posted: Sunday 28 August 2016 16:32
by scheveningen
jvdz wrote:That dummy device has an IDX number which needs to changed in the script as well!
Look at these lines:

Code: Select all

commandArray['UpdateDevice'] = '125|'..tostring(regen)..'|'..tostring(verw)
return commandArray
Change 125 for the IDX of your dummy device.

Jos
YES! it works! U used the script from the wiki page. But that line isn't in the script. So i added it to the script and it is working now!
Tanks for your help!

Re: Is it gonna rain within the next X minutes?

Posted: Tuesday 30 August 2016 18:23
by marmachine
Updated the script
There appears to be a redirect (in the request url) causing the script to fail!

my current (working) version:

Code: Select all

-- =============================================================================================================
-- IsItGonnaRain( int minutesinfuture)
-- returns: int avarage rainfall for the next minutesinfuture
-- =============================================================================================================
-- Function to get rain prediction from Buienradar.nl (dutch)
-- Original script here: https://www.domoticz.com/wiki/Is_it_gonna_rain
--
-- 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)
----------------------------------------------------------------------------------------------------------------
-- Marco van Wijngaarden
-- 30-08-2016 v1.0 Adopted and updated the above scripts
-- 30-08-2016 v1.1 Updated the request URL, apparently buienrader is redirecting to different url
-- 30-08-2016 v1.2 Updated CURL to follow redirect and reverted (back to documented) request URL
--
----------------------------------------------------------------------------------------------------------------
-- Buienradar.nl --
---------------------
-- Gratis Weerdata --
--
-- Buienradar stelt gratis weerdata beschikbaar voor particulieren en bedrijven (website/intranet). 
-- Het gebruik van onderstaande weerdata is alleen toegestaan voor niet-commerciële doeleinden. 
-- Het gebruik voor mobiele toepassingen of commerciële doeleinden vereist toestemming van Buienradar, zie ook de Disclaimer.
-- Vraag hier toestemming aan voor het gebruik van de weerdata: http://www.buienradar.nl/overbuienradar/contact 
-- Vragen, suggesties of een leuk idee? Neem contact met ons op en bouw mee aan Buienradar!
-- 
------------------------------------------------------------
-- Buienradar widget - Neerslagdata op basis van coördinaten
------------------------------------------------------------
--
-- Op basis van de door u gewenste coördinaten (latitude en longitude) kunt u de neerslag tot twee uur vooruit ophalen in tekstvorm. 
-- De data wordt iedere 5 minuten geüpdatet. 
-- Op deze pagina kunt u de neerslag in tekst vinden: http://gps.buienradar.nl/getrr.php?lat=51&lon=3
-- De waarde 0 geeft geen neerslag aan (droog), de waarde 255 geeft zware neerslag aan. 
-- Gebruik de volgende formule voor het omrekenen naar de neerslagintensiteit in de eenheid millimeter per uur (mm/u):
-- Neerslagintensiteit = 10^((waarde-109)/32)
-- Ter controle: een waarde van 77 is gelijk aan een neerslagintensiteit van 0,1 mm/u.
--
-- =============================================================================================================
-- config ------------------------------------------------------------------------------------------------------
-- =============================================================================================================
--
-- Set your local position (latitude and longitude)
local latitude                  = uservariables['latitude']         -- your home latitude, set as a user variable
local longitude                 = uservariables['longitude']        -- your home longtitude, set as a user variable
-- timewindow for prediction
local minutesinfuture           = 15                                -- (int) minutes in future to calculate rain
-- threshold for switch (when do we actually call it rain and want to act accordingly)
local switchthreshold           = 70                                -- (int) value to toggle virtual switch
-- Rain switch (ON when rain above threshold, else OFF)
local rainswitchname            = "Regen verwacht"                  -- (str) name for switch to toggle
-- Virtual device (txt) displays textual result
local idxRegenmmUur             = 113                               -- IDX for virtual (text) sensor
-- Show results in log
local debug                     = 1                                 -- 1 = ON or 0 = OFF
-- NMA notifications (only during the day)
local notify                    = false                             -- (bool) set 'false' or 'true'
-- URL for data rewquest
local requesturl                = "http://gps.buienradar.nl/getrr.php" 
-- redirects to "http://gadgets.buienradar.nl/data/raintext"
-- Where do we store the data (tmp) file
local tempfilename              = "/home/pi/domoticz/scripts/tmp/rain.tmp"
-- default to activate script (set 'false' to run once every 5 minutes or 'true' to run every minute)
local active                    = false                             -- (bool) set 'false' or 'true'
--
-- =============================================================================================================
--
-- No edit required below this line
--
-- =============================================================================================================
--
-- execute (activate) every 5 minutes
local time = os.date("*t")
if ((time.min % 5)==0) then
    -- set to active
    active = true
end
--
-- =============================================================================================================
-- Functions ---------------------------------------------------------------------------------------------------
-- =============================================================================================================

-- function to split a string --
function splitString(str, delim, maxNb)
    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        return { str }
    end

    if maxNb == nil or maxNb < 1 then
        maxNb = 0    -- No limit
    end

    local result = {}
    local pat = "(.-)" .. delim .. "()"
    local nb = 0
    local lastPos
    for part, pos in string.gmatch(str, pat) do
        nb = nb + 1
        result[nb] = part
        lastPos = pos
        if nb == maxNb then break end
    end
    -- Handle the last field
    if nb ~= maxNb then
        result[nb + 1] = string.sub(str, lastPos)
    end

    return result
end

-- function to request rain data 
function IsItGonnaRain(requesturl,latitude,longitude,tempfilename,minutesinfuture,debug)

    local averagerain = 0
    local totalrain = 0
    local rainlines = 0
    
    -- construct the request URL
    local url = requesturl..'?lat='..latitude..'&lon='..longitude
    
    -- print to log
    if (debug == 1) then print("| Request URL .............. : " .. url) end

    -- now get the data
    local trigger_action = 'curl -Lo '..tempfilename..' "'..url..'"' 
    -- CURL options:    -s for Silent (no error messages)
    --                  -o for Write output to file instead of stdout.
    --                  -L Follow redirects if the server reports that the requested page has moved (indicated with a Location: header and a 3XX response code)
    handle = os.execute(trigger_action)

    -- print request result to log
    if (debug == 1) then
        if handle then
            print("| CURL Data request ........ : Success")
        else
            print("! CURL Data request ........ : Failed")
        end
    end

    -- open file and process data
    file = io.open(tempfilename, "r")

        -- count datalines
        local linenbr = 0
        
        -- now analyse the received lines
        while true do
            line = file:read("*line")
            if not line then break end
            
            -- count received lines
            linenbr = linenbr+1
            
            -- line/data format is like 000|15:30 per line, we need to split the string
            raindata    = splitString(line,"|")
            rain        = tonumber(raindata[1])
            linetime    = raindata[2]

            -- Linetime2 holds the full date calculated from the time on each 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')}
            -- calculate the time difference between data/line and os time
            difference  = os.difftime (linetime2,os.time())

            -- When a line entry has a time in the future AND is within the given range, then add/totalize the rainfall
            if ((difference >= 0) and (difference <= minutesinfuture*60)) then
                
                -- print (relevant) data to log
                if (debug == 1) then print("| Rain data (line) ......... : " .. line) end
                
                -- calculate totals
                totalrain = totalrain+rain
                rainlines = rainlines+1
            end
        end
    -- close the file
    file:close()
    
    -- Returned value is average rain fall for next (int) 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)
    averagerain = totalrain/rainlines
    
    -- print summary to log
    if (debug == 1) then 
        print("| Rain data received # lines : " .. linenbr)
        print("| In timerange # lines ..... : " .. rainlines)
        print("| Total rain ............... : " .. totalrain)
        print("| Average rain calculated .. : " .. averagerain)
    end

    return(averagerain)

end

-- Functions to round a number to the given number of decimal places
-- returns result as string (text)
function round(num, idp)
  return string.format("%." .. (idp or 0) .. "f", num)
end
-- returns result as a number
function round2number(num, idp)
  return tonumber(string.format("%." .. (idp or 0) .. "f", num))
end

-- Note: If the number is rounded in order to be printed (as text) use function "round" (removed the tonumber function)
-- Converting to number then back to string would reintroduce rounding errors, so for numbers use "round2number" function

-- =============================================================================================================
-- Process -----------------------------------------------------------------------------------------------------
-- =============================================================================================================

commandArray = {}
-- start numbering at 1
indexArray=1

-- executes when active (every 5 minutes)
if (active) then

    -- when debugging set to 1, writing to log starts here
    if (debug == 1) then
        print("+--------------------------------------------------+")
        print("| =============== IS IT GONNA RAIN =============== |")
        print("+--------------------------------------------------+")
    end

    -- rain variables
    local regen = 0
    local regenmmUur = 0
    local rainstr = ""

    -- execute function (for given future minutes)
    regen = IsItGonnaRain(requesturl,latitude,longitude,tempfilename,minutesinfuture,debug)
    
    -- round result
    if (regen > 0) then
        regen = round2number(regen, 0)
    end

    -- convert rain to mm/uur
    if (regen > 0) then
        regenmmUur = 10^((regen-109)/32)
        regenmmUur = round(regenmmUur, 3)
    end

    -- textual result
    if (regen > 0) then
        rainstr = tostring("Regen verwacht: "..regen.." (".. regenmmUur.." mm/uur) binnen "..minutesinfuture.." minuten")
    else
        rainstr = tostring("Geen regen verwacht binnen komende "..minutesinfuture.." minuten")
    end

    -- write value to virtual (text) sensor
    if ((idxRegenmmUur) and (regenmmUur)) then
        commandArray[indexArray] = {['UpdateDevice'] = tostring(idxRegenmmUur)..'|0|'..rainstr}
        indexArray=indexArray+1
    end

    -- when debugging set to 1, write to log
    if (debug == 1) then 
        print("| Rain text ................ : " .. rainstr)
    end

    -- toggle switch ON
    if regen > switchthreshold and otherdevices[rainswitchname]=='Off' then
        
        -- send notification during the day
        if (timeofday['Daytime']) and (notify) then
            commandArray[indexArray] = {['SendNotification']=rainstr}
            indexArray=indexArray+1
        end
        
        -- change switch to ON
        commandArray[indexArray] = {[rainswitchname]='On'}
        indexArray=indexArray+1
    end

    -- toggle switch OFF
    if regen == 0 and otherdevices[rainswitchname] =='On' then
        
        -- send notification during the day
        if (timeofday['Daytime']) and (notify) then
            commandArray[indexArray] = {['SendNotification']=rainstr}
            indexArray=indexArray+1
        end
        
        -- change switch to OFF
        commandArray[indexArray] = {[rainswitchname]='Off'}
        indexArray=indexArray+1
    end

    -- logging end
    if (debug == 1) then
        print("+--------------------------------------------------+")
        print("| --------------------- END ---------------------- |")
        print("+--------------------------------------------------+")
    end

end

return commandArray

Re: Is it gonna rain within the next X minutes?

Posted: Tuesday 30 August 2016 23:44
by renerene
Thank you very much for this function. Has been working very well untill the point where I made some RAM drive folders, to prevent SD card wear.
To create the ramdrive the following line was added to fstab: "tmpfs /var/tmp tmpfs defaults,noatime,nosuid,mode=0777,size=30m 0 0"
Now lua cannot write the tempfile anymore. It just isnt there.
read = os.execute('curl -s -o '..tempfilename..' "'..url..'"') --> no juice :( .

suggestions :?: