setRainVar to rainfall in mm of last defined hours  [SOLVED]

Moderator: leecollings

Post Reply
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

setRainVar to rainfall in mm of last defined hours

Post by waaren »

Made it a separate topic: originated from a feature request in "updateWeatherSensors (yet another buienradar script)"

script will set a uservar with the the amount of rainfall in mm during a defined period in hours.

Code: Select all

-- setRainVar.lua for [ dzVents >= 2.4 ] 
-- Before first execution create var as type float and enter the deviceName or IDX of the raindevice

return {
    on      =   {   timer           =   { "every hour" },                       -- Triggers the getJsonPart
                    httpResponses   =   { "setRainVar" }                        -- Trigger the handle Json part
                },

    logging =   {   level     =   domoticz.LOG_ERROR,
                    marker    =   "setRainVar"    },

    execute = function(dz,trigger)

        local rainDevice    = dz.devices(nnn)                                 -- name enclosed in quotes or number without quotes
        local rainVar       = dz.variables("amountOfRainDuringLastHours")     -- name enclosed in quotes or number without quotes 
        local relevantHours = 12                                              -- below 24 day, above 23 year  
        local range         = "day"
        if relevantHours > 23 then range = "year" end 
        
               function isDevice(device)
            if device ~= nil then
                if device.deviceType == "General" then
                    return device.deviceSubType
                else
                    return device.deviceType
                end
            else
                return "device is not defined in domoticz"
            end
        end
        
        local function triggerJSON()
            local  URLString   = dz.settings['Domoticz url'] .. "/json.htm?type=graph&sensor=rain&idx=" .. rainDevice.idx .. "&range=" .. range 
            dz.openURL({    url = URLString,
                            method = "GET",
                            callback = "setRainVar" })                      
        end

        local function setVar()
            local Time = require('Time')
            local now  = Time()
            local relevantAmount = 0 
            local delta,t

            if trigger.json.result ~= nil then
                rt = trigger.json.result
            else
                dz.log("No values found in history. Put 0 in uservar",dz.LOG_DEBUG )
                rainVar.set(0)      -- Store 0 in uservariable
                return
            end            
            
            if range == "year" then timeCompletion = " 00:00:00" else timeCompletion = ":00" end
                
            for i=1,#rt do                                 -- Loop through the result
                t = Time(rt[i].d .. timeCompletion)        -- get time and prepare for compare
                delta = (t.compare(now).hours)             -- diff in hours between json record and now

                if delta <= relevantHours then
                    relevantAmount = relevantAmount + tonumber(rt[i].mm) 
                    dz.log(     "Date/time: " .. rt[i].d .. " ===>> Value in mm " .. 
                                rt[i].mm .. " ===>> Delta hours: "  .. delta .. 
                                " ===>> Total until now: " .. relevantAmount
                                ,dz.LOG_DEBUG)
                end    
            end
            if (rainVar.value ~= relevantAmount) or (rainVar.lastUpdate.hoursAgo > 12) then
                rainVar.set(relevantAmount)   -- Store value in uservariable
                dz.log("Set ".. rainVar.name .. " to: " .. relevantAmount,dz.LOG_DEBUG )
            end    
        end

        if isDevice(rainDevice) ~= "Rain" then 
           dz.log("Not a (valid) raindevice: " .. isDevice(rainDevice),dz.LOG_ERROR)    
           return 
        end
        
        if rainVar == nil or not(rainVar.isVariable) or rainVar.type ~= dz.FLOAT then
           dz.log("Not a (valid) rainVar",dz.LOG_ERROR)    
           return 
        end
        
        if trigger.isTimer or trigger.isDevice then
            triggerJSON()
        elseif trigger.ok and trigger.json.status ~= "ERR" then                                      -- statusCode == 2xx
            setVar()
        else
            dz.log("No valid response from domoticz; assuming rain = 0",dz.LOG_ERROR)    
            rainVar.set(0)      -- Store value in uservariable
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
cmartens75
Posts: 15
Joined: Monday 23 April 2018 10:43
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Netherlands
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by cmartens75 »

Hi Waaren, thanks for the script. I have a question. If I want to collect the rain during the last 24 hours, I have to change "local relevantHours" from "12" to "24" in the script. Besides that, I understand that I have to change "local range" from "day" to "year". Can you tell me why it is necessary to change the local range and what the impact is? Thanks in advance for your reaction.
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by waaren »

cmartens75 wrote: Saturday 29 December 2018 12:34 Hi Waaren, thanks for the script. I have a question. If I want to collect the rain during the last 24 hours, I have to change "local relevantHours" from "12" to "24" in the script. Besides that, I understand that I have to change "local range" from "day" to "year". Can you tell me why it is necessary to change the local range and what the impact is? Thanks in advance for your reaction.

You only have to manually change the amount of relevant hours. The change from day to year is done by the logic in the script. This does not require any further manual change.
The script gets the necessary data from the domoticz API that is internally used to produce the graphs.
The data for a day is more granular then the data for a week or year. ( this is related to the way domoticz stores historical data in domoticz.db)
See the examples below for day/week and year data

result of h ttp://PI-1:8084/json.htm?type=graph&sensor=rain&idx=782&range=day
Spoiler: show

Code: Select all

{
"result": [
{
"d": "2018-12-28 15:00",
"mm": "0.0"
},
{
"d": "2018-12-28 15:10:01",
"mm": "0.0"
},
{
"d": "2018-12-28 21:00",
"mm": "0.0"
},
{
"d": "2018-12-28 21:20:00",
"mm": "0.0"
},
{
"d": "2018-12-29 02:00",
"mm": "0.0"
},
{
"d": "2018-12-29 02:45:00",
"mm": "0.0"
},
{
"d": "2018-12-29 09:00",
"mm": "0.0"
}
],
"status": "OK",
"title": "Graph rain day"
}
result of h ttp://PI-1:8084/json.htm?type=graph&sensor=rain&idx=782&range=week
Spoiler: show

Code: Select all

{
"result": [
{
"d": "2018-12-22",
"mm": "7.1"
},
{
"d": "2018-12-23",
"mm": "11.4"
},
{
"d": "2018-12-24",
"mm": "11.4"
},
{
"d": "2018-12-25",
"mm": "0.0"
},
{
"d": "2018-12-26",
"mm": "0.0"
},
{
"d": "2018-12-27",
"mm": "0.0"
},
{
"d": "2018-12-28",
"mm": "0.0"
},
{
"d": "2018-12-29",
"mm": "0.0"
}
],
"status": "OK",
"title": "Graph rain week"
}
(partial) result of h ttp://PI-1:8084/json.htm?type=graph&sensor=rain&idx=782&range=year
Spoiler: show

Code: Select all

{
"result": [
{
"d": "2018-04-15",
"mm": "0.1"
},
{
"d": "2018-04-16",
"mm": "0.1"
},
{
"d": "2018-04-17",
"mm": "0.0"
},
....
{
"d": "2018-12-17",
"mm": "2.5"
},
{
"d": "2018-12-18",
"mm": "2.5"
},
{
"d": "2018-12-19",
"mm": "0.0"
},
{
"d": "2018-12-20",
"mm": "5.8"
},
{
"d": "2018-12-21",
"mm": "7.1"
},
{
"d": "2018-12-22",
"mm": "7.1"
},
{
"d": "2018-12-23",
"mm": "11.4"
},
{
"d": "2018-12-24",
"mm": "11.4"
},
{
"d": "2018-12-25",
"mm": "0.0"
},
{
"d": "2018-12-26",
"mm": "0.0"
},
{
"d": "2018-12-27",
"mm": "0.0"
},
{
"d": "2018-12-28",
"mm": "0.0"
},
{
"d": "2018-12-29",
"mm": "0.0"
}
],
"status": "OK",
"title": "Graph rain year"
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
cmartens75
Posts: 15
Joined: Monday 23 April 2018 10:43
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Netherlands
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by cmartens75 »

Thanks for your quick reaction and your clear answer.
janpeetoom
Posts: 12
Joined: Sunday 29 December 2019 12:07
Target OS: Linux
Domoticz version:
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by janpeetoom »

Hello Waaren.
How can I use this script?
I would like to use it as a trigger for the irrigation of my garden.
I have one switch witch power my waterpump for the irrigation named "Beregening".
I would like to have it switched on for one hour if the rainfall of the previous day is less than 2 mm.
How can I achieve this?
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by waaren »

janpeetoom wrote: Sunday 10 May 2020 16:29 I have one switch witch power my waterpump for the irrigation named "Beregening".
I would like to have it switched on for one hour if the rainfall of the previous day is less than 2 mm.
This should do it.

Code: Select all

local scriptVar = 'water the plants'

return 
{
    on =
    {
        timer =
        { 
            'at 09:00' -- change to the time you want to check the anmount of rain in the last 24 hours 
        },

        httpResponses =
        {
           scriptVar,
        },
    },

    logging =   
    {   
        level = domoticz.LOG_DEBUG, -- change to domoticz.LOG_ERROR when script works as expected
    },

    execute = function(dz, item)

        local rainDevice = dz.devices('myRain') -- name enclosed in quotes or number without quotes
        local waterPump = dz.devices('Beregening')
        
        if item.isDevice or item.isTimer then
            dz.openURL(
            {
                url = dz.settings['Domoticz url'] .. '/json.htm?type=graph&sensor=rain&idx=' .. rainDevice.idx .. '&range=day',
                callback = scriptVar,
            })
            return
        end
        
        local function getmm(rt)
            local mm = 0
            for index, record in ipairs(rt) do
                mm = mm + record.mm
            end
            return mm
        end
        
        if item.ok and item.isJSON then
            if getmm(item.json.result) < 2 then
                waterPump.cancelQueuedCommands()
                waterPump.switchOn()
                waterPump.switchOff().afterSec(3600)
                dz.log('Not enough rain in the last 24 hours. Switching on waterpump for 1 hour', dz.LOG_DEBUG)    
            else
                dz.log('Enough rain in the last 24 hours no need to switch on waterpump', dz.LOG_DEBUG)    
            end    
        else
            dz.log('No valid response from domoticz ',dz.LOG_ERROR)    
            dz.log(item,dz.LOG_ERROR)    
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
janpeetoom
Posts: 12
Joined: Sunday 29 December 2019 12:07
Target OS: Linux
Domoticz version:
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by janpeetoom »

Thanks for the pompt reply.
The problem is that I don't have a rainDevice. I would like to use "Buienradar"to predict the amount af rain that will fall the next 24 hours.
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by waaren »

janpeetoom wrote: Sunday 10 May 2020 18:48 Thanks for the pompt reply.
The problem is that I don't have a rainDevice. I would like to use "Buienradar"to predict the amount af rain that will fall the next 24 hours.
Sorry but I don't follow you.

In your earlier post you mentioned previous day. Now you write you want to use a forecast for the next 24 hours.
The Buienradar module will create a rain device fore you.
The Buienradar module does not give a prediction for more then 2 hours ahead.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
zavjah
Posts: 36
Joined: Tuesday 13 August 2019 10:20
Target OS: Raspberry Pi / ODroid
Domoticz version:

Re: setRainVar to rainfall in mm of last defined hours

Post by zavjah »

Hello waaren,

I've used your script from your post 246993 from Sunday 10 May 2020 18:14 and it works as a charm :-). Is there a way to set the range not oly for a day but for the last n days eg.?

thx,
zavjah
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by waaren »

zavjah wrote: Tuesday 23 June 2020 11:18 I've used your script from your post 246993 from Sunday 10 May 2020 18:14 and it works as a charm :-). Is there a way to set the range not only for a day but for the last n days eg.?
Yes,

could look like below

Code: Select all

local scriptVar = 'water the plants'

return
{
    on =
    {
        timer =
        {
            'at 09:09', -- change to the time you want to check the amount of rain in the set number of days
        },

        httpResponses =
        {
           scriptVar,
        },
    },

    logging =
    {
        level = domoticz.LOG_DEBUG, -- change to domoticz.LOG_ERROR when script works as expected
    },

    execute = function(dz, item)

        local minAmount = 2 -- in mm rain
        local daysToEvaluate = 5 -- in days

        local rainDevice = dz.devices('myRain') -- name enclosed in quotes or number without quotes
        local waterPump = dz.devices('Beregening')

        if item.isDevice or item.isTimer then
            dz.openURL(
            {
                url = dz.settings['Domoticz url'] .. '/json.htm?type=graph&sensor=rain&idx=' .. rainDevice.idx .. '&range=month',
                callback = scriptVar,
            })
            return
        end

        local function getmm(rt)
            local startDate = (dz.time.addMinutes(-1 * daysToEvaluate * 24 * 60)).rawDate
            local mm = 0
            dz.log('startDate: ' .. startDate, dz.LOG_DEBUG)
            for index, record in ipairs(rt) do
                if record.d > startDate then
                    mm = mm + record.mm
                end
            end
            return mm
        end

        if item.ok and item.isJSON then
            local mmRain = getmm(item.json.result, days )
            if mmRain < minAmount then

                waterPump.cancelQueuedCommands()
                waterPump.switchOn()
                waterPump.switchOff().afterSec(3600)
                dz.log('Not enough rain in the last ' .. daysToEvaluate .. ' days (' .. mmRain .. ' mm). Switching waterpump on for 1 hour', dz.LOG_DEBUG)
            else
                 dz.log('Enough rain in the last ' .. daysToEvaluate .. ' days (' .. mmRain .. 'mm). No need to turn on waterpump.', dz.LOG_DEBUG)
            end
        else
            dz.log('No valid response from domoticz ',dz.LOG_ERROR)
            dz.log(item,dz.LOG_ERROR)
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
zavjah
Posts: 36
Joined: Tuesday 13 August 2019 10:20
Target OS: Raspberry Pi / ODroid
Domoticz version:

Re: setRainVar to rainfall in mm of last defined hours

Post by zavjah »

AWESOME, thank you very much 😀
sailmich
Posts: 232
Joined: Wednesday 17 February 2016 22:55
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Germany
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by sailmich »

waaren wrote: Sunday 10 May 2020 18:14
janpeetoom wrote: Sunday 10 May 2020 16:29 I have one switch witch power my waterpump for the irrigation named "Beregening".
I would like to have it switched on for one hour if the rainfall of the previous day is less than 2 mm.
This should do it.

Code: Select all

local scriptVar = 'water the plants'

return 
{
    on =
    {
        timer =
        { 
            'at 09:00' -- change to the time you want to check the anmount of rain in the last 24 hours 
        },

        httpResponses =
        {
           scriptVar,
        },
    },

    logging =   
    {   
        level = domoticz.LOG_DEBUG, -- change to domoticz.LOG_ERROR when script works as expected
    },

    execute = function(dz, item)

        local rainDevice = dz.devices('myRain') -- name enclosed in quotes or number without quotes
        local waterPump = dz.devices('Beregening')
        
        if item.isDevice or item.isTimer then
            dz.openURL(
            {
                url = dz.settings['Domoticz url'] .. '/json.htm?type=graph&sensor=rain&idx=' .. rainDevice.idx .. '&range=day',
                callback = scriptVar,
            })
            return
        end
        
        local function getmm(rt)
            local mm = 0
            for index, record in ipairs(rt) do
                mm = mm + record.mm
            end
            return mm
        end
        
        if item.ok and item.isJSON then
            if getmm(item.json.result) < 2 then
                waterPump.cancelQueuedCommands()
                waterPump.switchOn()
                waterPump.switchOff().afterSec(3600)
                dz.log('Not enough rain in the last 24 hours. Switching on waterpump for 1 hour', dz.LOG_DEBUG)    
            else
                dz.log('Enough rain in the last 24 hours no need to switch on waterpump', dz.LOG_DEBUG)    
            end    
        else
            dz.log('No valid response from domoticz ',dz.LOG_ERROR)    
            dz.log(item,dz.LOG_ERROR)    
        end
    end
}
I would like to add average temperature from the day before to increase or decrease the amount of water, by switching on time length of the pump. I assume I have to use avgSince but I don't get it how and were in the code it should be in. '/json.htm?type=graph&sensor=temp&idx=' .. tempDevice.idx .. '&range=day', shows 180-182 data points with temperature. With a calculator it's simple for me but takes time to get the average, with code I can't solve it :oops:
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by waaren »

sailmich wrote: Tuesday 25 August 2020 10:59 I would like to add average temperature from the day before to increase or decrease the amount of water, by switching on time length of the pump. I assume I have to use avgSince but I don't get it how and were in the code it should be in. '/json.htm?type=graph&sensor=temp&idx=' .. tempDevice.idx .. '&range=day', shows 180-182 data points with temperature. With a calculator it's simple for me but takes time to get the average, with code I can't solve it :oops:
To get the average temperature you could do something like below.

Code: Select all

local scriptVar = 'water the plants'
local averageTemp = 'at 05:05' -- time to get the average of the last 24 hours

return
{
    on =
    {
        timer =
        {
            averageTemp, -- time to collect yesterday average temp
            'at 09:00' -- change to the time you want to check the amount of rain in the last 24 hours
        },

        httpResponses =
        {
           scriptVar,
        },
    },

    data =
    {
        averageTemp =
        {
            initial = 0,
        },
    },

    logging =
    {
        level = domoticz.LOG_DEBUG, -- change to domoticz.LOG_ERROR when script works as expected
    },

    execute = function(dz, item)

        local rainDevice = dz.devices('myRain') -- name enclosed in quotes or number without quotes
        local waterPump = dz.devices('Beregening')
        local temperatureSensor = dz.devices('Your temperature sensor name') -- change this to your sensor name


        if item.isDevice or item.isTimer then
            if dz.time.matchesRule(averageTemp) then
                dz.openURL(
                {
                    url = dz.settings['Domoticz url'] .. '/json.htm?type=graph&sensor=temp&idx=' .. temperatureSensor.idx .. '&range=day' ,
                    callback = scriptVar,
                })
            else
                dz.openURL(
                {
                    url = dz.settings['Domoticz url'] .. '/json.htm?type=graph&sensor=rain&idx=' .. rainDevice.idx .. '&range=day',
                    callback = scriptVar,
                })
            end
            return
        end

        local function getmm(rt)
            local mm = 0
            for index, record in ipairs(rt) do
                mm = mm + record.mm
            end
            return mm
        end

        local function getAverageTemp(rt)
            local totalTemperature = 0
            for _,  record in ipairs(rt) do
                totalTemperature = totalTemperature + record.te
            end
            return dz.utils.round(totalTemperature / #rt, 2 )
        end


        if item.ok and item.isJSON then
            if dz.time.matchesRule(averageTemp) then
                dz.data.averageTemp = getAverageTemp(item.json.result) -- this will store the averageTemperature in dz.data.averageTemp for future use
            elseif getmm(item.json.result) < 2 then
                -- you can use dz.data.averageTemp in this block
                waterPump.cancelQueuedCommands()
                waterPump.switchOn()
                waterPump.switchOff().afterSec(3600)
                dz.log('Not enough rain in the last 24 hours. Switching on waterpump for 1 hour', dz.LOG_DEBUG)
            else
                dz.log('Enough rain in the last 24 hours no need to switch on waterpump', dz.LOG_DEBUG)
            end
        else
            dz.log('No valid response from domoticz ',dz.LOG_ERROR)
            dz.log(item,dz.LOG_ERROR)
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
sailmich
Posts: 232
Joined: Wednesday 17 February 2016 22:55
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Germany
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by sailmich »

@waaren fantastic I really spent hours to change the code from mm to Celsius without success. Your code now is running on my system and make sure that my garden get the needed water. Thank you very much for this. If you have time I put some questions in the code below. I would appreciate if you may answer them. Cheers
Spoiler: show

Code: Select all

local function getAverageTemp(rt)
            local totalTemperature = 0
            for _,  record in ipairs(rt) do --What is _ for ?
                totalTemperature = totalTemperature + record.te	--Is record.te the sum of all temperature datas in the record? 
            end
            return dz.utils.round(totalTemperature / #rt, 2 ) --Is #rt numbers of data points in the record?  
        end
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by waaren »

sailmich wrote: Wednesday 26 August 2020 9:29 If you have time I put some questions in the code below. I would appreciate if you may answer them.

Code: Select all

local function getAverageTemp(rt)
	local totalTemperature = 0
	for _,  record in ipairs(rt) do --What is _ for ?
		totalTemperature = totalTemperature + record.te	--Is record.te the sum of all temperature datas in the record? 
	end
	return dz.utils.round(totalTemperature / #rt, 2 ) --Is #rt numbers of data points in the record?  
end
rt is the result table the script gets when sending the /json.htm?type=graph&sensor=temp&range=day&idx=<Sensor IDX>
The temperatures are stored every 5 minutes in the short term history table so you will have at least about 24 * 12 = 288 records.

the

Code: Select all

for _,  record in ipairs(rt) do
loops over all records in rt. In every cycle of that loop, record gets the content of that record and _ gets the index (not used here)
In temperature sensor records there are at least two key-value combinations; key "d" containing the date/time and "te" containing the temperature
(some other types also contain barometer and humidity key-value sets)

You refer to a value in a table by using the key. In this case record.te gives you the temperature in that record.
#rt is the number of records in the rt table

To summarize: the function getAverageTemp sums all temperatures for a sensor returned from the json and divide this total by the number of records.

-----------------------------------------------------------------------------------------

There could be an issue with this if you have set the Short Log Sensor setting to a value > 1, the json will then return also values older then 1 day. Because of this the function can be better modified a bit to

Code: Select all

        local function getAverageTemp(rt, hours) -- hours defaults to 24
            local hours = ( hours or 24 ) * -1 
            local startTime = dz.time.addHours(hours).rawDateTime
            local relevantTemperatures = 0
            local totalTemperature = 0

            for _,  record in ipairs(rt) do
                if record.d >= startTime then
                    totalTemperature = totalTemperature + record.te
                    relevantTemperatures = relevantTemperatures + 1
                end
            end

            return dz.utils.round(totalTemperature / relevantTemperatures, 2 )
        end
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
sailmich
Posts: 232
Joined: Wednesday 17 February 2016 22:55
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Germany
Contact:

Re: setRainVar to rainfall in mm of last defined hours  [SOLVED]

Post by sailmich »

@waaren Thx for the explanation! Short Time Log is set for just one day but I put the new code inside, all is running as espected. Cheers
Spoiler: show

Code: Select all

--[[This script is for watering my garden according to the amount of rainfall and the average temperature within the last 24 hours. Needs a rain device, a outside temperature sensor and e.g. a plug for water pump. Many thanks @waaren!]]

local scriptVar = 'water the plants'
local averageTemp = 'at 05:45'              -- time to get the average of the last 24 hours
local amountRain = 'at 06:00'               -- change to the time you want to check the amount of rain in the last 24 hours. Must be later than local averageTemp!
local autModeDate = 'on 01/05-01/10'        -- change to the date the garden should get watering
local trigAmoRain = 2                       -- change to the amount of rain in mm when watering should start  
local durDry = 1800                         -- duration of watering in seconds for warm temperature 
local durVeryDry = 2700                     -- duration of watering in seconds for very warm temperature
local durExtremDry = 3600                   -- duration of watering in seconds for hot temperature
local trigWarm = 15                         -- temperature trigger for warm weather
local trigVeryWarm = 20                     -- temperature trigger for very warm weather
local trigHot = 25                          -- temperature trigger for hot weather


return
{
    on =
    {
        timer =
        {
            averageTemp, 
            amountRain   
        },

        httpResponses =
        {
           scriptVar,
        },
    },

    data =
    {
        averageTemp =
        {
            initial = 0,
        },
    },

    logging =
    {
        level = domoticz.LOG_ERROR, -- change to domoticz.LOG_ERROR instead of LOG_DEBUG when script works as expected
    },

    execute = function(dz, item)
        local rainDevice = dz.devices('Regen') -- change this to your sensor name enclosed in quotes or Idx number without quotes
        local waterPump = dz.devices('Wandstecker') -- change this to your device name enclosed in quotes or Idx number without quotes
        local temperatureSensor = dz.devices('WetterAußen') -- change this to your sensor name enclosed in quotes or Idx number without quotes
        


        if item.isDevice or item.isTimer then
            if dz.time.matchesRule(averageTemp) then
                dz.openURL(
                {
                    url = dz.settings['Domoticz url'] .. '/json.htm?type=graph&sensor=temp&idx=' .. temperatureSensor.idx .. '&range=day' ,
                    callback = scriptVar,
                })
            else
                dz.openURL(
                {
                    url = dz.settings['Domoticz url'] .. '/json.htm?type=graph&sensor=rain&idx=' .. rainDevice.idx .. '&range=day',
                    callback = scriptVar,
                })
            end
            return
        end

        local function getmm(rt)
            local mm = 0
            for index, record in ipairs(rt) do
                mm = mm + record.mm
            end
            return mm
        end
        
        local function getAverageTemp(rt, hours) -- hours defaults to 24
            local hours = ( hours or 24 ) * -1 
            local startTime = dz.time.addHours(hours).rawDateTime
            local relevantTemperatures = 0
            local totalTemperature = 0

            for _,  record in ipairs(rt) do
                if record.d >= startTime then
                    totalTemperature = totalTemperature + record.te
                    relevantTemperatures = relevantTemperatures + 1
                end
            end

            return dz.utils.round(totalTemperature / relevantTemperatures, 2 )
        end

        if item.ok and item.isJSON and dz.time.matchesRule(autModeDate) then
            if dz.time.matchesRule(averageTemp) then
                dz.data.averageTemp = getAverageTemp(item.json.result) -- this will store the averageTemperature in dz.data.averageTemp for future use
                dz.log('Average Temperature = '.. dz.data.averageTemp ..' Grad',dz.LOG_DEBUG)
            elseif getmm(item.json.result) < trigAmoRain and dz.data.averageTemp > trigHot then
                waterPump.cancelQueuedCommands()
                waterPump.switchOn()
                waterPump.switchOff().afterSec(durExtremDry)
                dz.log('Not enough rain in the last 24 hours. Switching on waterpump for '.. durExtremDry .. ' seconds', dz.LOG_DEBUG)
            elseif getmm(item.json.result) < trigAmoRain and dz.data.averageTemp > trigVeryWarm then
                waterPump.cancelQueuedCommands()
                waterPump.switchOn()
                waterPump.switchOff().afterSec(durVeryDry)
                dz.log('Not enough rain in the last 24 hours. Switching on waterpump for '.. durVeryDry .. ' seconds', dz.LOG_DEBUG)
            elseif getmm(item.json.result) < trigAmoRain and dz.data.averageTemp > trigWarm then
                waterPump.cancelQueuedCommands()
                waterPump.switchOn()
                waterPump.switchOff().afterSec(durDry)
                dz.log('Not enough rain in the last 24 hours. Switching on waterpump for ' .. durDry .. ' seconds', dz.LOG_DEBUG)
            else
                dz.log('Enough rain in the last 24 hours no need to switch on waterpump', dz.LOG_DEBUG)
            end
        else
            dz.log('No valid response from domoticz ',dz.LOG_ERROR)
            dz.log(item,dz.LOG_ERROR)
        end
    end
}
Dickey
Posts: 25
Joined: Friday 19 April 2019 22:29
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Netherlands
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by Dickey »

I'm using this script for a few day's now, but today something strange happend. I've got a negative amount of rain last night. :D

I'm using the amount of rain from the buienradar plugin and have Schiphol Amsterdam ( 6240 ) as station. The log file shows a negative value as well.

Any idea's?
Dz-beta | Dashticz 3.8.10 BETA | Tradfri | RF-Link | Z-Wave | Harmony | Unify | P1 |
sailmich
Posts: 232
Joined: Wednesday 17 February 2016 22:55
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Germany
Contact:

Re: setRainVar to rainfall in mm of last defined hours

Post by sailmich »

Rpi3 Zstick newest beta
I noticed also negative amounts of rain. I didn't change the code since my last post. Without that negative amount watering wouldn't start! If there is no explanation for negative amounts Is there code to ignore negative amounts?
Spoiler: show

Code: Select all

{
	"result" : 
	[
		{
			"d" : "2021-06-05 08:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 09:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 10:00",
			"mm" : "0.3"
		},
		{
			"d" : "2021-06-05 11:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 12:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 13:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 14:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 15:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 16:00",
			"mm" : "0.6"
		},
		{
			"d" : "2021-06-05 17:00",
			"mm" : "0.3"
		},
		{
			"d" : "2021-06-05 18:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 19:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 20:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 21:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 22:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-05 23:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-06 00:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-06 01:00",
			"mm" : "-1.2"
		},
		{
			"d" : "2021-06-06 02:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-06 03:00",
			"mm" : "0.3"
		},
		{
			"d" : "2021-06-06 04:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-06 05:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-06 06:00",
			"mm" : "0.0"
		},
		{
			"d" : "2021-06-06 07:00",
			"mm" : "0.0"
		}
	],
	"status" : "OK",
	"title" : "Graph rain day"
}
Bildschirmfoto vom 2021-06-06 07-55-58.png
Bildschirmfoto vom 2021-06-06 07-55-58.png (56.15 KiB) Viewed 7617 times
What amount of rain is showing on the device? The amount of last 24 hours or the last bigger than zero?
Bildschirmfoto vom 2021-06-06 07-56-45.png
Bildschirmfoto vom 2021-06-06 07-56-45.png (11.22 KiB) Viewed 7617 times
Thanks for any help
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest