Page 1 of 1

script to predict storm

Posted: Monday 17 February 2020 16:53
by Gravityz
Hello,
i made a little script which checks a barometer drop or rise thus predicting the chance of a storm or hard wind.

i however got a couple of problems

every hour i record the value in a historical record but the initial value does not seem to be set to 0(thus causing problems)
also dz.utils.round(dz.data.pressure.get(12).data,1) does not seem to work (nil error but initial should be 0)
how can i initialize a local value to 0 when the value in the historical record is nill and causing an error


here is the script

Code: Select all

return {
          on   = { timer    = { 'Every minute'}},
	data = {
		pressure = { history = true, maxItems = 12, initial = 0 }
	},
	
    execute = function(dz, trigger)
    local myNotificationTable   = {dz.NSS_Telegram}
    local sensor = dz.devices('Barometer')
    
    if dz.data.pressure.getOldest() == nil then  -- Check if history is already filled (initial does not work with history persistent data
       dz.data.pressure.add(10)
    end

		local twelvehourpressure = dz.utils.round(dz.data.pressure.getOldest().data,1)
		local threehourpressure = dz.utils.round(dz.data.pressure.get(3).data,1)
		local currentpressure = dz.utils.round(sensor.barometer,1)
		local threehourdelta = 0
		local twelvehourdelta = 0

		local threehourdelta = threehourpressure - currentpressure
		local twelvehourdelta = twelvehourpressure - currentpressure
		
		-- severe storm warning barometer drop
		if ((twelvehourdelta >= 8 or threehourdelta >= 0) and currentpressure < 1011) then
		local notifyString = "Sterke luchtdruk daling".."\r\n".."luchtdruk is "..currentpressure.."hPa".."\r\n".."Kans op zware storm"
		dz.notify("Weather forecast", notifyString, dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable )
    end
    
        -- storm warning barometer rise
        if threehourdelta <= -3 then
		local notifyString = "Sterke luchtdruk daling".."\r\n".."luchtdruk is "..currentpressure.."hPa".."\r\n".."Kans op harde wind"
		dz.notify("Weather forecast", notifyString, dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable )
    end
    
		
		-- add new data
		dz.data.pressure.add(sensor.barometer)

end
}

Re: script to predict storm

Posted: Monday 17 February 2020 19:01
by EdwinK
I'm no scripter, but shouldn't line 2 read:

Code: Select all

                      on      =   {   timer       =   { "every hour"  } }, 

see the double quotation marks.

Also line 31 looks to be wrong, although I can't exactly tell what it is, with my little knowledge.
2020-02-17 19:08:21.130 Error: dzVents: Error: (3.0.0) error loading module 'Storm' from file '/home/pi/domoticz/scripts/dzVents/generated_scripts/Storm.lua':
2020-02-17 19:08:21.130 .../pi/domoticz/scripts/dzVents/generated_scripts/Storm.lua:31: 'then' expected near '='

Re: script to predict storm

Posted: Monday 17 February 2020 19:12
by Gravityz
you are right.

was a typo, change it
timer should still work, i see examples with both " and '

the problem is that the historical initial value is nill instead of 0

Re: script to predict storm

Posted: Monday 17 February 2020 19:25
by Gravityz
i changed it and now it works but i need to fill the history first to avoid the nill error

Re: script to predict storm

Posted: Monday 17 February 2020 19:37
by waaren
Gravityz wrote: Monday 17 February 2020 16:53 Hello,
i made a little script which checks a barometer drop or rise thus predicting the chance of a storm or hard wind.
i however got a couple of problems
You already had the code to initialize but there are other methods of the historical persistent data you can use for this type of script

Please have a look at the script below. save it with a different name or make sure you remove the data file of your script, as it might cause a conflict with the data from this script.

Code: Select all

return
{
    on =
    {
        timer =
        {
            'Every hour',
        }
    },

    data =
    {
        pressure =
        {
            history = true,
            maxItems = 14,
        },
    },

    logging =
    {
        level = domoticz.LOG_DEBUG,
        marker = 'storm'
    },


    execute = function(dz, trigger)
        local myNotificationTable   = {dz.NSS_Telegram}
        local sensor = dz.devices('Barometer')

        local threehourpressure, threehourdelta, twelvehourpressure, twelvehourdelta

        local currentpressure = dz.utils.round(sensor.barometer,1)

        if dz.data.pressure.getOldest() == nil then  -- Check if history is already filled (initial does not work with history persistent data
           dz.data.pressure.add(0)
        end

        local function handle3Hours()
            threehourpressure = dz.data.pressure.getAtTime('03:00:00')
            if threehourpressure == nil then return end
            threehourdelta = threehourpressure.data - currentpressure
            -- storm warning barometer rise
            if threehourdelta <= -3 then
                local notifyString = "Sterke luchtdruk daling".."\r\n".."luchtdruk is "..currentpressure.."hPa".."\r\n".."Kans harde wind"
                dz.notify("Weather forecast", notifyString, dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable )
            end
        end

        local function handle12Hours()
            twelvehourpressure = dz.data.pressure.getAtTime('12:00:00')
            if twelvehourpressure == nil then return end
            twelvehourdelta = twelvehourpressure.data - currentpressure
            if ((twelvehourdelta >= 8 or threehourdelta >= 3) and currentpresure < 1005) then
                local notifyString = "Sterke luchtdruk daling".."\r\n".."luchtdruk is "..currentpressure.."hPa".."\r\n".."Kans op zware storm"
                dz.notify("Weather forecast", notifyString, dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable )
            end
        end

        if dz.data.pressure.size < 13 then
            dz.log('Not enough data points yet for twelve hour delta', dz.LOG_DEBUG)
            if dz.data.pressure.size < 4 then
                dz.log('Not enough data points yet for three hour delta', dz.LOG_DEBUG)
            else
                handle3Hours()
            end
        else
            handle3Hours()
            handle12Hours()
        end

        -- add new data
        dz.data.pressure.add(currentpressure)

        local entries = dz.data.pressure
        entries.forEach(function (entry)
            dz.log('data: ' .. entry.data .. ' was stored at ' .. entry.time.rawDateTime, dz.LOG_DEBUG)
        end)
    end
}

Re: script to predict storm

Posted: Monday 17 February 2020 21:13
by Gravityz
thanks.

looks a lot bigger than my version :-)

one question
i tried tuse variables like 3hourpressure or 3hourdelta but that seems not permitted, Why?

Re: script to predict storm

Posted: Monday 17 February 2020 21:19
by waaren
Gravityz wrote: Monday 17 February 2020 21:13 looks a lot bigger then my version :-)
That's because of the checks to prevent errors stopping the script processing. :)
one question
i tried tuse variables like 3hourpressure or 3hourdelta but that seems not permitted, Why?
Lua variables cannot start with a digit

