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

[code]-- 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[/code]