I have a problem with my rain script, especially with the text switch which never changes.
this is my code.
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 = '52.65' -- your home latitude, set as a user variable
local longitude = '4.77' -- your home longtitude, set as a user variable
-- timewindow for prediction
local minutesinfuture = 30 -- (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 = 370 -- 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://gadgets.buienradar.nl/data/raintext?lat='..lat..'&lon='..lon"
-- 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
this is my error
Code: Select all
2017-04-18 21:05:00.479 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_rain.lua: /home/pi/domoticz/scripts/lua/script_time_rain.lua:165: bad argument #1 to 'sub' (string expected, got nil)
Does someone have any idea how to solve this?