User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

The following script check temperature for one or more zones, to find out if windows or doors are open: in that case send notification by Telegram

Useful to avoid energy consumption during winter or summer, when someone forget windows/doors open.

The up-to-date version of this file is avaible at http://docs.crasol.it/script_time_openwindows.lua


-- Script that checks temperature and try to discover if doors/windows are open: in that case sends notification by Telegram.
-- Useful to limit energy consumption in winter and summer, if someone forgets windows or doors open.
--
-- This script should be named DOMOTICZ_HOME/scripts/lua/script_time_SCRIPTNAME.lua , e.g. /home/pi/domoticz/scripts/lua/script_time_openwindows.lua
-- It will be called every minute and will check and compare, for each zone (defined below), the current temperature with previous temperature.
--
-- The following user variables must be set:
-- telegramChatid : the Telegram chat ID where notifications should be sent : see https://www.domoticz.com/wiki/Telegram_Bot
-- telegramToken : the Telegram token : see https://www.domoticz.com/wiki/Telegram_Bot
-- HeatingOn: a variables that assumes the following values
--   0 => Heating/Cooling system is OFF
--   1 => Heating is ON
--   2 => Cooling is ON
--
-- Creasol - https://www.creasol.it/products

debug=1	-- if True, print debug information
domoticzUrl='http://192.168.3.230:8080'

-- zones: array that associate for each zone the name of the temperature device, and max difference for temperature
-- This script automatically create a variable zTemp_ZONENAME that contains the temperature measured before
zones={	--zonename  {tempsensor,difference}
	['Cucina']={'Temp_Cucina',0.6},	
	['Bagno']={'Temp_Bagno',0.6},
	['Camera']={'Temp_Camera',0.6}, 
	['Camera_Valentina']={'Temp_Camera_Valentina',0.6},
	['Camera_Ospiti']={'Temp_Camera_Ospiti',0.6},
	['Stireria']={'Temp_Camera',0.6}, --TODO: replace Temp_Camera with Temp_Stireria
}

commandArray={}	-- reset commandArray, an associative array that will contain the list of commands for Domoticz.

function telegramNotify(msg)
	os.execute('curl --data chat_id='..uservariables['telegramChatid']..' --data-urlencode "text='..msg..'"  "https://api.telegram.org/bot'..uservariables['telegramToken']..'/sendMessage" ')
end

function min2hours(mins)
	-- convert minutes in hh:mm format
	return string.format('%02d:%02d',mins/60,mins%60)
end

function timedifference (s)
	year = string.sub(s, 1, 4)
	month = string.sub(s, 6, 7)
	day = string.sub(s, 9, 10)
	hour = string.sub(s, 12, 13)
	minutes = string.sub(s, 15, 16)
	seconds = string.sub(s, 18, 19)
	t1 = os.time()
	t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
	difference = os.difftime (t1, t2)
	return difference
end

function checkVar(varname,vartype,value) 
	-- check if create, if not exist, a variable with defined type and value
	-- type=
	-- 0=Integer
	-- 1=Float
	-- 2=String
	-- 3=Date in format DD/MM/YYYY
	-- 4=Time in format HH:MM
	local url
	if (uservariables[varname] == nil) then
		telegramNotify('Created variable ' .. varname..' = ' .. value)
		url=domoticzUrl..'/json.htm?type=command&param=saveuservariable&vname=' .. varname .. '&vtype=' .. vartype .. '&vvalue=' .. value
		-- openurl works, but can open only 1 url per time. If I have 10 variables to initialize, it takes 10 minutes to do that!
		-- commandArray['OpenURL']=url
		os.execute('curl "'..url..'"')
		uservariables[varname] = value;		
	end
end

if (debug) then print('------------------------- openwindows --------------------------------') end

timenow = os.date("*t")
minutesnow = timenow.min + timenow.hour * 60

checkVar('HeatingOn',0,0)	-- 0=heating off, 1=heating on, 2=cooling on

for n,v in pairs(zones) do	-- check that temperature setpoint exist
	-- n=zone name, v=array with temperature sensor name and max acceptable temperature drop in degrees
	checkVar('zTemp_'..n,1,otherdevices[v[1]])	-- if zTemp_Cucina does not exist, create variable and store current temperature
	if (otherdevices[v[1]]==nil) then
		telegramNotify('Zone '..n..': temperature sensor '..v[1]..' does not exist')
	end
end

if (uservariables['HeatingOn']==1) then
	-- Heating enabled
	-- compare zTemp_ZONE (old temperature) with current temperature
	for n,v in pairs(zones) do
		-- n=zonename (HeatingSP_n = setpoint temperature)
		-- v[1]=tempsensor
		-- v[2]=max difference
		diffTemp=tonumber(otherdevices[v[1]])-uservariables['zTemp_'..n]
		if (diffTemp>=0) then
			-- current temperature > old temperature: update old temperature
			commandArray['Variable:zTemp_'..n]=otherdevices[v[1]]
		else
			-- current temperature < old temperature
			-- compute gradient (diffTemp/TIME)
			gradient=diffTemp*60/timedifference(uservariables_lastupdate['zTemp_'..n])	-- degrees/minute
			--if (diffTemp<=-0.2) then
				if (debug) then print('Zone='..n..' gradient='..string.format('%0.3f',gradient)..' Temp='..otherdevices[v[1]]..'C diffTemp='..diffTemp) end
				if (math.abs(gradient)<(0.2/30)) then -- temperature falls slowly, less than 0.2C on 30 minutes
					-- |gradient|=v[2]) then
						telegramNotify('Zone '..n..': window open!! Gradient='..string.format('%0.2f',gradient*60)..'K/hour');
						commandArray['Variable:zTemp_'..n]=otherdevices[v[1]]	-- update zTemp_ZONE temperature
					end
				end
			--end
		end
	end
elseif (uservariables['HeatingOn']==2) then	
	-- HeatingOn=2 => Cooling
	-- TODO
else
	-- HeatingOn=0 => Heating or Cooling = OFF => don't check windows
end

if (debug) then 
	for i, v in pairs(commandArray) do
		print('### ++++++> Device Changes in commandArray: '..i..':'..v)
	end
end
::mainEnd::
return commandArray

Pin It