Re: script to predict storm

Posted: Tuesday 18 February 2020 10:19
by EdwinK
Now let's wait for a storm to come so we can see if it works ;)

Re: script to predict storm

Posted: Tuesday 18 February 2020 16:24
by Gravityz
yes.
i only put 2 checks in there (rapid drop and rapid rise).

we had 2 storms last week the 3hour drop of 3 is probably to high but the 8 hPa drop in 12 hours was a reality

Re: script to predict storm

Posted: Tuesday 18 February 2020 16:29
by Gravityz
@waaren
checked the timestamp but after 16:00 the first entry in the data has the timestamp 15:00
time in domoticz and on synology is accurate.
also the timestamp of the datafile is 16:00
as far as i can see the script is triggered every hour so at 16:00 the data is written to the file at the end of the script so it should state 16:00 as well

functionality wise this should not matter but it would be nice if the timestamp matches with the current time

Re: script to predict storm

Posted: Tuesday 18 February 2020 16:57
by waaren
Gravityz wrote: Tuesday 18 February 2020 16:29 as far as i can see the script is triggered every hour so at 16:00 the data is written to the file at the end of the script so it should state 16:00 as well
functionality wise this should not matter but it would be nice if the timestamp matches with the current time
That is because historical storage use UTC by design. There should not be a requirement to use this directly. All access should go via the dzVents API which will take care of the conversion to local time.

Re: script to predict storm

Posted: Tuesday 18 February 2020 17:03
by Gravityz
clear. thanks. I learn new things every day. :-)

Re: script to predict storm  [Solved]

Posted: Sunday 23 February 2020 17:31
by Gravityz
Tested it (we had a storm again in the netherlands)
works perfectly

it sends out a message through telegram when there is either a drop in pressure or a rise(both create hard winds)
i raised the delta for the 3hour measurement to 4.

i also noticed that when you have a big drop within the hour you get storms as well
However it makes no sense to detect this because by the time you get the warning you are already experiencing the bad weather.

Code: Select all

return
{
    on =
    {
        timer =
        {
            'Every hour',
        }
    },

    data =
    {
        pressure =
        {
            history = true,
            maxItems = 14,
        },
    },

    logging =
    {
        level = domoticz.LOG_DEBUG,
        marker = 'storm'
    },


    execute = function(dz, trigger)
        local myNotificationTable   = {dz.NSS_Telegram}
        local sensor = dz.devices('Barometer')

        local threehourpressure, threehourdelta, twelvehourpressure, twelvehourdelta

        local currentpressure = dz.utils.round(sensor.barometer,1)

        if dz.data.pressure.getOldest() == nil then  -- Check if history is already filled (initial does not work with history persistent data
           dz.data.pressure.add(0)
        end

        local function handle3Hours()
            threehourpressure = dz.data.pressure.getAtTime('03:00:00')
            if threehourpressure == nil then return end
            threehourdelta = threehourpressure.data - currentpressure
            -- storm warning barometer rise
            if threehourdelta <= -4 then
                local notifyString = "Sterke luchtdruk stijging".."\r\n".."luchtdruk is "..currentpressure.." hPa".."\r\n".."Kans op harde wind"
                dz.notify("Weather forecast", notifyString, dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable )
            end
        end

        local function handle12Hours()
            twelvehourpressure = dz.data.pressure.getAtTime('12:00:00')
            if twelvehourpressure == nil then return end
            twelvehourdelta = twelvehourpressure.data - currentpressure
            if ((twelvehourdelta >= 8 or threehourdelta >= 4) and currentpressure < 1005) then
                local notifyString = "Sterke luchtdruk daling".."\r\n".."luchtdruk is "..currentpressure.." hPa".."\r\n".."Kans op zware storm"
                dz.notify("Weather forecast", notifyString, dz.PRIORITY_NORMAL,dz.SOUND_DEFAULT, "" , myNotificationTable )
            end
        end

        if dz.data.pressure.size < 13 then
            dz.log('Not enough data points yet for twelve hour delta', dz.LOG_DEBUG)
            if dz.data.pressure.size < 4 then
                dz.log('Not enough data points yet for three hour delta', dz.LOG_DEBUG)
            else
                handle3Hours()
            end
        else
            handle3Hours()
            handle12Hours()
        end

        -- add new data
        dz.data.pressure.add(currentpressure)

        local entries = dz.data.pressure
        entries.forEach(function (entry)
            dz.log('data: ' .. entry.data .. ' was stored at ' .. entry.time.rawDateTime, dz.LOG_DEBUG)
        end)
    end
}
barometer.JPG
barometer.JPG (74.99 KiB) Viewed 1159 times