From RevSpace
Jump to navigation Jump to search

Project "Thermostat":

Project Luteijn/Thermostat
Status In progress
Contact Luteijn
Last Update 2018-03-13


My house has a thermostat in the living room. It controls the central heating bij switching a boiler on and off. Although it is a relatively advanced thermostat (Honeywell Chronotherm IV), that even has some provisions for remote controlling/overriding, and extra temperature sensors, I just have the basic connector-plate that is missing the physical connections for this. And I'm not going to bother hacking them in, as I'm not satisfied with the current set-up for several reasons.

  • My version of the Thermostat is the basic on-off non-modulating version, as at the time I bought it, the boiler didn't support Open Therm anyway, and Open Therm is only 'open' for certain values of 'open'. Boiler is upgraded and now has Open Therm capability, also quite a bit of the Open Therm stuff is now opened up by reverse engineering etc.
  • I don't care that the temperature in the living room is 'adequate' if I'm in the study where it is not adequate. If it is too hot in the study, I could turn down the radiator there, but if it is too cold in the study and the living room thermostat has shut down the boiler, it won't get any warmer.
  • Although there is some intelligence/self-learning included in the thermostat, so it starts heating in time to have the house warm at the scheduled time, it doesn't handle rapid weather changes too well, and the scheduling is a bit limited. It would be nice if it could read the weather forecast and be a bit more aware of presence and adjust its program on that.
  • I don't want a 'cloud-based' thermostat, but don't mind a home computer making the decisions.

Some related info

Installers manual for a similar Chronotherm IV explaining how to get to the installer's menu (TL;DR: press all three buttons [i] [^] and [v] at the same time for a few moments), and what to do when you get there to activated more features:

Bigger characters to make a large 'current temperature' display:

Basic idea

  • Replace the thermostat by a relay/FET capable of handling the 24 V 'interface' to the Boiler. (a relay is enough for basic on-off 24V, FET probably needed if I want to talk Open Therm to it instead). Control this 'switch' with a microcontroller that can take more input into account than the Chronotherm can/does. Another option is a 24V tolerant optocoupler. I'll try that as it should take a lot less power than a relay, but still provide some isolation from the 24V. Ordered a batch of PC817's from China, thes should handle up to 50mA and 35V, which should be plenty (see under power from heater section)
  • Initially just have the Chronotherm proxied by the microcontroller via a direct wired connection, then built up from there. Might just skip this step and make a wireless bridge right away.
  • An ESP would seem like a useful microcontroller, as it could get its input(s) wirelessly, and a nice step two would be to have one ESP control the boiler, and another connected to the Chronotherm, so it can be easily moved to whatever room I want it to monitor, and have them talk to each other, either directly or via MQTT. Voltage on the thermostat side seems to be available, so the ESP can use the Chronotherm for power. Would be nice to program it to be energy conservative.
  • Next, move the final decision making away from the Chronotherm, and make it just one of potentially many sensors providing suggestions. Final decision to turn on/off the Heater would be made on the microcontroller controlling the Boiler, but it might be 'strongly influenced' by a more intelligent program running on a homeserver.
  • Add more mini-thermostats/sensors throughout the house that can indicate the 'need for heat' based on current temperature, Rel. Humidity, user-input (e.g. a big 'I am fscking cold, activate boiler now - RED ALERT, all engines flanking speed, ahead warp-factor 9, damn the torpedoes, go to defcon 1, dive-dive-dive, women-and-children-first'-panicbutton) and basically OR all these to decide to ('strongly suggest' the microcontroller to) switch on the heater. These would/could/should have a little 'flame' display/led/indicator to show the current boiler state too, to reassure the user(s) heat is on its way/not being generated needlessly.
  • Graph the information collected by the sensors to try and find patterns to optimize the decision process and hopefully avoid user-intervention as much as possible.
  • Remote controlled radiator(knobs) don't seem needed at first, just need to make sure the thermostatic knobs are set to match the desired max temperature, and trust the system to run the heater as long as at least one room needs heat. Eventually it would make things even better to have remote controlled radiators, so a room can be kept cooler than its max even if there is another room that needs to heat up. Should be a relatively simple operation to pop off the existing knobs and replace them by remote controlled ones that can be set to the desired temperature by the system, or just opened/closed more based on the heat demand from the room they are in.
  • etc.

