I've embarked on a project that I thought others may be interested in, and I would be interested in some feedback.
Unsatisfied with my Honeywell T6 Pro's ability to properly regulate temperature in some zones no matter what I set Cycles Per Hour to, I decided I would try my hand at coding a thermostat to control my heating zones.
To do this I had to disconnect my thermostat heating wires and instead use a ZigBee Relay board to control the zone valves from Hubitat.
This is the before-state wiring diagram for my furnace thermostats connected to the zone valves, and should be typical for most setups for hot water baseboard heating.
I disconnected the white heating wire from the zone valves and inserted relays in-between.
I added an extra board to automatically re-engage the thermostats, if I need to for any reason. This is controlled by the "engage relays" relay which allows me to switch between the ZigBee relay control or thermostat control remotely from a dashboard icon, or by pressing the button on the board. It is wired so the "all off" state uses thermostats. If Hubitat or a board goes down on a below zero day, I didn't want to be in the basement wiring the thermos back to the valves to get heat back.
The boards were each about $20 on Amazon, so with the bus rails I only have about $50 into this project.
Then came the harder part, writing a virtual thermostat driver to run the heat. Having baseboard heat, there is a large delay in the heat coming up and going down.
I started with a tight hysteresis, but I still went under setpoint waiting for heat, and over setpoint waiting for it to stop. It still was working better than the T6 thermostats alone.
After a discussion about T6 thermostats in another thread, I realized that I needed to add cycling to my driver, to turn the heat on before it goes below setpoint, and to turn it off before it reaches setpoint.
It was more difficult to code than I had anticipated. I could not find any good algorithms for a cycling thermostat, so I played around until I got something working.
Not mentioned yet, but to use a virtual device to control actual devices also requires a controller app that subscribes to events to sync temperature sensors and to turn the zone valve relays on and off with the thermostatOperatingState.
Here is picture of the boards wired:
My driver with cycling works like this:
Choose a cycles per hour in preferences. This is used in cycleInit() to assign a cycling duration and a waiting interval, based on an outside temp of 32 degrees. I found the best calculation for this to be 15/cycles. You would think 30/cycles would be better, to get the proper on and off cycles per hour, but the cycles are way too long using this and there were fewer cycles than set. 15/cycles works pretty well as a starting point.
From there I also sync the outside temp to the driver using the controller app. A calculation is performed when out temp changes to add seconds to the cycles and subtract seconds from the wait interval, based on how much above or below freezing. I have been using about 10sec per degree for this, though I need some colder temps to really test it out. I left seconds per degree change as a preference so I can play with the value. Above freezing gives negative changes, so in that case cycles are shortened and waits are lengthened above freezing.
I use three hysteresis settings (maybe better to call them offsets)
- hysteresis - This determines when to Ramp. I use 0.2 degrees generally. So at 0.2 degrees below setpoint, the furnace will ramp continuously up to that temperature. Once at temp, cycles kick in to maintain temperature
- cyclingHysteresis - determines when the cycling starts above setpoint. Depends on the zone, but generally around 0.2 to start cycling when temp is 0.2 above setpoint. If a cycle is running and temp goes above this point, cycling will stop and there will be a wait set.
- stopHysteresis - This is the stop point for a cycle, and it is a bit less than the cycleHystereis. This will stop a cycle if temperature is rising, and the thermostat is cycling. If a cycle actually gets up to the cyclingHysteresis point before turning off, it tends to overheat, so the stop hysteresis stops the cycle a bit before that. It only stops with rising temp so it will not stop the cycle while running a cycle, since the heat is usually still trying to recover (the temp is still going down).
After each cycle, it enters a waiting period that stops a new cycle from starting. This is because the temperature from baseboard heat is so delayed that the temperature is still rising after a cycle, and a cycle will just start again without a wait as it is still within the start cycle range.
Once the wait expires, a cycle can start if temp is <= the cyclingHysteresis temperature.
This has been working pretty well for the last few days. I am maintaining a temperature now within a 0.3 degrees swing.
Here is the driver in its current state:
It was a fun project, and I really got my heating under control. I encourage others to use a temp sensor with more accuracy to see what your thermostat temp swings really are.
I'm not sure what is up with the T6 Pro cycling, but there are not enough settings available to really tune it into my particular zone needs. I sync everything from the T6s to the virtual thermostats, so I still use them as usual to change setpoints, etc.