Hi all,
I am in the process of writing my heating control scripts.
They have been working well so far.
System Overview
I have a virtual switch per room to enable/disable heating for that room.
When switched on, if the room temp is cooler than the set point, the boiler is switched on.
Each time a room switches the boiler on, a user variable (Boiler_Call_TOTAL) is incremented, storing the total number of rooms which are calling for the boiler.
When a room temp reaches the set point, Boiler_Call_TOTAL is decremented.
Each time Boiler_Call_TOTAL is decremented, I check to see if it's reached 0, and if it has, switch the boiler off because all the rooms are up to temp.
Issue
I added a master switch to switch all the room switches on/off in one go.
When this switch is switched on, each individual switch is switched on [working].
They in turn they trigger the temperature check for each of their rooms [working].
The issue is, that the Boiler_Call_TOTAL looses count!
If I switch each room switch on with a delay (using .aftersec(5)) it works fine (although that feels like a bit of a bodge!).
This still leaves me at risk of two room temps changing in quick succession, resulting in Boiler_Call_TOTAL loosing count.
I understand that the user variables are not updated until the end of the script, but I would have expected the update to be complete before the next event is processed?
Is this a bug?
Does anyone have a robust workaround that I have not thought of?!
Thanks
Chris
User Variable not updating as expected
Moderator: leecollings
-
- Posts: 12
- Joined: Sunday 17 December 2017 3:05
- Target OS: NAS (Synology & others)
- Domoticz version:
- Contact:
-
- Posts: 1355
- Joined: Friday 29 August 2014 11:26
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Ermelo
- Contact:
Re: User Variable not updating as expected
Yes, there is some optimization in dzVents where if there are multiple devices who changed state, that they are all handled in one batch by dzVents. So, Domoticz prepares a set of changes and passes that to dzVents. dzVents then processes them all at once and builds up the commandArray that is sent back to Domoticz at the end of the batch. This is done for performance reasons as preparing the event data in Domoticz and in dzVents is quite costly and it is unnecessary to do this again and again for each device. So, normally this is not a problem unless you have your specific situation. As in this batch each device increases the uservariable but they all work from the same initial state of this uservariable. So, this is not going to work for you.
So, we have three options here:
The second is not needed as you can use the third option:
So, instead of using some global counter you create one dzVents script for all your rooms. You place the all the roomsensors in one on-devices rule. Every time a room reports a new temperature you simply check all rooms and see if there is at least one room that is below the desired room temperature (make sure you use some hysteresis control). In your script you have access to all devices (including their setpoint) so this is quite simple to do. You could add a timer rule to be sure you didn't miss a necessary change event and you can also add a master switch in the rules as well and check for the state of that switch.
The advantage of this is that you can keep all your logic in one script, no need for extra variables etc. The current states of the room sensors determines if you need to switch the boiler.
So, we have three options here:
- we change this in dzVents and Domoticz but then things become slow for all other use cases.
- you don't use user variables but use dzVents (global) persistent variables. They are updated after each script also within a batch update.
- you don't use variables at all as this is not needed in your situation.
The second is not needed as you can use the third option:
So, instead of using some global counter you create one dzVents script for all your rooms. You place the all the roomsensors in one on-devices rule. Every time a room reports a new temperature you simply check all rooms and see if there is at least one room that is below the desired room temperature (make sure you use some hysteresis control). In your script you have access to all devices (including their setpoint) so this is quite simple to do. You could add a timer rule to be sure you didn't miss a necessary change event and you can also add a master switch in the rules as well and check for the state of that switch.
The advantage of this is that you can keep all your logic in one script, no need for extra variables etc. The current states of the room sensors determines if you need to switch the boiler.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
-
- Posts: 5
- Joined: Saturday 09 June 2018 10:17
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: User Variable not updating as expected
I think that also with performance in mind, to check all rooms for temperature in each call of the script is a hard job in cpu terms.
I think that the use of one persistent variable is the best way to do it. Of course use only one script for all rooms.
At last, I think that persistent variables are only fields of a file and it's impossible to lose the count.
I think that the use of one persistent variable is the best way to do it. Of course use only one script for all rooms.
At last, I think that persistent variables are only fields of a file and it's impossible to lose the count.
-
- Posts: 1355
- Joined: Friday 29 August 2014 11:26
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Ermelo
- Contact:
Re: User Variable not updating as expected
No, that is not correct. All room-temperature data is already available to your script so it doesn't matter if you use it or not. Don't worry about performance here.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: User Variable not updating as expected
To give you an idea on performance; on my PI3 with 243 active devices and 8 heating zones it takes 0.2 seconds to filter the heating zones, compare the temperatures against the setpoints and send a switch command to the boiler.
Code: Select all
--[[
evoFilter.lua
]]--
return {
on = { timer = { "every 5 minutes"}},
logging = { level = domoticz.LOG_INFO, marker = "evoFilter" },
execute = function(dz, trigger)
local devices = 0
local evoDevices = 0
local boilerOn = false
local hysteresis = 0.2
local boiler = dz.devices(161)
dz.devices().filter(function(device)
devices = devices + 1
return (device.hardwareName == "Evohome") -- or any other attribute that identifies the heating devices
end).forEach(function(device)
if device.temperature < device.setPoint - hysteresis then
boilerOn = true
end
evoDevices = evoDevices + 1
dz.log(device.name .. " temperatuur: " .. device.temperature .."°C ; Setpoint: " .. device.setPoint .. "°C",dz.LOG_INFO)
end)
dz.log(devices .. " devices filtered to get " .. evoDevices .. " evohome devices",dz.LOG_INFO)
if boilerOn then
boiler.switchOn().checkFirst()
else
boiler.switchOff().checkFirst()
end
end
}
- Spoiler: show
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
Who is online
Users browsing this forum: No registered users and 1 guest