Work done so far

  • Not enough.
  • Made a wikipage
  • Looked into working of existing heating set-up.
  • Ordered some small ESP based boards and sensors from China.
  • Experimented with 16x2 LCD displays to be used as status displays.
  • Practiced sensor graphing from existing CO2/Temp/Hum meter (similar to Voltcraft C-60)
  • Looked into existing stand alone e-thermometers to be enhanced by an ESP or gutted for parts.
  • Got some experience controlling relay by microcontroller to open garage-door
  • Analogue sensor experience from garage-door open sensor. (As it only had an analogue pin left that can't be allowed to go completely low, it doubles as the active low RESET pin)
  • Saved up some old candy tins and toothpaste caps that might work nice as housing and knobs for rotary encoders

Basically waiting for more parts to arrive and some free time to make the Chronotherm work wirelessly and experiment with placing it in different rooms.

LCD Layout

16x2 cells, each having 5x8 pixels, with a 1 pixel gap between cells, or alternatively seen, 6x9 pixels with one 'dead' row and column per cell. Or, a screen of 95x17 pixels with a few lines in it. Unfortunately there are only 8 programmable characters so it's not possible to fake a completely bitmapped display, but an 8 cell area could be done, and there are libraries for doing a 'big' font using reusable tiles.

A Thermostat display should probably by default show current room temperature in the big font, and the current target temperature in a smaller one, as well as a small clock and a symbol indicating if this thermostat is requesting heat, and a flame on to indicate if the boiler is currently running. Pressing a button could cycle the display to show settings like room name, overall system status, and/or information of other things going on in the house. After all, if you have a small screen able to talk/listen to MQTT in each room, might as well use it to display events coming in.

Mock up of display

To the left a crude version of the large font showing 17. Arrow indicates target temperature,humidity (if applicable is also shown). The 🔥 flame to show boiler is on (reported from boiler controller), and a '+' is another status indicator e.g. showing this node wants heat.

o 2 0 ° 3 2 % +
_ _ 1 3 : 3 7 : 4 2 🔥

A rotary controller would be fun, but 3-4 buttons (next item,select,prev item,cancel) would also work as a control panel for local control/cycling through other displays.


draft version Faceplate.svg

Ideas for events to generate and/or react to

There will be several slightly different types of units that might differ in the types of events that are useful to them. Most nodes would not keep most of their state locally, but rely on values published to MQTT (most likely by themselves), so they can quickly recover from resets and the like, just based on their 'name' and questioning persistent MQTT info.

Topic of the MQTT info should be of the form /.../<node-ID>/[sub id/]<topic>, with the message payload as per the table below. Node ID's should be a short type indicator(2-4 characters), a dash, and a three digit number). Friendly names can be given separately. Sub id's should be numbers from 1-whatever, with 0 being the implied sub id for units with only one of the type of sensors c.q. the value representing the 'average' of all subsensors of a type. The topic indicates the type of sensor or desire this report is about.


/RLL255/sensors/CO2-001/co2 739 PPM 
/RLL255/sensors/CO2-001/0/co2 739 PPM 
/RLL255/sensors/room-001/1/temperature 17.1 °C
/RLL255/sensors/room-001/2/temperature 17.2 °C
/RLL255/sensors/room-001/alert message="Report to the Mess:Dinner!",target=room-011
Topic Message payload Comments
alert message="<message>"[,target="<target-id>"[,...]] Target is by default all nodes, but one or more specific targets can be specified by their ID
barometer <barometric pressure> Current Barometric pressure
co2 <CO2 PPM> CO2 level measured
desire:<what> <value> probably just 0 for 'False', -1 for 'True', but might have meaningful other values, e.g. 1 to indicate there is an ongoing need that is currently being satisfied (to avoid pingponging between a heater on/off). <what> could be e.g. heat,no_heat or ventilator. This indicates a locally computed desire based on settings and sensor input. Nodes that can fulfill these desires should weigh their decisions and decide to pitch in or not.
engage:<what> <value>,<target-id> This is a more or less explicit directive for a node to engage its <what> (typically heater relay). To be used by more or less 'smart' units to force relatively 'dumb' units to forget about making their own decisions and just defer to whomever they trust most. Value=0 to cancel the directive, and everything else as a priority to act as tie breaker between conflicting orders between equally trusted nodes. NORMALLY a node with a relay would be sufficiently smart not to need this and just react to desire_<what> instead.
friendly_name <name> The friendly/display name for this node, e.g. a room name describing the room it is in
gravity <field strength> Now we're just making things up :)
humidity <RH> current relative humidity
I <current> Current flowing
keepalive "recovering"|"leaving"|"power"|<whatever> Periodic message to report (continued) presence, intention to leave, power issues (battery low etc.), and/or recovering from e.g. power outage, reset etc.
light <light level> current light level (in whatever unit makes sense)
manual:<what> <value> probably just 0 for 'False', -1 for 'True', but might have meaningful other values. <what> could be e.g. heat or ventilator.

This indicates a locally made manual request that should be given a lot of weight in any further decisions

noise <noise level> current noise level (in whatever unit makes sense)
occupants <number of occupants> Either a guess at the number of occupants, based on user entry or other inputs, or simply -1 for undetermined amount >0.
pir <movement sensed> probably just 0 for 'False', -1 for 'True'
query:<what> [target=<target>] request information to be re-published
relay:<what> <value> Reports relay state,0 for at rest, -1 to indicate engaged. <what> is typically heat or maybe ventilation
setting:<key> <value> settings for the unit, like schedule, target temperature, humidity alert levels etc.
temperature <temperature> Current ambient temperature
unixtimestamp <timestamp in seconds since epoch> Current time at reporting unit. Other units could sync to this if they trust this time more than their own. Units without a properly set clock should not usually report their time to avoid 'dumb' units to sync to unreliable time. Units should generally only sync to one, trusted, source.
V <voltage> Voltage level
water_level <level> Level of water in crawlspace, sink-well, cistern etc.
xrays <level> Roentgen radiation level
Room node

A room node most likely will combine one or more environment sensor(s) with a status display and a manual input unit, sharing a power source, microcontroller and connectivity, as most of the time you'd want all three of these functions in each room anyway, and duplicating most of these into separate units probably is not very efficient.


  • Sensor readings (e.g. Temperature, CO2 level, Rel. Humidity, Occupants, Ambient light,
  • Settings (e.g. current target temperature, current switching scheme/schedule)
  • Local User input (e.g. override to just request heat with priority, or to copy settings from a default or other node)


  • Date/Time updates (to keep clock in sync)
  • Its own published measurements setting etc. to update local status
  • Published measurements from other nodes to display when requested by user
  • 'PA' messages ("All Hands, report to the galley"; "Doorbell"; "Incoming phonecall"; "DEFCON change")
Control node

This will be located near a/the heater boiler/furnace (or airco, or ventilator or whatever) and should be the only unit actually directly talking to it. It might include more or less 'intelligence' to make a decision based on possibly conflicting demands from different other nodes. Produces:

  • Anything a normal Room node would
  • Relay state


  • Anything a normal Room node would
  • Desires and Engages directed to it
Computer node

This would be running on a 'server' type of computer (not a microcontroller), and use information from different sources to come to a compound decision on turning on the heat or not.

Sensor unit

Basically just produces current sensor values and they occasional setting/friendly name message. Might consume settings to control its name and reporting frequency.

Display unit


  • Data produced by its associated sensor(s), which it displays.
  • Input from its associated manual input unit(s)
  • Settings to control what is associated with it etc.


  • Keepalives

Power from the heater?

As the heater on/of switch provides around 24V, maybe the controller can be run from that. Of course, if you complete the circuit with a short, the voltage is pulled down to 0, but maybe it is enough to use a pulldown, forming a voltage divider with whatever series R is used as a kind of pull up, but still enough for the heater to consider it a request for heat.

Did some quick measurements to get an idea of what might be possible. At the Thermostat location in the living room, there is 22V available. When shorted with a 22kΩ resistor, this drops to 16.5V. So it seems that there is indeed some pull-up upstream.

Assuming my multimeter is more or less perfect and no current of note runs when measuring voltage, and the cable used is also good, with no resistance of note, we have this voltage divider:


So, 16.5V drops over 22kΩ, which means a current of (16.5/22)mA = 0.75mA flows (Ohm's law, I=U/R;R=U/I;U=RI). The same current flows through R, and 5.5V drops over R, so R is (5.5/0.75)kΩ = 7 1/3 kΩ

If we drop the entire 22V over R alone, the expected current would be about 3mA, so this is probably the maximum we should try to draw. I checked, and indeed when short-circuiting with a multimeter, 3mA is exactly what's on the display. Anyway, 3mA at 22V is only 66mW, (22mA at 3V) so not a lot of power to work with, but might be enough for a small microprocessor. 'Real' thermostats use a kind of supercap to buffer energy.

Next is to figure out what actually makes the heater switch on? If it is based on the voltage being drawn to (almost) 0, then bad luck. I suppose it is more likely what is being measured is current flowing through the thermostat, so any reasonable drop over R is enough. This kind of switch also has to work with less than perfect switches, after all. This might still mean bad luck, as it means we can't really pull much power from here, before triggering the heater...

Next experiment would be putting in a variable resistor and see at what value of U/I the heater is triggered, but for now it seems a bit hopeless to use this idea. It does give us an idea of the max current a relay/FET/optocoupler would have to handle.

comments welcome

23:21 <@Juerd> luteijn: voor inspiratie :)örperthermostat-Version-stabiler-Metallmutter/dp/B01A5R1I8K/ref=sr_1_2?ie=UTF8&qid=1519944121&sr=8-2