My dzVents Wind Monitoring script

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

My dzVents Wind Monitoring script

Post by BakSeeDaa »

Hey guys.

I'd like to share my dzVents Wind Monitoring script.

The idea is to provide info about the strongest seen wind gust level for the last 30 minutes and display it in an Alert Device.

I have a wind speed meter (WIND_DEVICE) that is reporting the wind speed to Domoticz regularly. (It might not report if the wind conditions haven't changed since last time) The virtual Domoticz Alert Device will display the current wind conditions and an alert level allowing to automate tasks like the automatic retraction of my window awnings etc.

Code: Select all

--[[
windMonitoring.lua by BakSeeDaa
Version 1.0.2
--]]
local WIND_DATA_MAX_AGE = 30
local ALERT_SENSOR = 'Wind Alert'
local WIND_DEVICE = 'WH2600 Wind'

local WIND_HURRICANE_TEXT = 'Orkan. Mer än 32,7 m/s'
local WIND_VIOLENT_STORM_TEXT = 'Svår storm. 28,5–32,6 m/s'
local WIND_STORM_TEXT = 'Storm. 24,5–28,4 m/s'
local WIND_STRONG_GALE_TEXT = 'Halv storm. 20,8–24,4 m/s'
local WIND_FRESH_GALE_TEXT = 'Hård kuling. 17,2–20,7 m/s'
local WIND_MODERATE_GALE_TEXT = 'Styv kuling. 13,9–17,1 m/s'
local WIND_STRONG_BREEZE_TEXT = 'Hård bris. 10,8–13,8 m/s'
local WIND_FRESH_BREEZE_TEXT = 'Styv bris. 8,0–10,7 m/s'
local WIND_MODERATE_BREEZE_TEXT = 'Frisk bris. 5,5–7,9 m/s'
local WIND_GENTLE_BREEZE_TEXT = 'God bris. 3,4–5,4 m/s'
local WIND_CALM_TO_LIGHT_BREEZE_TEXT = 'Stiltje till lätt bris. 0–3,3 m/s'
local WIND_HURRICANE_LEVEL = 32.7
local WIND_VIOLENT_STORM_LEVEL = 28.5
local WIND_STORM_LEVEL = 24.5
local WIND_STRONG_GALE_LEVEL = 20.8
local WIND_FRESH_GALE_LEVEL = 17.2
local WIND_MODERATE_GALE_LEVEL = 13.9
local WIND_STRONG_BREEZE_LEVEL = 10.8
local WIND_FRESH_BREEZE_LEVEL = 8
local WIND_MODERATE_BREEZE_LEVEL = 5.5
local WIND_GENTLE_BREEZE_LEVEL = 3.4

return {
	active = true,
	on = {
		WIND_DEVICE,
		['timer'] = 'every minute'
	},
	data = {
		lastSeenHurricane = { history = true, maxItems = 1 },
		lastSeenViolentStorm = { history = true, maxItems = 1 },
		lastSeenStorm = { history = true, maxItems = 1 },
		lastSeenStrongGale = { history = true, maxItems = 1 },
		lastSeenFreshGale = { history = true, maxItems = 1 },
		lastSeenModerateGale = { history = true, maxItems = 1 },
		lastSeenStrongBreeze = { history = true, maxItems = 1 },
		lastSeenFreshBreeze = { history = true, maxItems = 1 },
		lastSeenModerateBreeze = { history = true, maxItems = 1 },
		lastSeenGentleBreeze = { history = true, maxItems = 1 }
	},
	execute = function(domoticz, windDevice, triggerInfo)
		local LOG_LEVEL = domoticz.LOG_DEBUG -- Script default log level. You may change this.
		if (triggerInfo.type == domoticz.EVENT_TYPE_TIMER) then
			-- Timer event occurred

			-- Init data if missing (e.g. the first time that the scripts runs)
			-- Note that all wind speeds initially will have the current time as "Last Seen", it will cause an alert.
			if (domoticz.data['lastSeenHurricane'].size == 0) then domoticz.data['lastSeenHurricane'].add('Init') end
			if (domoticz.data['lastSeenViolentStorm'].size == 0) then domoticz.data['lastSeenViolentStorm'].add('Init') end
			if (domoticz.data['lastSeenStorm'].size == 0) then domoticz.data['lastSeenStorm'].add('Init') end
			if (domoticz.data['lastSeenStrongGale'].size == 0) then domoticz.data['lastSeenStrongGale'].add('Init') end
			if (domoticz.data['lastSeenFreshGale'].size == 0) then domoticz.data['lastSeenFreshGale'].add('Init') end
			if (domoticz.data['lastSeenModerateGale'].size == 0) then domoticz.data['lastSeenModerateGale'].add('Init') end
			if (domoticz.data['lastSeenStrongBreeze'].size == 0) then domoticz.data['lastSeenStrongBreeze'].add('Init') end
			if (domoticz.data['lastSeenFreshBreeze'].size == 0) then domoticz.data['lastSeenFreshBreeze'].add('Init') end
			if (domoticz.data['lastSeenModerateBreeze'].size == 0) then domoticz.data['lastSeenModerateBreeze'].add('Init') end
			if (domoticz.data['lastSeenGentleBreeze'].size == 0) then domoticz.data['lastSeenGentleBreeze'].add('Init') end

			-- Update the Wind Alert virtual sensor
			local alertLevel = domoticz.ALERTLEVEL_GREY
			local alertText = WIND_CALM_TO_LIGHT_BREEZE_TEXT
			local alertSensor = domoticz.devices[ALERT_SENSOR]
			if (domoticz.data['lastSeenHurricane'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_RED
				alertText = WIND_HURRICANE_TEXT
			elseif (domoticz.data['lastSeenViolentStorm'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_RED
				alertText = WIND_VIOLENT_STORM_TEXT
			elseif (domoticz.data['lastSeenStorm'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_RED
				alertText = WIND_STORM_TEXT
			elseif (domoticz.data['lastSeenStrongGale'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_ORANGE
				alertText = WIND_STRONG_GALE_TEXT
			elseif (domoticz.data['lastSeenFreshGale'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_ORANGE
				alertText = WIND_FRESH_GALE_TEXT
			elseif (domoticz.data['lastSeenModerateGale'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_YELLOW
				alertText = WIND_MODERATE_GALE_TEXT
			elseif (domoticz.data['lastSeenStrongBreeze'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_YELLOW
				alertText = WIND_STRONG_BREEZE_TEXT
			elseif (domoticz.data['lastSeenFreshBreeze'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_GREEN
				alertText = WIND_FRESH_BREEZE_TEXT
			elseif (domoticz.data['lastSeenModerateBreeze'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_GREEN
				alertText = WIND_MODERATE_BREEZE_TEXT
			elseif (domoticz.data['lastSeenGentleBreeze'].getLatest().time.minutesAgo < WIND_DATA_MAX_AGE) then
				alertLevel = domoticz.ALERTLEVEL_GREY
				alertText = WIND_GENTLE_BREEZE_TEXT
			end
			domoticz.log('alertSensor.rawData[1]: '..alertSensor.rawData[1], LOG_LEVEL)
			domoticz.log('alertText: '..alertText, LOG_LEVEL)
			if(alertSensor.rawData[1] ~= alertText) then
				alertSensor.updateAlertSensor(alertLevel, alertText)
			end
		else
			-- Device event occurred
			local sWindDirectionDegrees = tonumber(windDevice.rawData[1])
			local sWindDirection = windDevice.rawData[2]
			local sWindSpeed = tonumber(windDevice.rawData[3]) * 0.1
			local sWindGust = tonumber(windDevice.rawData[4]) * 0.1
			local sWindTemperature = tonumber(windDevice.rawData[5])
			local sWindChill = tonumber(windDevice.rawData[6])

			domoticz.log('______________________________________________________________________________________', LOG_LEVEL)
			domoticz.log('Windmeter: Winddirection (in degrees) is: '..sWindDirectionDegrees, LOG_LEVEL)
			domoticz.log('Windmeter: Winddirection is: '..sWindDirection, LOG_LEVEL)
			domoticz.log('Windmeter: Windspeed is: '..sWindSpeed, LOG_LEVEL)
			domoticz.log('Windmeter: Windgust is: '..sWindGust, LOG_LEVEL)
			domoticz.log('Windmeter: Windtemperature is: '..sWindTemperature, LOG_LEVEL)
			domoticz.log('Windmeter: Windchill is: '..sWindChill, LOG_LEVEL)
			domoticz.log('______________________________________________________________________________________', LOG_LEVEL)
			if (sWindGust >= WIND_GENTLE_BREEZE_LEVEL) then domoticz.data['lastSeenGentleBreeze'].add() end
			if (sWindGust >= WIND_MODERATE_BREEZE_LEVEL) then domoticz.data['lastSeenModerateBreeze'].add() end
			if (sWindGust >= WIND_FRESH_BREEZE_LEVEL) then domoticz.data['lastSeenFreshBreeze'].add() end
			if (sWindGust >= WIND_STRONG_BREEZE_LEVEL) then domoticz.data['lastSeenStrongBreeze'].add() end
			if (sWindGust >= WIND_MODERATE_GALE_LEVEL) then domoticz.data['lastSeenModerateGale'].add() end
			if (sWindGust >= WIND_FRESH_GALE_LEVEL) then domoticz.data['lastSeenFreshGale'].add() end
			if (sWindGust >= WIND_STRONG_GALE_LEVEL) then domoticz.data['lastSeenStrongGale'].add() end
			if (sWindGust >= WIND_STORM_LEVEL) then domoticz.data['lastSeenStorm'].add() end
			if (sWindGust >= WIND_VIOLENT_STORM_LEVEL) then domoticz.data['lastSeenViolentStorm'].add() end
			if (sWindGust >= WIND_HURRICANE_LEVEL) then domoticz.data['lastSeenHurricane'].add() end
		end
	end
}
EDIT: Updated the script to version 1.0.1
Last edited by BakSeeDaa on Thursday 23 March 2017 12:30, edited 3 times in total.
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: My dzVents Wind Monitoring script

Post by dannybloe »

You can also use domoticz.log(msg, [level]) method instead of print() which respects the log level as it is configured in the dzVents settings.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

Re: My dzVents Wind Monitoring script

Post by BakSeeDaa »

dannybloe wrote:You can also use domoticz.log(msg, [level]) method instead of print() which respects the log level as it is configured in the dzVents settings.
Thank You @dannybloe for the suggestion. I've corrected the script to respect the log level. I've also modified it to use script level historical data for storing data about when different wind speeds were last seen.

There is an initialization part which I guess is necessary to avoid errors before the data is on place. Also I use historical data only for the purpose of accessing the time stamp and being able to use the associated time functions (like: domoticz.data['lastSeenViolentStorm'].getLatest().time.minutesAgo)

Please feel free if You see something else that could be improved.

Cheers!
markcame
Posts: 36
Joined: Wednesday 07 December 2016 19:13
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: My dzVents Wind Monitoring script

Post by markcame »

I've tried the scripts and works very well, I have only a question regarding the dummy alert sensor created on domoticz.
Anyone know how it is possible to link the status of this sensor to activate a switch (for example to retract the sunscreen), I've tried to set-up a lua script but I am not able to get the level status there's some workaround ?
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

Re: My dzVents Wind Monitoring script

Post by BakSeeDaa »

markcame wrote:I've tried the scripts and works very well, I have only a question regarding the dummy alert sensor created on domoticz.
Anyone know how it is possible to link the status of this sensor to activate a switch (for example to retract the sunscreen), I've tried to set-up a lua script but I am not able to get the level status there's some workaround ?
Hi @markcame

The alert sensor has a level device attribute that you can use for scripting. Maybe something like this can get you started (untested):

Code: Select all

local ALERT_SENSOR = 'Wind Alert'

return {
	active = true,
	on = {
		ALERT_SENSOR
	},

	execute = function(domoticz, alertSensor)
		if alertSensor.level >= domoticz.ALERTLEVEL_ORANGE
		and domoticz.devices['sunScreen'].state ~= 'On' then
			domoticz.notify('Hey!', 'THE WIND IS HOWLING AND SHAKING THE WINDOWS !', domoticz.PRIORITY_NORMAL)
		end
	end
}
Cheers!
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest