this is my variant of a script that will set the flow temperature depending on the exterior temperature and the inside desired temperature:
Code: Select all
-- This script will set the flow temperature of a heating system based on the external temperature and the
-- internal temperature of the room.This is done with the help of the heating curves that are defined based
-- on the desire and the needs of the room u wish.
-- Also the script will set the desire flow temperature based on the type of the heating system u have: underfloor or
-- radiators. In one of this states, the script will automatically keep a minimum and maximum flow temperature depending
-- on the state of your settings (underfloor or radiators). Also a manual state can be set where u set the temperature
-- at any value u want.
-- Define a threshold for exterior temperature change to trigger the script
-- U can set here how many degrees the outside temperature need to change before the flow temperature will be changed to the next value from the coresponding heating curve
local tempChangeThreshold = 2 -- Adjust this value as needed
local decimalNumber = 1 -- this is the noumber of decimal for the temperature sensors
-- Define heating curves based on your requirements
-- The heating curves will be set as follow: temp - is the outside temperature; pardosealaFlow - is the underfloor temperature
-- u want for the coresponding outside temperature; calorifereFlow - is the radiator temperature.
local heatingCurves = {
C1 = {
{temp = 18, pardosealaFlow = 20.5, calorifereFlow = 28.3},
{temp = 17, pardosealaFlow = 21, calorifereFlow = 28.8},
{temp = 16, pardosealaFlow = 21.5, calorifereFlow = 29.4},
{temp = 15, pardosealaFlow = 22, calorifereFlow = 29.9},
{temp = 14, pardosealaFlow = 22.5, calorifereFlow = 30.4},
{temp = 13, pardosealaFlow = 23, calorifereFlow = 30.9},
{temp = 12, pardosealaFlow = 23.5, calorifereFlow = 31.3},
{temp = 11, pardosealaFlow = 24, calorifereFlow = 31.9},
{temp = 10, pardosealaFlow = 24.5, calorifereFlow = 32.3},
{temp = 9, pardosealaFlow = 25, calorifereFlow = 32.8},
{temp = 8, pardosealaFlow = 25.5, calorifereFlow = 32.3},
{temp = 7, pardosealaFlow = 26, calorifereFlow = 33.7},
{temp = 6, pardosealaFlow = 26.5, calorifereFlow = 34.2},
{temp = 5, pardosealaFlow = 27, calorifereFlow = 34.7},
{temp = 4, pardosealaFlow = 27.5, calorifereFlow = 35.1},
{temp = 3, pardosealaFlow = 28, calorifereFlow = 35.6},
{temp = 2, pardosealaFlow = 28.5, calorifereFlow = 36},
{temp = 1, pardosealaFlow = 29, calorifereFlow = 36.5},
{temp = 0, pardosealaFlow = 29.5, calorifereFlow = 37},
{temp = -1, pardosealaFlow = 30, calorifereFlow = 37.4},
{temp = -2, pardosealaFlow = 31.5, calorifereFlow = 37.9},
{temp = -3, pardosealaFlow = 32, calorifereFlow = 38.3},
{temp = -4, pardosealaFlow = 32.5, calorifereFlow = 38.7},
{temp = -5, pardosealaFlow = 33, calorifereFlow = 39.2},
{temp = -6, pardosealaFlow = 33.5, calorifereFlow = 39.6},
{temp = -7, pardosealaFlow = 34, calorifereFlow = 40},
{temp = -8, pardosealaFlow = 34.5, calorifereFlow = 40.5},
{temp = -9, pardosealaFlow = 35, calorifereFlow = 41},
{temp = -10, pardosealaFlow = 35.5, calorifereFlow = 41.4},
{temp = -11, pardosealaFlow = 36, calorifereFlow = 41.8},
{temp = -12, pardosealaFlow = 36.5, calorifereFlow = 42.2},
{temp = -13, pardosealaFlow = 37, calorifereFlow = 42.7},
{temp = -14, pardosealaFlow = 37.5, calorifereFlow = 43.1},
{temp = -15, pardosealaFlow = 38, calorifereFlow = 43.5},
{temp = -16, pardosealaFlow = 38.5, calorifereFlow = 44.9},
{temp = -17, pardosealaFlow = 39, calorifereFlow = 44.4},
{temp = -18, pardosealaFlow = 39.5, calorifereFlow = 45.8},
{temp = -19, pardosealaFlow = 40, calorifereFlow = 45.2},
{temp = -20, pardosealaFlow = 40.5, calorifereFlow = 45.6},
{temp = -21, pardosealaFlow = 41, calorifereFlow = 46.1},
{temp = -22, pardosealaFlow = 41.5, calorifereFlow = 46.5},
{temp = -23, pardosealaFlow = 42, calorifereFlow = 46.9},
{temp = -24, pardosealaFlow = 42.5, calorifereFlow = 47.3},
{temp = -25, pardosealaFlow = 43, calorifereFlow = 47.7},
{temp = -26, pardosealaFlow = 43.5, calorifereFlow = 48.1},
{temp = -27, pardosealaFlow = 44, calorifereFlow = 48.6},
{temp = -28, pardosealaFlow = 44.5, calorifereFlow = 49},
{temp = -29, pardosealaFlow = 45, calorifereFlow = 49.4},
{temp = -30, pardosealaFlow = 45.5, calorifereFlow = 50.8},
},
C2 = {
{temp = 18, pardosealaFlow = 20.5, calorifereFlow = 32.3},
{temp = 17, pardosealaFlow = 21, calorifereFlow = 32.8},
{temp = 16, pardosealaFlow = 21.5, calorifereFlow = 33.4},
{temp = 15, pardosealaFlow = 22, calorifereFlow = 33.9},
{temp = 14, pardosealaFlow = 22.5, calorifereFlow = 34.4},
{temp = 13, pardosealaFlow = 23, calorifereFlow = 34.9},
{temp = 12, pardosealaFlow = 23.5, calorifereFlow = 35.3},
{temp = 11, pardosealaFlow = 24, calorifereFlow = 35.9},
{temp = 10, pardosealaFlow = 24.5, calorifereFlow = 36.3},
{temp = 9, pardosealaFlow = 25, calorifereFlow = 36.8},
{temp = 8, pardosealaFlow = 25.5, calorifereFlow = 37.3},
{temp = 7, pardosealaFlow = 26, calorifereFlow = 37.7},
{temp = 6, pardosealaFlow = 26.5, calorifereFlow = 38.2},
{temp = 5, pardosealaFlow = 27, calorifereFlow = 38.7},
{temp = 4, pardosealaFlow = 27.5, calorifereFlow = 39.1},
{temp = 3, pardosealaFlow = 28, calorifereFlow = 39.6},
{temp = 2, pardosealaFlow = 28.5, calorifereFlow = 40},
{temp = 1, pardosealaFlow = 29, calorifereFlow = 40.5},
{temp = 0, pardosealaFlow = 29.5, calorifereFlow = 41},
{temp = -1, pardosealaFlow = 30, calorifereFlow = 41.4},
{temp = -2, pardosealaFlow = 31.5, calorifereFlow = 41.9},
{temp = -3, pardosealaFlow = 32, calorifereFlow = 42.3},
{temp = -4, pardosealaFlow = 32.5, calorifereFlow = 42.7},
{temp = -5, pardosealaFlow = 33, calorifereFlow = 43.2},
{temp = -6, pardosealaFlow = 33.5, calorifereFlow = 43.6},
{temp = -7, pardosealaFlow = 34, calorifereFlow = 44},
{temp = -8, pardosealaFlow = 34.5, calorifereFlow = 44.5},
{temp = -9, pardosealaFlow = 35, calorifereFlow = 45},
{temp = -10, pardosealaFlow = 35.5, calorifereFlow = 45.4},
{temp = -11, pardosealaFlow = 36, calorifereFlow = 45.8},
{temp = -12, pardosealaFlow = 36.5, calorifereFlow = 46.2},
{temp = -13, pardosealaFlow = 37, calorifereFlow = 46.7},
{temp = -14, pardosealaFlow = 37.5, calorifereFlow = 47.1},
{temp = -15, pardosealaFlow = 38, calorifereFlow = 47.5},
{temp = -16, pardosealaFlow = 38.5, calorifereFlow = 48.9},
{temp = -17, pardosealaFlow = 39, calorifereFlow = 48.4},
{temp = -18, pardosealaFlow = 39.5, calorifereFlow = 48.8},
{temp = -19, pardosealaFlow = 40, calorifereFlow = 49.2},
{temp = -20, pardosealaFlow = 40.5, calorifereFlow = 49.6},
{temp = -21, pardosealaFlow = 41, calorifereFlow = 50.1},
{temp = -22, pardosealaFlow = 41.5, calorifereFlow = 50.5},
{temp = -23, pardosealaFlow = 42, calorifereFlow = 50.9},
{temp = -24, pardosealaFlow = 42.5, calorifereFlow = 51.3},
{temp = -25, pardosealaFlow = 43, calorifereFlow = 51.7},
{temp = -26, pardosealaFlow = 43.5, calorifereFlow = 52.1},
{temp = -27, pardosealaFlow = 44, calorifereFlow = 52.6},
{temp = -28, pardosealaFlow = 44.5, calorifereFlow = 53},
{temp = -29, pardosealaFlow = 45, calorifereFlow = 53.4},
{temp = -30, pardosealaFlow = 45.5, calorifereFlow = 53.8},
},
C3 = {
{temp = 18, pardosealaFlow = 20.5, calorifereFlow = 36.3},
{temp = 17, pardosealaFlow = 21, calorifereFlow = 36.8},
{temp = 16, pardosealaFlow = 21.5, calorifereFlow = 37.4},
{temp = 15, pardosealaFlow = 22, calorifereFlow = 37.9},
{temp = 14, pardosealaFlow = 22.5, calorifereFlow = 38.4},
{temp = 13, pardosealaFlow = 23, calorifereFlow = 38.9},
{temp = 12, pardosealaFlow = 23.5, calorifereFlow = 39.3},
{temp = 11, pardosealaFlow = 24, calorifereFlow = 39.9},
{temp = 10, pardosealaFlow = 24.5, calorifereFlow = 40.3},
{temp = 9, pardosealaFlow = 25, calorifereFlow = 40.8},
{temp = 8, pardosealaFlow = 25.5, calorifereFlow = 41.3},
{temp = 7, pardosealaFlow = 26, calorifereFlow = 41.7},
{temp = 6, pardosealaFlow = 26.5, calorifereFlow = 42.2},
{temp = 5, pardosealaFlow = 27, calorifereFlow = 42.7},
{temp = 4, pardosealaFlow = 27.5, calorifereFlow = 43.1},
{temp = 3, pardosealaFlow = 28, calorifereFlow = 43.6},
{temp = 2, pardosealaFlow = 28.5, calorifereFlow = 44},
{temp = 1, pardosealaFlow = 29, calorifereFlow = 44.5},
{temp = 0, pardosealaFlow = 29.5, calorifereFlow = 45},
{temp = -1, pardosealaFlow = 30, calorifereFlow = 45.4},
{temp = -2, pardosealaFlow = 31.5, calorifereFlow = 45.9},
{temp = -3, pardosealaFlow = 32, calorifereFlow = 46.3},
{temp = -4, pardosealaFlow = 32.5, calorifereFlow = 46.7},
{temp = -5, pardosealaFlow = 33, calorifereFlow = 47.2},
{temp = -6, pardosealaFlow = 33.5, calorifereFlow = 47.6},
{temp = -7, pardosealaFlow = 34, calorifereFlow = 48},
{temp = -8, pardosealaFlow = 34.5, calorifereFlow = 48.5},
{temp = -9, pardosealaFlow = 35, calorifereFlow = 49},
{temp = -10, pardosealaFlow = 35.5, calorifereFlow = 49.4},
{temp = -11, pardosealaFlow = 36, calorifereFlow = 49.8},
{temp = -12, pardosealaFlow = 36.5, calorifereFlow = 50.2},
{temp = -13, pardosealaFlow = 37, calorifereFlow = 50.7},
{temp = -14, pardosealaFlow = 37.5, calorifereFlow = 51.1},
{temp = -15, pardosealaFlow = 38, calorifereFlow = 51.5},
{temp = -16, pardosealaFlow = 38.5, calorifereFlow = 51.9},
{temp = -17, pardosealaFlow = 39, calorifereFlow = 52.4},
{temp = -18, pardosealaFlow = 39.5, calorifereFlow = 52.8},
{temp = -19, pardosealaFlow = 40, calorifereFlow = 53.2},
{temp = -20, pardosealaFlow = 40.5, calorifereFlow = 53.6},
{temp = -21, pardosealaFlow = 41, calorifereFlow = 54.1},
{temp = -22, pardosealaFlow = 41.5, calorifereFlow = 54.5},
{temp = -23, pardosealaFlow = 42, calorifereFlow = 54.9},
{temp = -24, pardosealaFlow = 42.5, calorifereFlow = 55.3},
{temp = -25, pardosealaFlow = 43, calorifereFlow = 55.7},
{temp = -26, pardosealaFlow = 43.5, calorifereFlow = 56.1},
{temp = -27, pardosealaFlow = 44, calorifereFlow = 56.6},
{temp = -28, pardosealaFlow = 44.5, calorifereFlow = 57},
{temp = -29, pardosealaFlow = 45, calorifereFlow = 57.4},
{temp = -30, pardosealaFlow = 45.5, calorifereFlow = 57.8},
},
C4 = {
-- Add temperature-flow rate pairs for Curba4
},
Manual = {
-- Leave custom temperature-flow rate pairs for Manual mode free
},
}
local FLOW_MIN_TEMP_CALORIF = 20 -- the minimum flow temperature for radiators
local FLOW_MAX_TEMP_CALORIF = 75 -- the maximum flow temperature for radiators
local FLOW_MIN_TEMP_PARD = 20 -- the minimum flow temperature for underfloor
local FLOW_MAX_TEMP_PARD = 45.5 -- the maximum flow temperature for underfloor
return {
on = {
devices = {
'Mod Incalzire', -- selector switch (Heating Mode) with Pardoseala(Underfloor), Calorifere(Radiators), Manual modes - (Pardoseala if the renamed Off mode of the selector in my case)
-- to switch betwin Underfloor, Radiators or Manual mode
'Setare_temperatura_tur', -- thermostat like device (Set_flow_temp) to set the desired flow temperature when in Manual mode or to show the set temperature in automatic mode
'Curba De Incalzire', -- selector switch (Heating Curve) to pick between the desired defined heting curves (C1, C2, C3, ...) or to put it in Manual mode.
-- The Manual is the renamed Off mode of the selector and allow u to manually set a desired flow temperature with the help of the 'Set_flow_temp' device
-- but forcing the minimum and maximum of the flow temperature at the set values
'EXTERIOR', -- exterior temperature sensor
'Setare_temperatura_camera',-- thermostat device (Room_Temp_Set)that set the disired room temperature.
}
},
logging = {
-- level = domoticz.LOG_DEBUG,
level = domoticz.LOG_INFO,
marker = "&&##**^^ Adjust Flow Temperature Script ^^**##&& "
},
execute = function(domoticz, devices, customEvents)
local heatingMode = domoticz.devices('Mod Incalzire').state
local settempTur = domoticz.devices('Setare_temperatura_tur')
local exteriorTemp = domoticz.devices('EXTERIOR').temperature
local heatingCurve = domoticz.devices('Curba De Incalzire').state
local tSetat = domoticz.variables('t_tur_setat') -- user variable that keep the set flow temperature to be shared amongst different scripts
local lastExteriorTemp = domoticz.variables('lastExteriorTemp') -- user variable that help keepeng the previous outside temperature that script used
local tCamSet = domoticz.variables('t_cam_setat') -- user variable that keep the desired set room temperature to be shared amongst different scripts
local thermostat = domoticz.devices('Setare_temperatura_camera')
local tempRoom = domoticz.devices('Baie')
local outTempDifference = thermostat.setPoint - 20 -- this is to calculate the difference between the actual room temperature and the ideal room temperature for what heating curves are defined
local roomTempDifference = tCamSet.value - tempRoom.temperature -- in this case the ideal temperature is 20 degrees Celsius. If your room temperature is set at 20 degrees, the flow temperature will be picked
-- from the desired heating curve. if u set the temperature at 19, the flow temperature will be set as
-- the temperature from the set curve for 20 degrees - tempDifference (19-20=-1 so the flow temperature will be -1 degree from the normal 20)
local t= 'false' -- this variable is used to determine if the outside temperature was changed for the 'tempChangeThreshold' ammount
-- if the script is triggered by the exterior temperature sensore we check to see if the outside temperature is changed from the last reading when we set the flow temperature
-- to this: 'tempChangeThreshold' ammount. if is changed, we will proceed to set a new flow temperature. if not the script will not run
if devices.name == 'EXTERIOR' then
local exteriorTempRound = domoticz.helpers.customRoundFunction(exteriorTemp, decimalNumber)
local diffTemp = lastExteriorTemp.value - exteriorTempRound
--domoticz.log('1.5 Temp difference : ' ..lastExteriorTemp.value..' - '..exteriorTempRound..' =' .. diffTemp)
-- Check if the exterior temperature has changed beyond the threshold
if math.abs(diffTemp) > tempChangeThreshold then
t = 'true'
domoticz.log(' ')
domoticz.log('1.1 THE SCRIPT WAS TRIGGERED BY : ' .. devices.name .. ' because:')
domoticz.log('1.3 Last exterior temperatre : ' .. lastExteriorTemp.value)
domoticz.log('2.1 Exterior temperature changed more than '.. tempChangeThreshold)
domoticz.log('1.5 Temp difference : ' ..lastExteriorTemp.value..' - '..exteriorTempRound..' =' .. diffTemp)
domoticz.log('2.2 Last exterior temperatre will be set to : ' .. exteriorTempRound)
lastExteriorTemp.set(exteriorTempRound)
else
t='false'
--domoticz.log('3.1 Exterior temperature did not changed more than '.. tempChangeThreshold)
--domoticz.log('3.2 Last exterior temperatre will remane : ' .. lastExteriorTemp.value)
end
end
-- we check to see if the script was triggered by the exterior temp sensor and if the outside temperature changed the 'tempChangeThreshold' ammount or
-- by the any other device from the trigger part of the script
if (devices.name == 'EXTERIOR' and t=='true') or devices.name == 'Mod Incalzire' or devices.name == 'Setare_temperatura_tur' or devices.name == 'Curba De Incalzire' or devices.name == 'Setare_temperatura_camera' then
domoticz.log(' ')
domoticz.log('1.1 THE SCRIPT WAS TRIGGERED BY : ' .. devices.name)
domoticz.log('1.3 Last exterior temperatre : ' .. lastExteriorTemp.value)
if heatingMode ~= 'Manual' then -- check to see if the Heating Mode is in the automatic (C1 ... Cn) mode so we can pick the flow temperature from the wanted heating curve
local targetTemp = FLOW_MIN_TEMP_PARD
if heatingCurve ~= 'Manual' and heatingCurves[heatingCurve] then
for i = 1, #heatingCurves[heatingCurve] do
if exteriorTemp >= heatingCurves[heatingCurve][i].temp then
if heatingMode == 'Pardoseala' then
targetTemp = heatingCurves[heatingCurve][i].pardosealaFlow
domoticz.log('(5.1.P) targetTemp for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' should be set to : ' .. targetTemp)
break
elseif heatingMode == 'Calorifere' then
targetTemp = heatingCurves[heatingCurve][i].calorifereFlow
domoticz.log('(5.2.C) targetTemp for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' should be set to : ' .. targetTemp)
break
else
-- Handle other heating modes if necessary
domoticz.log('(5.3) Invalid heating mode: ' .. heatingMode)
return
end
end
end
-- if room temperature is ~= to 20, we adjust the flow temperature from the heating curve accordingly
if outTempDifference ~= 0 then
targetTemp = targetTemp + outTempDifference
end
local minLimit = FLOW_MIN_TEMP_PARD
local maxLimit = FLOW_MAX_TEMP_PARD
-- set the limits of the flow temperature depending on the Heating Mode chosen (Underfloor or Radiators)
if heatingMode == 'Pardoseala' then
minLimit = FLOW_MIN_TEMP_PARD
maxLimit = FLOW_MAX_TEMP_PARD
elseif heatingMode == 'Calorifere' then
minLimit = FLOW_MIN_TEMP_CALORIF
maxLimit = FLOW_MAX_TEMP_CALORIF
end
-- Ensure that targetTemp is within the specified range
if targetTemp < minLimit then
targetTemp = minLimit
domoticz.log('(6.1) targetTemp is less than min for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown')..'. Will be automatically set to minim : ' .. targetTemp)
elseif targetTemp > maxLimit then
targetTemp = maxLimit
domoticz.log('(6.2) targetTemp is over the maxim for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown')..'. Will be automatically set to maxim : ' .. targetTemp)
end
settempTur.updateSetPoint(targetTemp).silent() -- Update the selecting flow temperature thermostat setpoint automatically
tSetat.set(targetTemp) -- updating the user variable with the new value
domoticz.log('(6.3) targetTemp fo the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' is set to : ' .. tostring(targetTemp))
elseif heatingCurve == 'Manual' then -- if the Heating Curve is set to Manual we can manually set the flow temperature, but not outside the min and max alowed by the Heating Mode (Underfloor or Radiators)
domoticz.log('(7.1) S-a intrat in logica devices.trigger and heatingCurve == Manual')
local setpointTemp = settempTur.setPoint
local minLimit, maxLimit
domoticz.log('(7.2) targetTemp for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' should be set to : ' .. setpointTemp)
-- Set the minimum and maximum limits based on the heating mode
if heatingMode == 'Pardoseala' then
minLimit = FLOW_MIN_TEMP_PARD
maxLimit = FLOW_MAX_TEMP_PARD
elseif heatingMode == 'Calorifere' then
minLimit = FLOW_MIN_TEMP_CALORIF
maxLimit = FLOW_MAX_TEMP_CALORIF
else
-- Handle other heating modes if necessary
domoticz.log('(1.2) Invalid heating mode: ' .. heatingMode)
return
end
if setpointTemp < minLimit then
setpointTemp = minLimit
domoticz.log('(7.3) targetTemp is less than min for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown')..'. Will be automatically set to minim : ' .. setpointTemp)
elseif setpointTemp > maxLimit then
setpointTemp = maxLimit
domoticz.log('(7.4) targetTemp is over the maxim for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown')..'. Will be automatically set to maxim : ' .. setpointTemp)
end
-- Update the thermostat setpoint device if the manually set flow temperature is outside the min or max
settempTur.updateSetPoint(setpointTemp).silent()
tSetat.set(setpointTemp)
domoticz.log('(7.5) targetTemp fo the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' is set to : ' .. setpointTemp)
else
domoticz.log(" (3) Invalid heating curve selected.")
return
end
else -- if Heating Mode is in Manual we can set whatever flow temperature we want, not taking into account the min and max value for the flow temperatures
setpointTemp = settempTur.setPoint
tSetat.set(settempTur.setPoint)
domoticz.log('(7.6) targetTemp fo the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' is set to : ' .. settempTur.setPoint)
end
else
--domoticz.log('Flow temperature did not changed')
end
end
}
the 'global_data' script contain some global persistent variable that i use in the scripts i made including this one (useful for the future modification of my setup) and also a rounding function that round a number depending on the amount of decimals someone desire (i made this because i didn't know what the correct function is (if exist) in dzvents. the way the rounding is done is like this: if u want to round at 1 decimal, we look at the 2 decimal and if that is under 5, the 1-st decimal will remain unchanged. if the second decimal is >5 then the 1-st decimal is increased by 1. if the second decimal ==5 we look at the 3-rd decimal and if is <5, first decimal remain the same if 3-rd decimal>5 then 1-st decimal is increased by 1 and so on. we can do that for 0, 1, 2, 3, ... n decimals.
if someone know the correct function in dzvents that does this kind of rounding please poste it here !!