Page 1 of 1
dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 20:22
by mcmikev
Hi Danny,
It thought that it would be better to do this in an own topic.
The problem: script for room heating is editted and works fine with old version dzventz. Then the 2.x version came intergrated in domoticz and I changed the lines that needed to be compatible for the 2.x version to work.
That part I have figured out i hope , but the temp reading has some issues i think or some code is not as it should now to work with the 2.x version.
the code
Code: Select all
-- assumptions:
-- the setpoint is set by a selector dummy device where the values are numeric temperatures
-- but you can easily change it to a setpoint device
local BOILER_DEVICE = 'State-CV-Badkamer' -- switch device
local SETPOINT_DEVICE = 'Thermostaat Badkamer' -- selector dummy device
local TEMPERATURE_SENSOR = 'TH-Badkamer'
local HYSTERESIS = 0.1 -- temp has to drop this value below setpoint before boiler is on again
local SMOOTH_FACTOR = 3
local LOGGING = true
local OVERRIDE_SWITCH = 'CV-Badkamer-Override' -- override switch
return {
on = {
timer = { 'every minute'},
device = { TEMPERATURE_SENSOR, SETPOINT_DEVICE}
},
data = {
temperatureReadings = { history = true, maxItems = SMOOTH_FACTOR }
},
active = true,
execute = function(domoticz, device, triggerInfo)
local avgTemp
local temperatureReadings = domoticz.data.temperatureReadings
-- first check if the sensor got a new reading or the setpoint was changed:
if (triggerInfo.type == domoticz.EVENT_TYPE_DEVICE) then
local sensor = domoticz.devices(TEMPERATURE_SENSOR)
if (sensor.changed and sensor.attributeChanged('temperature')) then
-- sensor just reported a new reading
-- add it to the readings table
local current = sensor.temperature
if (current ~= 0 and current ~= nil) then
temperatureReadings.add(current)
else
-- no need to be here, weird state detected
domoticz.log('Strange sensor reading.. skiping', domoticz.LOG_ERROR)
return
end
elseif (domoticz.devices(SETPOINT_DEVICE).changed) then
-- a new setpoint was set
if LOGGING then domoticz.log('Setpoint was set to ' .. device.state) end
else
-- no business here, bail out...
return
end
end
-- now determine what to do
local boiler = domoticz.devices(BOILER_DEVICE)
local setpoint = domoticz.devices(SETPOINT_DEVICE)
local override = domoticz.devices(OVERRIDE_SWITCH)
if (setpoint.state == nil or setpoint.state == 'Off') then
boiler.switchOff()
return -- we're done here
end
local setpointValue = tonumber(setpoint.state)
-- determine at which temperature the boiler should be
-- switched on
local switchOnTemp = setpointValue - HYSTERESIS
-- don't use the current reading but average it out over
-- the past <SMOOTH_FACTOR> readings (data smoothing) to get rid of noise, wrong readings etc
--local avgTemp = temperatureReadings.avg(1, SMOOTH_FACTOR)
local avgTemp = temperatureReadings.avg(1, SMOOTH_FACTOR, 0) -- when there's no average, return 0 (or whatever you want it to return)
if LOGGING then
domoticz.log('Average: ' .. avgTemp, domoticz.LOG_INFO)
domoticz.log('Setpoint: ' .. setpointValue, domoticz.LOG_INFO)
domoticz.log('Current boiler state: ' .. boiler.state, domoticz.LOG_INFO)
domoticz.log('Switch-on temperature: ' .. switchOnTemp, domoticz.LOG_INFO)
end
if (avgTemp >= setpointValue and boiler.state == 'On') then
if LOGGING then domoticz.log('Target temperature reached, boiler off') end
boiler.switchOff()
boiler.switchOff().afterMin(2)
end
if (avgTemp < setpointValue and boiler.state == 'Off' and override.state == 'Off') then
if (avgTemp < switchOnTemp) then
if LOGGING then domoticz.log('Heating is required, boiler switched on') end
boiler.switchOn()
boiler.switchOn().afterMin(2)
else
if LOGGING then domoticz.log('Average temperature below setpoint but within hysteresis range, waiting for temperature to drop to ' .. switchOnTemp) end
end
end
if (boiler.state == 'On' and override.state == 'On') then
if LOGGING then domoticz.log('Override is aan, CV Badkamer UIT') end
boiler.switchOff()
boiler.switchOff().afterMin(2)
end
end
}
He does not use the avg anymore and that gives the compare to nil error.
With the line you gave me to try, the avg is now 0 so the "temp" in the room is 0 so the heating always keeps turning on even though the setpoint is low.
Hope you can help out here

Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 20:25
by dannybloe
Yes, just dawned to me that it really resembles my own heating script that I used a while ago. Hahaha.
So, as I have been running that script for quite some time it should work (famous last words).
Anyway,
Code: Select all
boiler.switchOff()
boiler.switchOff().afterMin(2)
This looks weird. I don't know what Domoticz will do with these two commands.
But, what I would do is put print statements in the various locations and see if you get to the proper if-branches and what the values are. And I'd get rid of those weird double switch commands.
Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 20:28
by mcmikev
the double switch commands are needed because although the valves are zwave they seem to mis the commands now and then and then keep heating the room until tropical temps. (LC13 valves)
So the wakeup time is 180 seconds so by repeating the command after 2 minutes (most of the timesit works) they will do what I want. open or close.
Can you help out with the print statements?
Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 20:34
by dannybloe
oh, ok.
Oh, I see there are already logging statements every where. Make sure you have set the logging level in the settings to at least 'Errors + minimal execution info + generic info' and check the domoticz log. It should give you hints as to where the logic of you script is taking you.
Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 20:38
by mcmikev
Code: Select all
2017-07-07 20:36:01.295 dzVents: Info: ------ Start internal script: dz_cv_badkamer:, trigger: every minute
2017-07-07 20:36:01.297 dzVents: Debug: Device-adapter found for State-CV-Badkamer: Switch device adapter
2017-07-07 20:36:01.297 dzVents: Debug: Processing device-adapter for State-CV-Badkamer: Switch device adapter
2017-07-07 20:36:01.298 dzVents: Debug: Device-adapter found for Thermostaat Badkamer: Thermostat setpoint device adapter
2017-07-07 20:36:01.298 dzVents: Debug: Processing device-adapter for Thermostaat Badkamer: Thermostat setpoint device adapter
2017-07-07 20:36:01.298 dzVents: Debug: Device-adapter found for CV-Badkamer-Override: Switch device adapter
2017-07-07 20:36:01.298 dzVents: Debug: Processing device-adapter for CV-Badkamer-Override: Switch device adapter
2017-07-07 20:36:01.298 dzVents: Info: Average: 0
2017-07-07 20:36:01.299 dzVents: Info: Setpoint: 18
2017-07-07 20:36:01.299 dzVents: Info: Current boiler state: Off
2017-07-07 20:36:01.299 dzVents: Info: Switch-on temperature: 17.9
This is the logging. Have dzventz in debug mode
The avg temp = 0 and setpoint 18. Script does a if avg<setpoint do boiler on.
So right now the boiler always gets turned on

