DIY IoT Thermostat

Context

I recently became obsessed with creating my own IoT devices using ESP8266/ESP32 microcontrollers, ESPHome, and Home Assistant. Most of what I had been playing with had been dev boards with sensors haphazardly soldered to them. Although this had been a lot of fun, I wanted to created something more permanent that would be more useful.

Note, this isn’t an instructional guide, I’m not responsible if you mess up your HVAC system because of the information I provided below.

HVAC systems

From my research I found that most residential HVAC systems are very simple. The common ones are a straightforward 24 VAC system where a series of wires that preform different functions are shorted to a 24 VAC common wire. This means that the whole system can be controlled with just a few relays and an MCU. The system in my apartment is a heat-pump system which complicates things a little bit, but with some simple reverse-engineering of the original thermostat, it was no match for me.

The main connections in my system are:

  • R – 24 VAC
  • C – Common
  • G – Fan
  • Y1 – First stage cooling
  • O & B – Reverse valve connections
  • W1 – First stage heating
  • W2 – Second stage heating

Most regular HVAC systems will have similar connections sans the reverse valve connection which is exclusive to heat pump systems.

I also found that the W1 and W2 heating stages in my system are shorted together on the HVAC side, so it does not matter which one is switched on. I believe W1 is normally used as a auxiliary heater in case the heat pump cannot produce enough of a temperature delta.

In my system G, Y1 and O must be connected to 24 VAC for cooling and W2, G and B must be connected for heating. I also noted that if you switch the original thermostat from cooling to heating quickly, you can hear some form of pressure relief valve letting out pressure in the system, so In my design, I would like to avoid this.

Additionally, there is a common connection which many older systems lack, luckily my system includes this connection. Old thermostats are generally very dumb devices that use bimetal switches to connect the correct wires together, this meant they did not need power from the system. For modern electronic thermostats to work, the common wire is needed to form a voltage potential from the 24 VAC connection.

Electronics Design

I chose an ESP8266 for this design as it is cheap and has just enough GPIO for the functionality I require. In addition to an MCU, I would need a temperature/humidity sensor, relays, and a way to power the device.

To get power to the board, I used a half wave rectifier and smoothing capacitor to get a DC voltage, and then an off the shelf DC-DC converter with a high input range to get 5V for the board electronics. As I didn’t want to damage my HVAC system, I added a fuse and MOV to ensure a failure did not damage the HVAC system or the board.

For temperature sensing, I found a very nice sensor from Honeywell that measures temperature and humidity, with an accuracy of ±4% RH. The sensor uses I2C which is another requirement I had as the screen I wanted to use also uses I2C.

My goal was to make the PCB as small as possible, and still be somewhat easy to solder by hand, or at least my hand. The ESP8266 is in the top left of the PCB. The center of the board has an OLED display to show the current indoor and outdoor temperatures. The outdoor temperature is taken from another ESP32 IoT sensor node I have on my balcony that reports outdoor pressure, temperature and humidity. I also added a push button to wake up the display as I did not want it turned on all of the time. The last two features are the 6 relays and terminal block header to connect the PCB to the HVAC system.

PCB layout in KiCAD

ESPhome Code

The esphome code I wrote can be found below. There is a main esphome yaml file and an additional c header I wrote that talks with the honeywell sensor. But be warned, this may not work with your HVAC or could damage your HVAC if not used correctly.

Homeassistant

After the code is uploaded on the MCU the device shows up in homeassistant as we would normally expect. Here is a screenshot of my homeassistant overview (and yes, I like it a little warm, don’t judge me):