What a great feeling to return to a warm and cozy home after a busy day! For years we have had a Junkers (Bosch) gas boiler, feeding hot water to wall-mounted radiator panels. When the rather dull and basic room control unit started to hiccup, it was time for an upgrade!
Thanks to an ESP8266 and Amazon Alexa, the central heating can now be controlled from anywhere, and even by voice!
Some modern gas boilers have adopted an open standard (OpenTherm) for the interface between the gas boiler and the room control unit, but in my installation, the interface is proprietary by the manufacturer. The solution shown here replaces a Junkers (Bosch) TW2 room control unit, or any compatible unit.
BackgroundThe gas heater is a modulating gas boiler with weather compensation, controlled by a basic room control unit. Contrary to an on/off thermostat, heating control is achieved by precisely controlling the water temperature in the hydronic circuit, and thus the thermal energy that is released in the house through the radiator panels. The water temperature is influenced by the TW2 room control unit, and the outdoor temperature, measured by a temperature sensor.
The picture shows the heating curves from the boiler’s user manual. The colder the outdoor temperature (AT), the higher the water temperature’s set point (VT), to compensate for bigger heat losses through the house’s outer shell.
The gas boiler’s control system tries to achieve and maintain the requested water temperature with the least possible gas usage by modulation. That’s the manufacturer’s know-how and we’re not interfering with that.
The existing room control unit consists of a switch selecting the thermostat mode, a knob (potentiometer) to increase/decrease the water temperature set point, and a few resistors. Turns out in my case, that the potentiometer was wearing out, and producing a out-of-whack control signal to the gas boiler. Wow, it gets warm in here!
Rather then trying to find a compatible spare part, or buying a new unit, like the missus suggested, why not completely rebuild the unit?
Sounds familiar? We are makers after all!
ConceptThe control unit has a simple 2-wire interface to the gas boiler, and no active components or processor. It’s essentially a variable resistor. The reverse engineering was pretty straight-forward : the gas boiler sends a fixed current through the wires, and measures the output voltage generated over the control unit’s resistance. So what we need is a precisely controlled voltage source.
Rather than using a digital to analog converter (DAC), I chose to use the esp8266’s internal sigma-delta source, a bit of a hidden feature that was reported to work, but not yet supported in the arduino-esp8266 platform core. It’s a high-frequency PWM signal, with 256 discrete duty cycle steps, more than enough for this application. With a RC low-pass filter the PWM signal is smoothed to a DC-signal. The arduino analogWrite is not suited here, it has a much too low frequency, and then the RC-filter leaves a considerable ripple on the output signal. (For a simulation, try this interesting link : http://sim.okawa-denshi.jp/en/PWMtool.php)
With a resistor divider network and a PNP-transistor circuit in emitter follower configuration, we obtain an output signal in the valid range for this application (0.6V ..1.02V), with 256 steps over this range.
BuildThe electronics circuit can be easily built on a piece of single-sided perf board, and fits nicely in a project box of 100x60x25mm.
Use 2.54mm female headers for the Wemos board; this way the module can be easily plugged in and out afterwards if necessary.
For a power supply I used an adjustable DC/DC converter (buck), because I had access to a 24 VDC power supply on 2 spare wires in the thermostat’s cable, but any other stable 3.3V power source will do.
Adjust the DC/DC module’s output voltage before inserting the Wemos board in its headers!
Use wires of about 15cm in length to connect the OLED display, capacitive touch buttons and temperature / humidity sensor to the circuit board : these components will have to be glued in place on the front shell of the project box at the end of the build with a few blobs of hot glue. So make sure to solder all wires to the back side of these components.
Ah yes, the OLED module comes with a header pre-soldered : carefully de-solder this without damaging the oled’s glass, not like I did ..
Next are the capacitive touch buttons; they are an amazing piece of hardware! They only cost about 2€ for 10 pieces, and work great. Glued on the inside of the project box, they detect the touch through the plastic casing. Wow! No need for drilling holes, or fiddling with cheap looking push buttons! They work on a range of voltages, but on 3.3V here, because the ESP8266 I/O is 3.3V.
No need for debouncing either, all this is handled by the TTP223 IC. On the module there are 2 solder pads to change the behavior to active low/high, or on-off versus toggle-mode; I used the modules in their standard configuration : active high and on-off.
I had one touch button fail from the beginning, but why complain at 0.2€ per piece?
They are quite sensitive too; to avoid ghost touches I added an additional 1uF capacitor close to the modules power input. The sketch provided here will not only detect button touches, but also swipe gestures.
Next up is the project box; it needs a few holes : one in the back plate to pass the four wall wires (power supply and thermostat control), a hole for the temperature / humidity sensor, and a square hole for the display. A basic drill, a cutter knife and some patience with the tough plastic will do the job.
Then onto the most fun part of the build : the paint job. You might want to take the project box to a beauty parlor and have it professionally coated in a few layers of nail polish, or you want to give it a try yourself. At least, put on your most geeky outfit when going to buy the nail polish, take plenty of time to chose the right brand and color, and enjoy the weird looks in the shop!
With the paint job done, it's time to glue the OLED display, touch buttons and sensor in place with a few blobs of hot glue.
The finished project box is light enough to fix on the wall with two dots of blue tack, no screws required.
If you haven’t done so, start by installing the arduino-esp8266 platform https://github.com/esp8266/Arduino
For the display graphics, I am using Daniel Eichhorn’s great work for the esp8266 weather station. The library implements nice looking frame animations, and supports bitmaps.
https://github.com/ThingPulse/esp8266-oled-ssd1306
The library comes with a few built-in arial fonts, but Daniel developed an online tool to create additional fonts : http://oleddisplay.squix.ch/#/home . You won’t need this to rebuild the sketch though.
The NessieGraphics.h file contains all the bitmaps used by the sketch. The bitmaps are in xbm (X-Bitmap) format, a text based format, that can be cut and pasted as such in a header file, and compiled along your code. If you intend to create your own custom xbm bitmaps, GIMP is the goto tool : open any image file in GIMP, resize to the intended number of pixels, and save as xbm format. Easy!
The arduino sketch will connect to the Amazon AWS IOT service. Amazon offers a few options to setup this connection, see this link : https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html
I chose for the MQTT protcol with a client certificate as authentication, on port 443. For this connection to work only the Pubsubclient MQTT library must be installed additionally ( go to https://github.com/knolleary/pubsubclient, or install directly from within the Arduino IDE ). All other libraries to setup a TLS 1.2 connection are already part of the arduino-esp8266 platform. Amazing!
There’s a few more things to do before the sketch can work correctly :
- Of course filling in your WiFi credentials in the .ino file.
- a few library fixes must be applied : the files are in the bitbucket repository; follow the readme instructions.
- You need to give birth to your IOT "thing" now. Some of its parameters are required in the sketch. Read on!
The software build doesn't require any specific parameters. For reference, I used 80MHz, 1M+3M spiffs, no debug.
Amazon Web Services SetupNow it’s time to enter the maze of Amazon Web Services! If you have no prior experience with Amazon’s cloud services, like me, this step will probably take most of the time. It’s a complex setup, although logically laid out, and a lot of good guides exist, both by Amazon and others.
The learning takes time, but is entirely free! Amazon has a free tier for its services, that are largely sufficient to setup this kind of DIY project. The IOT service is free for the first 12 months, as long as you’re not sending millions of mqtt messages from your device.
Start by creating an Amazon account, and an Amazon developer account. You will need the developer account for creating your Alexa skill.
AWS - Part 1 : Creating your Thing on Amazon AWS IOTFollow these instructions https://docs.aws.amazon.com/iot/latest/developerguide/iot-gs.html
to create your thing, create a device certificate, setup a policy, attach the policy to the device certificate, and attach the certificate to your thing. No need to further configure your device here, or configure rules. We won’t use these in our application.
As you can see from the screenshot, I named my thing“stefaan_wemos”. This name will have to be hardcoded in the arduino sketch.
Once the device certificate created, download the files to your PC.
We will convert the client certificate and private key in binary format using openssl. On Windows you might need to install openssl : https://wiki.openssl.org/index.php/Binaries. On a command line type :
> openssl x509 -in c7ddc08d09.cert.pem-out cert.der -outform DER
> openssl rsa -in c7ddc08d09.private.key -out key.der-outform DER
Replacing the input filenames with the exact name of your certificate and private key. Keep the output file names as “cert.der” and “key.der” : these files will have to be stored in SPIFFS, and the sketch code is referencing these exact filenames.
I am not using the public key and root CA for AWS IOT; my code is not verifying the AWS IOT server’s identity. Blind trust ..
Under the tab ‘Interact’ you will find the last required parameters to get your esp8266 hardware connected to the Amazon cloud. Copy the strings shown in red on the screenshot to your sketch, and you’re ready to compile and upload!
If all’s well, the esp8266 will report its status to the AWS IOT device shadow. The serial output will help you identify potential errors.
The AWS IOT MQTT client console can be used to send mqtt test messages to the esp8266 device.
Publish anything on $aws/things/<yourthingname>/update, and you should see the message echoed on the serial output.
Or subscribe to $aws/things/<yourthingname>/update/accepted to receive any messages from the esp8266.
If you're not receiving callbacks from AWS IOT, then most likely you forgot to apply the library fixes, in particular the #define MQTT_MAX_PACKET_SIZE 768
in PubSubClient.h
.
If the Serial doesn't say "MQTT connection ok", look through the serial output for clues. There could be a problem with setting up the TLS connection : check the hard-coded AWS parameters, and the certificate/private key files.
AWS - Part 2 : Setup the AWS Lambda functionFollow this guide to setup your lambda function :
https://docs.aws.amazon.com/lambda/latest/dg/get-started-create-function.html
Make sure to create the function in the N. Virginia region. The function need access to AWS IOT and CloudWatch logs; make sure to set the policy correspondingly. Check that your view resembles the screenshot below.
Note your lambda function's ARN; you will need it later on when setting up your alexa skill.
Copy the javascript code index.js from my bitbucket repository into the code window. Don't forget to modify the objects 'iotData' and 'thingName' with your own thing's name and endpoint.
var iotData = new AWS.IotData({endpoint: "aaaaaaaaaaaaaa.iot.eu-west-1.amazonaws.com"});
const thingName = "your-AWS-IOT-thingname";
The bitbucket repository contains a few test events to test your lambda function. Go to "Configure Test Events" and copy-paste the sample test events (json code) in the text field. The test events allow to test the connection to the AWS IOT shadow, that you set up during the previous step.
If your esp8266 hardware is still connected, you will notice that the test events will effectively retrieve and modify the thermostat settings through the thing's device shadow.
If this is working properly you are one step away from a voice enabled thermostat!
AWS - Part 3 : Creating your Alexa Smart Home SkillAs a final step, we will create the voice control for our thermostat. We will be using the Alexa Smart Home framework.
From the initial screen, choose the 'Smart Home' skill type, and give your skill a name. Note the Application id (amzn1.ask.skill.xxxx) : you will need to add this to the triggers of the lambda function you created in the previous step. This will allow your skill to invoke your lambda function.
In the 'Endpoint' section, fill in the ARN of the lambda function you created before. You can add additional lambda functions in other regions too. (For info, I created a copy in the Ireland region, but it is never called. So I must be missing something here.)
In the configuration screen, set up the account linking; this is a mandatory step for an Alexa Smart Home skill. I chose to use the “Login with Amazon”; it's a convenient option because you don't need to set up your own authentication server. A good tutorial can be found here : https://developer.amazon.com/blogs/post/Tx3CX1ETRZZ2NPC/Alexa-Account-Linking-5-Steps-to-Seamlessly-Link-Your-Alexa-Skill-with-Login-wit
The fields shown in blue rectangles on the screenshots are specific to your skill and account linking. Make sure they are correct! If you get strange errors from the Alexa app while performing the account linking, come back here to try and find your mistake!
Now it's time to find your skill in the Alexa store, and activate it.
Once the account linking is successful, you can use any Alexa voice service to test your result. The video below shows the result using the Alexa app on android.
Final ResultClosing NotesIf you don't feel like waking up Alexa, you can always control the thermostat over its internal web interface. To expose the web interface to the outside world, a possible approach is to use a dyndns service, and set up port forwarding in your router to the esp8266.
There are still many options to improve this project. I hope it inspired you to get going!
Comments