My override switch is the only thing prevening it from doing it actualy
If I remove the ,0 in the line you gave me so the script is "original" again i get the compare to nil again.
Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 20:50
by dannybloe
Ah, I think I see what's going on here. You don't have the latest code from the example. The idea is simple:
You do a sensor reading and put it into the storage (temperatureReadings.add(current)). Then, if you do an avg() later on, you always get at least the first reading as the average value. However, in your if-statement on line 32 you still have sensor.attributeChanged. That doesn't exist anymore in 2.0. You have to remove that:
You see, in your version that if statement was never true so the current reading was never added to the history so your avg() was always calculating the average of 0 readings. My suggestion to add ,0 didn't help of course

.
Give it a try.. again
Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 20:59
by mcmikev
I have removed the ,0 from the line and changed the other line like you suggest.
Code: Select all
2017-07-07 20:58:01.175 dzVents: Info: ------ Start internal script: dz_cv_badkamer:, trigger: every minute
2017-07-07 20:58:01.177 dzVents: Debug: Device-adapter found for State-CV-Badkamer: Switch device adapter
2017-07-07 20:58:01.177 dzVents: Debug: Processing device-adapter for State-CV-Badkamer: Switch device adapter
2017-07-07 20:58:01.178 dzVents: Debug: Device-adapter found for Thermostaat Badkamer: Thermostat setpoint device adapter
2017-07-07 20:58:01.178 dzVents: Debug: Processing device-adapter for Thermostaat Badkamer: Thermostat setpoint device adapter
2017-07-07 20:58:01.178 dzVents: Debug: Device-adapter found for CV-Badkamer-Override: Switch device adapter
2017-07-07 20:58:01.179 dzVents: Debug: Processing device-adapter for CV-Badkamer-Override: Switch device adapter
2017-07-07 20:58:01.179 Error: dzVents: Error: An error occured when calling event handler dz_cv_badkamer
2017-07-07 20:58:01.179 Error: dzVents: Error: ...icz/scripts/dzVents/generated_scripts/dz_cv_badkamer.lua:78: attempt to concatenate local 'avgTemp' (a nil value)
line 78 is :
Code: Select all
domoticz.log('Average: ' .. avgTemp, domoticz.LOG_INFO)
Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 21:14
by dannybloe
Ok, try this. I modified it a bit. Previously, if there hasn't been any reading yet, your history is empty and so the avg() is nil. Then the timer fires, and it tries to get the avg() on an empty history so there you have your error. So, I did a temp reading at the beginning of the script and have that as fallback (third param to avg) so you always have an avg():
(and I moved some declarations to the beginning as well)
Code: Select all
-- assumptions:
-- the setpoint is set by a selector dummy device where the values are numeric temperatures
-- but you can easily change it to a setpoint device
local BOILER_DEVICE = 'State-CV-Badkamer' -- switch device
local SETPOINT_DEVICE = 'Thermostaat Badkamer' -- selector dummy device
local TEMPERATURE_SENSOR = 'TH-Badkamer'
local HYSTERESIS = 0.1 -- temp has to drop this value below setpoint before boiler is on again
local SMOOTH_FACTOR = 3
local LOGGING = true
local OVERRIDE_SWITCH = 'CV-Badkamer-Override' -- override switch
return {
on = {
timer = { 'every minute' },
device = { TEMPERATURE_SENSOR, SETPOINT_DEVICE }
},
data = {
temperatureReadings = { history = true, maxItems = SMOOTH_FACTOR }
},
active = true,
execute = function(domoticz, device, triggerInfo)
local avgTemp
local temperatureReadings = domoticz.data.temperatureReadings
local boiler = domoticz.devices(BOILER_DEVICE)
local setpoint = domoticz.devices(SETPOINT_DEVICE)
local override = domoticz.devices(OVERRIDE_SWITCH)
local sensor = domoticz.devices(TEMPERATURE_SENSOR)
local current = sensor.temperature
-- first check if the sensor got a new reading or the setpoint was changed:
if (triggerInfo.type == domoticz.EVENT_TYPE_DEVICE) then
if (sensor.changed) then
-- sensor just reported a new reading
-- add it to the readings table
if (current ~= 0 and current ~= nil) then
temperatureReadings.add(current)
else
-- no need to be here, weird state detected
domoticz.log('Strange sensor reading.. skiping', domoticz.LOG_ERROR)
return
end
elseif (domoticz.devices(SETPOINT_DEVICE).changed) then
-- a new setpoint was set
if LOGGING then domoticz.log('Setpoint was set to ' .. device.state) end
else
-- no business here, bail out...
return
end
end
-- now determine what to do
if (setpoint.state == nil or setpoint.state == 'Off') then
boiler.switchOff()
return -- we're done here
end
local setpointValue = tonumber(setpoint.state)
-- determine at which temperature the boiler should be
-- switched on
local switchOnTemp = setpointValue - HYSTERESIS
-- don't use the current reading but average it out over
-- the past <SMOOTH_FACTOR> readings (data smoothing) to get rid of noise, wrong readings etc
--local avgTemp = temperatureReadings.avg(1, SMOOTH_FACTOR)
local avgTemp = temperatureReadings.avg(1, SMOOTH_FACTOR, current)
if LOGGING then
domoticz.log('Average: ' .. avgTemp, domoticz.LOG_INFO)
domoticz.log('Setpoint: ' .. setpointValue, domoticz.LOG_INFO)
domoticz.log('Current boiler state: ' .. boiler.state, domoticz.LOG_INFO)
domoticz.log('Switch-on temperature: ' .. switchOnTemp, domoticz.LOG_INFO)
end
if (avgTemp >= setpointValue and boiler.state == 'On') then
if LOGGING then domoticz.log('Target temperature reached, boiler off') end
boiler.switchOff()
boiler.switchOff().afterMin(2)
end
if (avgTemp < setpointValue and boiler.state == 'Off' and override.state == 'Off') then
if (avgTemp < switchOnTemp) then
if LOGGING then domoticz.log('Heating is required, boiler switched on') end
boiler.switchOn()
boiler.switchOn().afterMin(2)
else
if LOGGING then domoticz.log('Average temperature below setpoint but within hysteresis range, waiting for temperature to drop to ' .. switchOnTemp) end
end
end
if (boiler.state == 'On' and override.state == 'On') then
if LOGGING then domoticz.log('Override is aan, CV Badkamer UIT') end
boiler.switchOff()
boiler.switchOff().afterMin(2)
end
end
}
Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 21:22
by mcmikev
seems to have done it ! APPLAUSE!!!
Dank je Danny!
I will test some more tomorrow. I see an average now
2017-07-07 21:22:01.124 dzVents: Info: ------ Start internal script: dz_cv_badkamer:, trigger: every minute
2017-07-07 21:22:01.126 dzVents: Debug: Device-adapter found for State-CV-Badkamer: Switch device adapter
2017-07-07 21:22:01.126 dzVents: Debug: Processing device-adapter for State-CV-Badkamer: Switch device adapter
2017-07-07 21:22:01.127 dzVents: Debug: Device-adapter found for Thermostaat Badkamer: Thermostat setpoint device adapter
2017-07-07 21:22:01.127 dzVents: Debug: Processing device-adapter for Thermostaat Badkamer: Thermostat setpoint device adapter
2017-07-07 21:22:01.128 dzVents: Debug: Device-adapter found for CV-Badkamer-Override: Switch device adapter
2017-07-07 21:22:01.128 dzVents: Debug: Processing device-adapter for CV-Badkamer-Override: Switch device adapter
2017-07-07 21:22:01.128 dzVents: Info: Average: 24.5
2017-07-07 21:22:01.128 dzVents: Info: Setpoint: 18
2017-07-07 21:22:01.128 dzVents: Info: Current boiler state: Off
2017-07-07 21:22:01.128 dzVents: Info: Switch-on temperature: 17.9
Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 21:24
by dannybloe
Logic always wins

Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 21:26
by dannybloe
Oh and no need to keep debugging mode active as it will fill you logs quite easily.
Re: dzVents 2.0 simple heating script editted for room control
Posted: Friday 07 July 2017 21:32
by mcmikev
I have disabled debug and execution and minimal info for now.
Morgen meer tijd om te testen maar zag er goed uit!
Re: dzVents 2.0 simple heating script editted for room control
Posted: Saturday 08 July 2017 8:48
by mcmikev
Hi Danny,
Well been testing and it looks to be fine again. Changed all my room scripts and tested with high setpoint temp to turn on the heating and that worked. Low setpoint temp turned it off again.
Now lets wait for winter to come
PS: A lot of the example scripts are the "old version". Maybe wise to remove them from the integrated part????
Re: dzVents 2.0 simple heating script editted for room control
Posted: Saturday 08 July 2017 9:12
by dannybloe
I thought I converted all examples. But I'll look again.
Re: dzVents 2.0 simple heating script editted for room control
Posted: Tuesday 31 October 2017 0:05
by Skippiemanz
Dannybloe and Mcmikev,
I've used your script for switching on/off my boiler.
But i have several rooms with several valves.
If i now create multiple scripts and for example room 1 needs heat and room 2 is ok the boiler is switched on by room 1 and 1 min later switched off by the script of room 2.
How could this be solved?
Can there be more rooms/devices added? on
https://github.com/bobkersten/domoticz- ... arming.lua
i saw the lua option like underneath:
Code: Select all
local aThermostatDeviceNames = { 'Woonkamer Thermostaat', 'Badkamer Thermostaat', 'Entree Thermostaat' } -- An array with the names of the thermostat pseudo devices above
local aThermostatWeights = { 12, 4, 1 } -- The priorities for the thermostats
local aTemperatureDeviceNames = { 'Woonkamer Temperatuur', 'Badkamer Temperatuur', 'Entree Sensor Temperatuur' } -- An array with temperature sensor names that correspond to the thermostats above
local aValvesDeviceNames = { 'Vloerverwarming Pomp Schakelaar', nil, nil } -- An array with comma separated valve device names.
local aPreHeat = { true, true, false } -- Wether or not to pre-heat the zone
local sTemperatureOutsideDeviceName = 'Buiten Temperatuur' -- The name of an outside temperature sensor
local sHeatingDeviceName = 'CV Aansturing' -- The name of the on/off heating device
local fMeasureDeltaMinimum = 0.3 -- Minimum temperatature delta measured to determine pre-heat duration
local iHeaterMinimumDuration = 3.5 -- Minimum duration in minutes the heater is off or off to prevent to excessive switching
local iValveMinimumDuration = 4.5
Could this be usefull?
Also i have some windows sensors. Would be nice to integrate this also, so that it will be a complete multi zone solution.
dzVents 2.0 simple heating script editted for room control
Posted: Tuesday 31 October 2017 7:36
by mcmikev
Hi.
I don’t have boiler. I have city heating so the main valve is always open and I have temp sensor in every room that opens of closes the radiator
Re: dzVents 2.0 simple heating script editted for room control
Posted: Wednesday 29 November 2017 16:41
by madrian
Thanks for this script, I am using it now 2 years back and it's working great.
In the last week I switched to Xiaomi Gateway & sensors and there is a little problem. These sensors send new temperature only when is a significant change in the temperature, that's sometimes takes long 10-15 minutes. With my "old" DIY sensor I red values at every 5 minutes so the "avgTemp" changed quickly. Not with the Xiaomi sensors...I must wait much longer to get "avgTemp" over the set value -> my heating running is running unnecessary.
Do you have any recommendation how to get "avgTemp" update more quickly/lower the smooth factor?
Re: dzVents 2.0 simple heating script editted for room control
Posted: Wednesday 16 May 2018 19:15
by funnybu
It works perfect! But i don't understand, why you power off boiler twice?
Code: Select all
boiler.switchOff()
boiler.switchOff().afterMin(2)
dannybloe wrote: ↑Friday 07 July 2017 21:14
Ok, try this. I modified it a bit. Previously, if there hasn't been any reading yet, your history is empty and so the avg() is nil. Then the timer fires, and it tries to get the avg() on an empty history so there you have your error. So, I did a temp reading at the beginning of the script and have that as fallback (third param to avg) so you always have an avg():
(and I moved some declarations to the beginning as well)
Code: Select all
-- assumptions:
-- the setpoint is set by a selector dummy device where the values are numeric temperatures
-- but you can easily change it to a setpoint device
local BOILER_DEVICE = 'State-CV-Badkamer' -- switch device
local SETPOINT_DEVICE = 'Thermostaat Badkamer' -- selector dummy device
local TEMPERATURE_SENSOR = 'TH-Badkamer'
local HYSTERESIS = 0.1 -- temp has to drop this value below setpoint before boiler is on again
local SMOOTH_FACTOR = 3
local LOGGING = true
local OVERRIDE_SWITCH = 'CV-Badkamer-Override' -- override switch
return {
on = {
timer = { 'every minute' },
device = { TEMPERATURE_SENSOR, SETPOINT_DEVICE }
},
data = {
temperatureReadings = { history = true, maxItems = SMOOTH_FACTOR }
},
active = true,
execute = function(domoticz, device, triggerInfo)
local avgTemp
local temperatureReadings = domoticz.data.temperatureReadings
local boiler = domoticz.devices(BOILER_DEVICE)
local setpoint = domoticz.devices(SETPOINT_DEVICE)
local override = domoticz.devices(OVERRIDE_SWITCH)
local sensor = domoticz.devices(TEMPERATURE_SENSOR)
local current = sensor.temperature
-- first check if the sensor got a new reading or the setpoint was changed:
if (triggerInfo.type == domoticz.EVENT_TYPE_DEVICE) then
if (sensor.changed) then
-- sensor just reported a new reading
-- add it to the readings table
if (current ~= 0 and current ~= nil) then
temperatureReadings.add(current)
else
-- no need to be here, weird state detected
domoticz.log('Strange sensor reading.. skiping', domoticz.LOG_ERROR)
return
end
elseif (domoticz.devices(SETPOINT_DEVICE).changed) then
-- a new setpoint was set
if LOGGING then domoticz.log('Setpoint was set to ' .. device.state) end
else
-- no business here, bail out...
return
end
end
-- now determine what to do
if (setpoint.state == nil or setpoint.state == 'Off') then
boiler.switchOff()
return -- we're done here
end
local setpointValue = tonumber(setpoint.state)
-- determine at which temperature the boiler should be
-- switched on
local switchOnTemp = setpointValue - HYSTERESIS
-- don't use the current reading but average it out over
-- the past <SMOOTH_FACTOR> readings (data smoothing) to get rid of noise, wrong readings etc
--local avgTemp = temperatureReadings.avg(1, SMOOTH_FACTOR)
local avgTemp = temperatureReadings.avg(1, SMOOTH_FACTOR, current)
if LOGGING then
domoticz.log('Average: ' .. avgTemp, domoticz.LOG_INFO)
domoticz.log('Setpoint: ' .. setpointValue, domoticz.LOG_INFO)
domoticz.log('Current boiler state: ' .. boiler.state, domoticz.LOG_INFO)
domoticz.log('Switch-on temperature: ' .. switchOnTemp, domoticz.LOG_INFO)
end
if (avgTemp >= setpointValue and boiler.state == 'On') then
if LOGGING then domoticz.log('Target temperature reached, boiler off') end
boiler.switchOff()
boiler.switchOff().afterMin(2)
end
if (avgTemp < setpointValue and boiler.state == 'Off' and override.state == 'Off') then
if (avgTemp < switchOnTemp) then
if LOGGING then domoticz.log('Heating is required, boiler switched on') end
boiler.switchOn()
boiler.switchOn().afterMin(2)
else
if LOGGING then domoticz.log('Average temperature below setpoint but within hysteresis range, waiting for temperature to drop to ' .. switchOnTemp) end
end
end
if (boiler.state == 'On' and override.state == 'On') then
if LOGGING then domoticz.log('Override is aan, CV Badkamer UIT') end
boiler.switchOff()
boiler.switchOff().afterMin(2)
end
end
}
Re: dzVents 2.0 simple heating script editted for room control
Posted: Tuesday 22 May 2018 19:35
by mcmikev
The reason for switching on or off after 2 minutes was because sometimes the danfoss misses the off or on command the room stays cold or gets too hot.