What started off as a simple home thermostat project with an ESP32 development board, a DHT11 temperature / humidity sensor, a display and a relay grew into something much bigger when I showed the project to co-workers who also received a Google Home device for Christmas. They wanted me to build some for them...
Here's what the prototype looked like. There's two displays because I started the project with a Nokia 5110 display but later decided to use a 128x64 OLED 1.3 inch display. The two buttons are to manually set the temperature and are really optional since the thermostat is, after all, voice enabled. Why push a button when I can speak the desired temperature.
The problem was not building a couple extra of these little thermostats, and perhaps making a little money on the side, the problem was making it 'User Friendly' to configure and setup. Things like WiFi network name, WiFi password, device location (kitchen, bedroom, living room, etc), minimum temperature, scheduled daily on/off cycles had to be configured by the user, not hard coded.
Being relatively new at Arduino development and the ESP32 environment, I had to figure out how to commercialize the product. Easier said than done... This is why I am publishing this project to perhaps help others with similar problems and show the solutions I used to resolve them.
ConfigurationLet's look at the first issue to resolve. Configuration. Since the ESP32 can work as a WiFi Station and WiFi Access Point, we need to create an Access Point and allow users to connect to it to receive a web page that will be used to configure the thermostat. The name of the Access Point is "Thermostat-xxxxxx" where "xxxxxx" is the device's MAC address. The display will guide the user along the steps to configure the device.
Next you will need to open your computer's WiFi network manager and select the thermostat Access Point and connect to it. Once this is done, open a web browser and connect to the thermostat IP address (192.168.4.1).
By connecting to the thermostat, it will present you with a configuration page where all of the user's parameters can be set. I am not an HTML programmer so the page returned uses basic HTML and there's nothing fancy about it. I'm sure some of you will modify the code and make it much prettier :)
This is where you need to make a decision. Will you be using dweet.io or io.adafruit.com as the destination for your voice commands. Initially I wrote the code to only use dweet.io as the destination. It was simple, the end user only had to create an account at ifttt.com and create two applets. Simple enough, I thought. Until I started to think that there might be a few people out there that would have fun in changing my bedroom temperature at night so I'd wake up to a cold, or super hot bedroom. Yes, there are malicious hackers out there. They typically like to break things and don't have the brains to create something interesting or original. Sad really...
So I decided to add the Adafruit interface. It requires the user to create a free account on their site and provide their User Name and API Key in thermostat's configuration screen. I highly suggest you go this route. You can create your free account here and this should be done before moving on. Once you have created your account with Adafruit, click on the "View AIO Key" in your profile page. This will open a popup page that will display your User Name and AIO Key to enter in the thermostat's configuration screen.
There are a few fields that need a little explanation in the configuration screen;
- Location: This is the physical location of where the device is being installed. It is a predefined list of locations in a drop-down box.
- Common Name: If left blank, the device will be recognized by the location name (previous bullet). When you enter a name here, the device will also recognize that name as it's location. So you could call your 'Kitchen' location "Cafeteria" and speak "Ok Google, change cafeteria temperature to 21.5 degrees", or name the 'Bedroom 1' location as "Mary's Room" and speak; "Ok Google, change Mary's room temperature to 23 degrees"
- Master Device: When using dweet.io as the destination for voice commands, this field is used to enter the first (or MASTER) device configured on your local network. All thermostats will be looking at that device for voice commands. The value entered here is the DEVICE number found at the top of the configuration page (in red).
- User Name: If you are going to use io.adafruit.com as the destination for voice commands (recommended), this is where you enter your Adafruit user name.
- API Key: This is the API Key generated for you by Adafruit.
Once the other fields have been filled, press the SUBMIT button and the device will validate the information, try to connect to the local WiFi network specified and make sure no other thermostats in the network has the same device location. If everything is okay, the ESP32 board will reboot itself. If there's an error found in the values, it will display the configuration screen again asking you to correct the field in error.
Serial MonitorOnce the device has rebooted it will send it's configuration values and other information over the serial port. This can be viewed by opening the serial monitor in the Arduino IDE environment.
Temperature / Humidity statistics are collected hourly, daily, monthly and yearly. Each time the device makes a temperature/humidity reading it is added to the hourly statistics and once the hour has closed, it will calculate the average temperature/humidity, heating cost and kWh consumption for that hour and store then in EEPROM memory.
By noting down the device IP address in the configuration process (or by viewing it in the serial monitor when the device boots up) you can connect to the device and get it's statistical data in a beautiful graph format.
The charts are generated on the fly by the LiveGap.com site created by Omar Hamed Sedki. Here's done a wonderful job at allowing us to create charts by simply sending HTML code and his site takes care of generating the graph image. Take a look at the functions WebPageHead() and WebPageChart() to see how simple it is to create beautiful charts using his website.
The device also stores Monthly historical data from last year and will compare it to this year's values. You can display temperature/humidity, heating cost and kWh consumption by selecting the appropriate chart option.
The device also has a seven day schedule with four different set points for each day. By clicking on the schedule button you'll be presented with the schedule configuration screen.
It's possible to Enable / Disable the schedule, copy the Monday values to all weekdays and to broadcast the schedule to all thermostat devices in your local network.
IFTTT HookSince the device can either use dweet.io or io.adafruit.com to receive voice commands, you'll need to choose one when configuring the device for the first time. See the Malicious Hackers section above. This will affect how you create the IFTTT applet and where it will post the data. I will cover how to create the applets with the Adafruit IO Service as this is my recommended destination.
You'll need to create two applets. One to change a location's requested temperature and another to enable the thermostat's schedule. The "$" represents the location you're referring to and the "#" represents the temperature requested. Remember that the "$" refer to a location name, it's common name or the keyword "HOME" location.
- Creating a New Applet: First start off by registering with IFTTT (if you haven't already done so) and then go and create a new applet. I'll step you thru this process using Google Assistant as my voice interface. Click on the blue "+this" link on the page to get started.
- Google Assistant: This is the service name you'll want to select. If this is the first time selecting this service, you'll be asked to enter your Google credentials so that IFTTT can recognize your Google Home device.
- Choose Trigger: You'll be asked what type of trigger you want to create for the Google Assistant, select "Say a phrase with both a number and text ingredient".
- Complete Trigger: Enter the text you want Google Assistant to recognize as your command to change the temperature with both the number field and the text field. The "$" will represent the thermostat's location name and the "#" will be the requested temperature. Then click on the "Create Trigger" button.
- Then That: Next click on the blue "+that" link on the page and you'll be asked which service to use. Select either "Adafruit" or "WebHooks" depending on how you've decided where the voice commands are sent.
- Choose Action Service: Next you'll select Adafruit as the action service and select "Send data to Adafruit IO" as the action.
- Complete Action: Choose the MASTER feed and fill in the data to save. This will be "{{TextField}}={{NumberField}}", then click on the Create action button.
- Scheduling: To create the applet that will run the schedule, create a new applet and fill in the information from these images.
As much as I wanted to *not* hard code anything in the program, I ended up adding one... The TimeZone definition and the rules for daylight savings and when it changes in my time zone. Jack Christensen created a nice library that handles this and works with the Time library I was using from Paul Stoffregen. Both these libraries are available on GitHub and are required in order to compile the project.
In the code, locate and change the following lines to reflect your time zone and the rules that will start and end daylight savings in your area.
//
// Eastern Time Zone rule (Change for other time zones and rules)
//
TimeChangeRule myEDT = {"EDT", Second, Sun, Mar, 2, -240};
TimeChangeRule myEST = {"EST", First, Sun, Nov, 2, -300};
Timezone myTZ(myEDT, myEST);
Reserved NamesThe Common Name field (used during the device's configuration) can not be a location name and can not be the special "Home" location. Meaning you can't give your 'Bedroom' location the common name of "Kitchen", since "Kitchen" is also a location name. Nor can you call your 'Bathroom' location "Home".
The "Home" keyword refers to all devices in the local network. This allows you to speak one command to change all thermostats. "Ok Google, change HOME temperature to 19.5 degrees". Looking at the code, you'll see that any location below 'Office' are excluded from the "Home" keyword.
char Location[][15] = {
"Kitchen",
"Dining Room",
"Living Room",
"Family Room",
"Master Bedroom",
"Bedroom",
"Bedroom 1",
"Bedroom 2",
"Bedroom 3",
"Bathroom",
"Bathroom 1",
"Bathroom 2",
"Bathroom 3",
"Office",
// Locations below 'Office' are excluded from the keyword "Home" location
"Basement",
"Cantina",
"Wine Cellar",
"Garage",
"Outdoor Shed"
};
Min / Max TemperaturesI've added code to prevent going outside a fixed temperature range. This is defined in the following lines of code. If you would like to extend this range, just change the values.
//
// Define temperature min/max values allowed
//
#define MinCelcius 5
#define MaxCelcius 30
#define MinFarenheit 41
#define MaxFarenheit 86
dweet.ioTemperature / Humidity reading are posted to dweet.io on a 15 second interval and can be viewed by looking at the 'Thermo-xxxx' feed. The 'xxxx' represents the device's MAC address. So for example, my Kitchen thermostat can be viewed at the following location: Thermo-5C8009C40A24.
If you are using Adafruit as the destination for your voice commands, the device will automatically create your data feeds and create a nice dashboard called "Home Heating" for you.
You can monitor and change your home temperature using this dashboard from anywhere you have internet access, your home computer, laptop or even from your mobile phone. The MASTER slider is used to set the HOME temperature (meaning all thermostats) and the Schedule toggle will enable or disable the thermostat scheduling function. If you add new thermostats in your home, the new device will automatically create a gauge for that location in the dashboard.
This is where I've had to modify the Adafruit IO libraries. Their exists() and create() functions did not work with the ESP32 boards I was using. You'll find the modified library in the code section below and is stored on GitHub. Overwrite your C:\Users\[USERNAME]\Documents\Arduino\libraries\Adafruit_IO_Arduino directory with the one I placed on GitHub.
freeboard.ioIt is also possible to create a dashboard (for viewing only) using freeboard.io website. It allows you to create panels and panel objects for your dweet.io feeds. With a bit of practice it's possible to create a nice looking dashboard that will give you the information you want to see in it. Or alternatively, you could clone my dashboard as a starting place. Here's the link to my dashboard. You'll have to remove the Espresso Maker from yours ;)
Now I had to figure out how to power this device. A battery was not an option as you only get about 10 hours of life on it before it needs to be recharged. Running wires out of the thermostat to connect to a USB power source was not an option as well. So my solution was to take apart a USB charger wall plug and to incorporate that into the thermostat.
WARNING: This now deals with high voltage and can potentially harm you.
The inside these USB wall chargers is a small transformer, bridge rectifier and a couple of capacitors. They provide an output voltage of 5v DC and are typically rated at 500 mA up to 1 amp. Enough to power our thermostat.
Using a volt meter, find the live side of your existing thermostat, that's the side you'll want to attach one lead of the USB charger 120/240 volts input. The other input lead will be connected to neutral and is typically the metal box of the wall fixture where you'll see a bare wire screwed to it.
Before connecting anything to live wires, make sure you've turned off the circuit breaker in your electrical panel for that heater.
Next connect leads from the two outer most pins of the USB connector. These will be your +5 and GND for the ESP32 board.
Finishing TouchNow that we have everything put together and working on our breadboard, it's time to put the finishing touch to the project. Since I wanted to replace the existing Honeywell thermostats in the house, I had to find a suitable housing for the components that would fit in the space where the old thermostats were.
Benjamin St-Pierre from 3D Hubs helped me create a beautiful 3D printed case for the thermostat that is physically the same size as the original Honeywell one. He can produce two different top cases and the bottom plate to screw into the wall. The top case options depend on which ESP32 board you use and are;
- Top case for a 1.3" OLED display for generic ESP32 board.
- Top case for a 0.96" Heltec OLED WiFi device.
He has quick turn-around and can provide you with a quote for each option.
AssemblingNow it's time to put everything together. As you can see in the 3D model, Benjamin has provided grooves and railings so that all the components fit nicely into the casing. A little hot glue is used to secure the parts in place. There's an opening on the left side of the top casing so that you can connect a USB cable to the controller board if you need to upload new code. However, the code supports OTA updates which the Arduino IDE can connect to and send updates over the air (or WiFi network actually).
You'll want to connect the COM (common) and NO (normally open) of the relay to the two wires that were used from your old thermostat. The relay module used is rated at 10A / 250VAC or 15A / 120VAC. With these ratings you can connect a heater up to 2500 Watts.
The next step in this project would be to make the thermostat HVAC friendly so that it can control a central heating system with heat, air conditioning and blower fan control. Since this is not the type of heating system I have at home, I'll leave these modifications for others to take this project further.
What would also be nice would be the addition of monitoring the outside temperature, using Weather Underground API, and flip the display between inside temperature, current outside temperature and temperature forecast every few seconds. Adafruit has a nice tutorial on doing just that with an ESP8266 board. You can find the tutorial here.
ConclusionAll in all this thermostat gives me everything I need; Voice controlled by Google Home or Alexa, saves me in heating cost with it's scheduling capabilities and I can view / modify the heating remotely from my phone using the Adafruit dashboard. All this for less than $60! Sure beats buying a NEST thermostat for $350...
Comments