Planner for central heating

Moderator: leecollings

Post Reply
Maxx
Posts: 58
Joined: Saturday 27 January 2018 20:59
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Contact:

Planner for central heating

Post by Maxx »

All,

This may be usefull,I have been using this script to plan my central heating system for the last two years now (flawlessly :-)).

It only publisches setpoints for two rooms based on a time and a day of week. It also calculates when the heating should turn on in order to reach the temperature on the desired time. It supports manual mode.(Manual mode will override at the next planned time in case someone forgets to put it back)
You can use the setpoints in another script to control your heater.

You will have to adjust the script for your own use and it most probably can be optimised.



You have to create two selector switches:
Livingroom periods: Wake, Home, Comfort, Away, Sleep
Heating Mode: Off, Normal, Vakantie, Weg, Thuis (Thuis is for Thuiswerken)

Code: Select all

local ComfortSetting   = 20
local HomeSetting      = 19
local SleepSetting     = 15
local AwaySetting      = 15
local WakeSetting      = 19

return {
	on = {
		devices = {'Livingroom periods'},
		timer = {'every minute'},
	},

	data = {    Period  = { initial = {},
	            oneShot = { initial = 0},
	    },
},

--    logging =   {   level                   = domoticz.LOG_DEBUG,
--                    marker                  = "Planner" },

	execute = function(dz, Item)
    local Heating_period            = dz.devices('Livingroom periods')
    local TK_Temp                   = dz.devices('TK_Eetkamer_Temp')
    local ManualSetpointLiving      = dz.devices('Temperature')

    
    t = {}

    local function initPersistent()
            t.periods       = {}
            t.periods       =  {   
                                {Day="Mon",Wake='7:00',Home='17:00',Comfort='20:00',Away='9:00', Sleep='23:00'},
                                {Day="Tue",Wake='7:30',Home='17:00',Comfort='20:00',Away='9:00', Sleep='23:00'},
                                {Day="Wed",Wake='7:30',Home='17:00',Comfort='20:00',Away='9:00', Sleep='23:00'},
                                {Day="Thu",Wake='7:15',Home='17:00',Comfort='20:00',Away='9:00', Sleep='23:00'},
                                {Day="Fri",Wake='7:10',Home='17:00',Comfort='20:00',Away='9:00', Sleep='23:59'},
                                {Day="Sat",Wake='8:30',Home='17:00',Comfort='20:00',Sleep='23:59'},
                                {Day="Sun",Wake='9:30',Home='17:00',Comfort='20:00',Sleep='23:30'},
                                {Day="Vak",Wake='8:30',Home='17:00',Comfort='20:00',Sleep='23:59'},
                                {Day="Thuis",Wake='7:30',Home='17:00',Comfort='20:00',Sleep='23:00'},
                             }
                             
            dz.data.Period = t
    end

    function round(n)
	    return n % 1 >= 0.5 and math.ceil(n) or math.floor(n)
	end
	
    local function calcCurve(Setpoint)
        local difference = Setpoint - TK_Temp.temperature
        if difference > 0 then
            local curve = 0.03 --C/min
            timeReq = difference / curve
            return round(timeReq)
        elseif difference <= 0 then
            return 0
        end
    end
    
    local function correctedTime(Time, Setpoint)
        h, m = string.match(Time, "(%d+):(%d+)")
        local hour = tonumber(h)
        local minute = tonumber(m)
        local totalMinutes = (hour * 60) + minute
        local startTime = totalMinutes - calcCurve(Setpoint)
        dz.log('Correctie ' .. calcCurve(Setpoint))
        dz.log(round(startTime))
        return round(startTime)
    end
    
    local function directTime(Time)
        h, m = string.match(Time, "(%d+):(%d+)")
        local hour = tonumber(h)
        local minute = tonumber(m)
        local totalMinutes = (hour * 60) + minute
        local startTime = totalMinutes
        dz.log(startTime)
        return round(startTime)
    end
    
    local function processPeriods(t)
        for i=1,#t.periods do          
            local Day       = t.periods[i].Day
            local Wake      = t.periods[i].Wake
            local Home      = t.periods[i].Home
            local Comfort   = t.periods[i].Comfort
            local Away      = t.periods[i].Away
            local Sleep     = t.periods[i].Sleep
            local HeatingMode   = dz.devices('Heating Mode').levelName
            if HeatingMode == 'Normal' or HeatingMode == 'Off' then
                ToDay     = os.date("%a")
            elseif HeatingMode == 'Vakantie' then
                ToDay     = 'Vak'
            elseif HeatingMode == 'Weg' then
                Today = 'Weg'
            elseif HeatingMode == 'Thuis' then
                Today = 'Thuis'
            end
            if Today ~= 'Weg' then
                dz.data.oneShot = 0
                if ToDay == Day then
                    totalTijd = os.date("*t")
	                tijd = totalTijd.min + totalTijd.hour * 60
	                dz.log('Present time :' .. tijd)
                    if tijd >= correctedTime(Wake, WakeSetting) and tijd <= correctedTime(Wake, WakeSetting) + 5  then
                        dz.log('Wakker worden')
                        Heating_period.switchSelector('Wake')
                    end
                    if not (ToDay == 'Sat' or ToDay == 'Sun'or ToDay == 'Vak' or Today == 'Thuis') then
                        if tijd == directTime(Away) then
                            dz.log('Away')
                            Heating_period.switchSelector('Away')
                        end
                    end
                    if tijd >= correctedTime(Home, HomeSetting) and tijd <= correctedTime(Home, HomeSetting) + 5 then
                        dz.log('Home')
                        Heating_period.switchSelector('Home')
                    end
                    if tijd >= correctedTime(Comfort, ComfortSetting) and tijd <= correctedTime(Comfort, ComfortSetting) + 5 then
                        dz.log('Comfort')
                        Heating_period.switchSelector('Comfort')
                    end
                    if tijd == directTime(Sleep) then
                        dz.log('Sleep')
                        Heating_period.switchSelector('Sleep')
                    end
                end
            elseif Today == 'Weg' then
                dz.log('Iedereen is weg')
                dz.globalData.Setpoint_Woonkamer    = AwaySetting 
                dz.globalData.Setpoint_Eetkamer     = AwaySetting
            end
        end
    end

    if Item.isTimer then    
        initPersistent()
        t = dz.data.Period
        processPeriods(t)
    end    
    
    if Item.isDevice and (Item.name == 'Livingroom periods') then
        local currentPeriod = dz.devices('Livingroom periods').levelName
        if currentPeriod == 'Comfort' then
            dz.globalData.Setpoint_Woonkamer    = ComfortSetting
            dz.globalData.Setpoint_Eetkamer     = ComfortSetting      
        elseif currentPeriod == 'Away' then
            dz.globalData.Setpoint_Woonkamer    = AwaySetting
            dz.globalData.Setpoint_Eetkamer     = AwaySetting
        elseif currentPeriod == 'Sleep' then
            dz.globalData.Setpoint_Woonkamer    = SleepSetting
            dz.globalData.Setpoint_Eetkamer     = SleepSetting
        elseif currentPeriod == 'Home' then  
            dz.globalData.Setpoint_Woonkamer    = HomeSetting 
            dz.globalData.Setpoint_Eetkamer     = HomeSetting
        elseif currentPeriod == 'Wake' then    
            dz.globalData.Setpoint_Woonkamer    = WakeSetting
            dz.globalData.Setpoint_Eetkamer     = WakeSetting
    
        end
    end


end

}
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest