A Thermostat Weekend

tmp3C7AAs I make changes and I don’t want to bore readers – I’m adding sections at the top of this article and moving earlier versions of the stat down the page. If you are new to this you might want to start at the bottom at the point in this blog entry marked “The Old Ways”.

The Newer Ways: You will read below about last weekend’s work on the thermostat control – here is the link to the current code which now also handles a de-humidifier (not on a timed basis) and a heating using indicators built into the gauge (my thanks to the author for his help). The image on the left depicts the latest version.

Mobile Thermostat panel by Peter ScargillThe New Ways: This is about a DIY Thermostat in Node-Red – if you want to read about how I got to this point, start at “The Old Ways” then come back up here. If not, read on. Here’s a short video. So – you want a thermostat using Node-Red Dashboard (remember you can set all of that up on a variety of hardware alternatives using the script – which turns your little SBC into a potentially powerful central control system for IOT). Here it is.  You should be familiar with Node-Red, Node-Red dashboards and flows. If you need to know more about home control you could read all about it in what is now called the Home Control 2018 blog (quickly before I come up with a reason to change that to 2019). Lots of links in there to code for Esp8266s (ESP-GO) etc.

I’m assuming you have sensors and a relay board to control the heating and all you need is the pretty bit with glue in the middle, understand basic heating and are ready to go.

Here it is on the left – two days of solid graft. With this magic screen you can set up an entire week’s heating, controllable at hourly intervals – in a minute if that. Each hour can be poked with finger or mouse, adjusted and at the touch of a button replicated to the next hour. Similarly a whole day’s settings can be instantly replicated to the next day etc. You have control of the automatic temperature, with manual override as well as frost and stat settings and all on one colourful screen.

And if you don’t like it – it’s all there in source in Node-Red – what could be easier.  I must’ve made a dozen variations as you’ll see in “The Old Ways” before coming to this – what’s really exciting is that some of the control and display elements of Node-Red Dashboard are getting easier as I go along – at first I seemed to get no-where, now, the sky seems like the limit.

So – each of those coloured elements represents one of the 24 hours of the day – simply select by touch (the black bar will light up purple) an move left or right using the bottom arrows. The COPY button next to it will replicate an hour in the next one if you have selected an hour – or will copy a whole day if you’ve selected DAY. You can select frost and away settings and adjust temperatures there. On the top of the display is your actual temperature – and settings to adjust the SET temperature – and away from hours (>) to days (>>).  A is for automatic! When you have the settings the way you want them – use the disk icon to save or use the cancel icon to revert back to what you had before you started. That’s it – nothing else.  The data (a very small amount) is stored in your /home/pi directory but of course you can change that.

And here’s the flow you’ll be looking at – complete with lots of test buttons.

flow for the thermostat

This is slightly different to the code I’ve put up as I’m now monitoring actual temperature (the purple MQTT node top right – in the demo code I have kept the demo buttons).

The left side is entirely test material, storing values from your temperature and humidity sensors (the latter is not used as I ran out of room to display – maybe this week I’ll re-think the sizes slightly. I’m also pondering expanding the hour-day idea to hour-day-zone as I have two heating systems here but that will be later and I’ll leave this code intact).

Note: You’ll see some icons here – I’ve not distributed then as I’m not 100% sure of their copyright status – if you look around and look at an earlier blog talking about icons and .png files – there are no shortages of decent transparent .png icons for you to use – there are also a bunch of them built into Angular.

Temperature display from the new thermostatAll seems to work – in Chrome on the PC and on my HTC phone the displays are identical. Now – if anyone would care to ponder improvements – maybe find enough room in that right corner to get some more info…. do write in with ideas and code.

HOLD THE PHONE: I think I’m in love… check this beauty out on the right – found it HERE and modified the colours, text and size – a true work of art – quick modification in a browser and I changed parameters to make it do temperature (originally speed) change colour – etc…  I have it working in a simple local web page but sadly when I put it in a template right now – I get a white screen… I’m at a bit of a loss as to why.. if anyone wants to step in here….. it is so lovely it would be a shame to miss.

And finally: The original gauge here had a grey display with decimal points. I needed to get rid of those as I’m dealing in integers. I contacted the author Mykhailo Stadnyk

At the end of that – two new parameters – valueInt:2 and valueDec:0 gave me what I wanted – a simple integer degrees printout.

If you are using my flows – and creating directories etc, always remember that Linux and Javascript are case-sensitive – don’t go making directories/files  in upper-case and addressing them in lower-case.

Oh – LEDS –  I just found this – lovely CSS LEDs  – I need to figure out how to add one into the canvas.. I’ve also asked hr writer of that gauge if he’d consider adding in an optional LED indicator for me (boiler active).

The Old Ways: Here is where this all started.

As it happens, a few days ago, reader Antonio pointed me to a little ESP8266 Thermostat – well, some code for it anyway, using one of those little 120*180 displays.

ESP8266 stat gave me ideasI’m not that partial to Arduino development but I grabbed the code and stuck it on my hardware. Some great ideas there – but the implementation using a rotary encoder left something to be desired – and the code doesn’t support MQTT – and minus temperatures messed the display up. Oh and it seems to be partly in Italian and partly in English. Oh and a good but not especially long-lasting sensor is sitting right next to warm electronics and a warm display.

Don’t get me wrong, a STERLING effort and no doubt it will go on to be very good – but it wasn’t quite what I was looking for. It certainly fired me up.

As you all by now know I’m an MQTT/Node-Red/Mobile phone kind of guy and so armed with my new knowledge of Node-Red Desktop I sat down with coffee on Friday morning and started to put together some new thermostat code (as if I needed more). One of the things I really liked about the ESP code was the timing page you see above. I have 5 time zones per day which can be any temperature – different at the weekend – but not without it’s issues – what if the weekend is not your “special” time for example – and it needs lots of controls.

This on the other hand was simple. I got to thinking – but if it was on a touch screen you would not have all that selecting nonsense and what about replicating settings for every day and….

And so it was that I sat down with a gallon of coffee and did what I always do – plough in with the code long before I’ve put a plan together. Sometimes it works, sometimes it doesn’t. Hey, I’m a one-man team!

Templates on Node-Red: Well, this time it did and I’m chuffed, but before getting into this – a quick lesson on using TEMPLATES in Node-Red Desktop.

Templates are easy – pretty much you can make a web page in a template – you can even have includes and JQuery comes with the deal.  The problem I’ve always had in the past is getting stuff in and out of the template – the examples given really don’t help and I spent HOURS trying to get to grips with this.

Scargill's very first Node-Red thermostatWhen we were messing with buttons (see other blog entries) I got a lot of help from folk, most of it I understood, getting variables into the Template I most definitely did not – but it worked and now the light is coming on.  Remember the good old days of ASP programming and other server-side interpreted coding – you had this code on the server which was NOT in the same space as the code in the web page. Well, this is similar.

The likes of msg.payload sits in Node-red along with global variables, context variables  etc. They do NOT reside in run-time Javascript on the web page and that had me going in circles for ages. Well, there is a way around it, digging through the code we ended up with for the buttons I extracted this and modified it a little…

scope.$watch(‘msg’, function(msg) {
// do stuff in here with msg… which includes any part of msg, even arrays etc.

So here we are on the web page – in a script tag – and we drop this in. I know – what the HELL is scope (yes I know what variable scope is). I can’t tell you in detail but I can tell you it works perfectly!  As soon as you inject the normal Node-Red msg (entire) object into the template – where that // comment is above, you can use the lot inside that function, calling javascript functions etc. Note that in typical examples elsewhere – inside that function you’d see the word data – and I’d previously then used “data.payload” etc. – however, keeping the name the same (msg) makes it easier.

Along with the ability to fire out information back to Node-Red with this and similar for buttons..

ng-click=”send({payload: ‘hello world’})”

The first attempt: With that realisation I started on my new little thermostat. The most COMPLICATED page is that of settings – and the project above that I really liked – got me started as gives you 24 settings every day of the week. FANTASTIC – but I had to make it easy. Now, it is REALLY easy. You can set up programs for the entire week in a minute.

Over on the right – you see my FIRST interpretation of this – yes, it works – I just don’t have a relay fastened up yet to DO something.

Ok –  the colours were not that subtle – don’t be awkward – I only started on Friday morning after a fear-filled, anaesthetic-devoid double-crown fitting at the dentists via a 90+ mile round trip. – yes, I was brave though it nearly reduced me to tears – so bear that in mind before criticising my colour taste  – I’ve change it as you’ll see later. The buttons are simply Angular buttons with png images inserted.

So – you can touch/click on any of the timings – or temperature, or day and using the up and down buttons (they’ll end up as left and right arrows) you can change the temperature from one of the presets for that time or the time slot you are playing with or the day. The black line under the relevant item will turn purple (for now).

Scargill's very first Node-Red thermostat flow

If you want to replicate the setting on subsequent hours, press/touch the copy button as often as you need (auto-increment). If you want to replicate the LOT, click on the DAY and then on the copy button and you’ll start whizzing through the days (auto-increment), coping the entire 24-hour schedule across – you can then tweak bits later. When you are happy you’ve not messed anything up – press the save button.

Now this lot is simply stored in an array – 24*7 bytes plus 4 bytes for the temperatures – so as an array, stored on SD it takes up almost no room – by using a 2-level array you could EASILY expand this into different ZONEs – so as well as a DAY field you’d have a ZONE field and a copy operation would copy the whole lot to the next zone –  etc. Seriously this is a DODDLE to set up.

Finally a cancel button…which simply restores the array from SD – that function is also called at power up to get the values in the first place. I could probably do with a timeout on saving to avoid the (admittedly small) write to SD on every change. Still – not something you’d do a lot of.

So now we have a non-volatile global array with all the info in (I jammed the temperature settings on to the end of the array) – a separate page will show the temperature with a nice pretty dial, let you change manually up and down that for a given time – what, 4 hours before reverting to auto? and of course you’d want to show the humidity and pressure – very important they are all super accurate so I’m thinking a single BME280 would do the lot for you!!!

And that’s it – the output of “process heat” is simply the required heat value, sent out every minute. I picked a minute – could be 5 minutes – if you are working with, say, an oil boiler you really don’t want to be changing things rapidly. You can use this value to display in another page as the “set” temperature and to compare with the REAL temperature to decide what to do with, say, a relay.  Options might include a manual override – which should time out after a couple of hours maybe – and maybe a longer-term override in case you want shopping or are away for a couple of days in which case you might want to go to the lowest setting (offset zero in the global array) for some period. Normally for manual override you’d simply ADD your override figure to the automatic figure – i.e. 2 degrees WARMER or COOLER. My next job will be to do a nice job of the main stat display page.

The main page will no doubt also feature the local weather forecast – again from a previous article. One could even add a complete week’s predictions with icons.

More on this in near future – here is the current FLOW for this (no support and it WILL change in time) so you can just drop it in into Node-Red. Aren’t you glad you adopted the latter!

Scargill's very first Node-Red thermostatAuto-learning

To do auto-learning I think I’d change this – instead of 4 fixed temperatures I’d allow arbitrary temperature between, say 14c and 26c for every time slot (could do that now)…

Now, given THAT you could maintain a separate array – and every time someone makes a manual change – this would added to the second array (initially zero in all values).

After, say 4 weeks, you could divide the array down by, say, 4 (so that X degrees updated on the same hour for all 4 weeks would show up as one change) – and merely ADD that to the main array – clearing the second array. That way the system would have learned from the last 4 weeks changes but be ready to adapt to another 4 weeks changes etc. That’s one way – without getting too silly about it can you think of a more USEFUL way of adapting?

Thermostat – The Return of the Stat: Well, it had to happen – once I started writing about this – I started thinking how DAFT that 4-temperature limit is – and so  – well, I changed it a bit…   a lot, actually.

The panels now gives full control for every hour of the week but because of the copy system, it still takes only a moment to set the entire week up and it did occur to me that it would be a doddle to extend this to a ZONE system with umpteen zones, even.

I’ve also spent ages working on colours so as you can see – as you adjust the temperatures, the colour changes per degree and it’s quite pretty.  And there is status help.

I’ve added in frost and away settings as you’ll need those for the front panel controls (up, down, set away, set frost).

I have to say, it looks beautiful on my screen. I’ve stripped out a lot of  CSS and put classes in to make the code at least partly readable. There’s a timeout on all the message that appear when you press buttons – should be 5 seconds but right now they vary a little – any Javascript experts – feel free to take a look at the function – but it all works well enough.

Here’s the second flow – this supersedes my first attempt.  Oh you’ll need to find some images – and change links accordingly. On my Pi2 I have a directory /home/pi/.node-red/public/myicons with a ton of folders in there with png images in them – well you have to make use of all that space.  You’ll need to find your own – there are many out there – make sure they are transparent. But then – if you’re working with Node-Red and Dashboard, it really is worth setting yourself up with a good selection of icons and images anyway.

Oh – the data… in “Process controls” you’ll see that we’re looking at an array of 168 bytes plus 2 bytes to store frost and away temperatures – that’s it. See later articles as this has all been improved.


114 thoughts on “A Thermostat Weekend

  1. Hi Pete,
    for me the “away” function works only for the “days”.
    If I click the >> button, it increases the days, but if I click the > button, it increases just for 1h, if I keep pushing it, nothing happens.

    Another thing that I’ve noticed is that in the debug I often see this message: “TypeError: Cannot read property ‘tout’ of undefined” related to the “trigger 1 min”.


  2. Hi Pete, Just spent the day incorporating this into my HA system. Super easy and works lovely. Many many thanks for sharing all the hard work you have put in on it.

  3. Make sure you don’t have the com port tied up doing other stuff (i.e. serial monitor in the Arduino IDE). Otherwise, it all should work. I’ve found that sometimes I need to supply my own 3.3v power to the serial to usb (FTDI) adapter, depending on the PC I’m using and the ESP8266 board that I’m flashing but other than that, once you get the hang of flashing these ESP based units, they’re pretty much the same.

    I’ve flashed various sonoff devices (basic, TH10, TH16, slampher, POW) and provided I have a good 3.3v power into the device, have a way of invoking flash mode (by momentarily connecting the relevant GPIO pin) and the correct firmware for the flash memory size, I’ve managed to flash ESPEasy, Tasmota and Arduino based code to these devices with ease.

    That’s what I particularly like about SONOFF – they encourage the Maker community and make it relatively easy to replace their proprietary firmware with your own (or alternatives).

    1. Thanks Darren!

      As, 15 minutes earlier I had just finished flashing a Sonoff basic [ 4 of them done the same day and 16 basics all total] without issue and nothing altered on my laptop, other than connecting to a TH10 which failed, I suspect I have missed an important instruction or, like you suggested, maybe the 3.3 Vcc from the USB/Serial device is not up to the task.

    2. Like Darren, I built a programming fixture that contains its own 3v3 supply.

      If you are having problems getting a device to flash, put a voltmeter on the 3v3 wire to make sure it isn’t dropping below 3V.

  4. Is there anything different to be done to flash Tasmota to a Sonoff TH10 rather than Sonoff basic. I have successfully flashed 16 Sonoff basic units with this command

    esptool.exe -vv -cb 115200 -cp COM3 -ca 0x00000 -bz 1M -bm dout -cf sonoff.bin

    Just flashed a basic about 15 minutes ago but cannot seem to get a serial connection to the TH10

    trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
    warning: espcomm_sync failed
    error: espcomm_open failed
    error: espcomm_upload_mem failed

      1. All the information on the wiki pages is how it is “supposed to work”.

        As both a Director of Engineering and Electronics Engineer and a former Technician I found quite often things don’t follow the book and that I why I posted on a site with people who actually use this stuff to see if anyone had any issues with programming a Sonoff Basic vs a TH10.

        When things fail, by definition, they are no longer following the rules be it human error or technical problems.

  5. Hi Pete,
    finally I’ve found a weekly chrono-thermostat that is missine even in most home automation sw (like DomoticZ, Home Assistand or OpenHab).
    I’ve tried to copy your code into Node Red, but it says that these are missing: ui_template, ui_group, ui_tab.
    What am I missing?
    Thanks and well done,

  6. Dear Peter, thank you for your fantastic work.
    I just have a backup and restore problem. When I finish the temperature configuration and I saved the settings, if I restart the PI I lost all the temperature program.

    Do you have any idea to help me ?

  7. Hi Peter

    This looks like a fantastic project. I am completely new to all this, and confused by the installation process of installing this and how to get the icons and gauge to display.
    I think this could be a great way to learn the systems used.
    Is there any chance of a short video or some detailed step by step instructions how to install this please.
    Thanks for you devoted work to this.

    1. Hi Laurie

      This was done some time ago and intended at medium level – I don’t have the time to do a training video I’m afraid. About the only problem I’m aware of that anyone has recently come back to me with is spacing – in Node-Red you need to adjust the cell sizes (in Dashboard – site) to widget size 56 * 40, widget spacing 3 * 9, group padding 6 * 6 and group spacing 3 * 3 – this is because all of this was changed at some point in Node-Red.

      Take it step by step, learning about how the various bits work as you go along – it will all appear straightforward after a while.

  8. Just been getting my head around Node red and really taken by the thermostat, had a play with it but struggling with the icons is there a how to on them as in how to install and where to as i would like to try this control as we are doing some upgrades to the heating and this might work well for this.

  9. Hi Maybe I can add my two-penneth to the suggestions re replacing a thermostat in the heating system.
    1 It would be nice to know what the current wiring setup is (S-Plan, Y Plan or some variant) and whether the existing controller, wiring centre and (if used) Mid position valve were being retained. Incidentally it would seem to be getting only part of the benefits whilst taking on most of the effort not to replace the controller along with the thermostat and missing the chance to utilise the Big Timer.
    2 If there is a standard Drayton wiring centre then all components are on a common neutral and uses mains level voltage to control the diverter valve and fire the boiler so I cannot see the inherent risk of using a Sonoff providing the correct connections are made.

    If I have misunderstood the advice or based my response on different assumptions I apologise, Also if the original query was asking whether he should connect Call to Neutral I would suggest he gets professional advice before he goes ahead as that will not work and may short circuit depending on other connections

  10. Hi Pete, i’ve drawn inspiration from your blogs and started building home automation with SONOFFS, tasmota firmware (which is by far the best ESP8266 firmware in my view in terms of simplicity to get running), MQTT and node-red.
    All working a dream, including connecting to homekit / apple, graphing, kitchen temperature and visual display with weather forecast., google cloud compute + cloudmqtt

    I’d like to now replace a really old room thermostat (RTS drayton) with a sonoff to control central heating. (https://www.diynot.com/diy/threads/replace-rts1-drayton-thermostat-with-simple-ac-on-off-switch.477064/)

    Have you any pointers as to how you’ve physically connected up your (as assume) sonoff to your boiler system. My worry is as sonoff has a shared neutral, if i get this wrong its going to blow something up.

    I’ve succeeded in getting the old thermostat off the wall and connecting neutral and live to sonoff to power it up, but little reluctant to what to connect to output..
    ie do i connect the same neutral + Call or live+call…


    1. I would not chance connecting live or neutral to the boiler controller. Much as I love Sonoffs, I always use a relay that is uncommitted, i.e. just a pair of contacts, when connecting to the heating system.

    2. in general heating boilers have a normally opened contact, you link the 2 wires to the normally opened pairs of a relay and use it just as a switch, without passing the mains power to it… and so, this could help you (there’s a boxed version, too, look bottom in same page):

      or you can do it yourself with basic premade components, all very well explained here 🙂

    1. Ciao Daniel

      I’d like to implement over your panel! How do you control heater when the temperature changes? I have a DS18B20 thermometer in my house, how do you inject the temperature into your thermostat?



  11. Going back to electrothermic actuator heads, these are the ones that Chris Dobson mentioned:
    http://www.plumbingandheating-solutions.co.uk/epages/BT4013.sf/en_GB/?ObjectID=22219355 (4 wire version) £13.71 a piece

    And here’s a slightly cheaper 2 wire version: http://www.plumbingandheating-solutions.co.uk/Emmeti-01213242-Actuator-head-with-indicator-2-wire-240V £10.98 each

    Interestingly these are in the category of underfloor heating but I’ve a feeling they fit regular central heating radiator valve manifolds..only a feeling mind you because I’m not a plumber.

    1. Certainly worth knowing about. A shame by the time you at VAT and postage the price goes up considerably – but still do-able. Can anyone confirm these would fit standard radiators?

  12. Peter
    It might be worth mentioning that the input temperature needs to be an integer otherwise the heat will turn at 20.99 if the set temperature is 21 for instance.
    I am currently experimenting with the input temperature rounded to 1/2 deg to see how that works out.
    Or maybe you could add some hysteresis into the thermostat?

  13. Hi. I have the thermostat working, but I am getting very irritating vertical scrollbars on the two-tone SET, AWAY and humidity blocks in the upper right. It seems the table is just a couple of pixels too tall for whatever container it’s in. Some bizarre css behavior I’m guessing, but I can’t figure it out.

    Just wondering if you have had this issue and solved it.

    1. Somewhere in recent blogs on this subject I have included some CSS – to get rid of wasted space – you should always have that on any page with my stuff in it.

      1. I’ve got the same issue with scroll bars. Did a search re wasted space and could not find the blog you referred to. I pulled the whole flow in and it does have a ‘css etc’ template in it.

        Could you point out where I’m going wrong?

      2. I am not a CSS expert but it looks like the box model on the ‘Set’ box (for instance) is not being calculated correctly. The outer box model reports as being 48×48, but inside this it is 31x 56 which is why the scoll bars are appearing.

        If in the Dashboard side bar I set the Widget Spacing as 12 and the group padding and spacing as 0 I can get rid of most of the scoll bars except the 3 with text in the top right.

        How to fix it is beyond me! 🙂

      3. I like a challenge and this bugged me.

        For me, to get rid of the scroll bars using the std Node-RED widget sizings and spacing;

        In the gauge template;
        I changed the size of the gauge to 156×156

        in the CSS etc Template;
        I changed the thead th style padding to 5,3,4,3
        I changed the tbody td style padding to 5,3,5,3

        In the Settings template
        I changed the main table tag to
        width=”318px” style=”border-spacing:0;”

        It isn’t absolutely right as the height of the settings is less than the 318px it should be so it needs a little padding out but for the moment it works for me 🙂

  14. Hello,
    i install your flow on my C-1, but i have little problems, i have 3 rooms with heating convector’s with 2 heating head + 1 wind fan, i correct code for my configurations, but when made 3 copies of thermostat they show same measures and controls.

  15. Using today’s code I’m having issues displaying the default 40% under Dehum – it is just saying ‘undefined%’ , so highlighting and using ‘<>’ just displays ‘Hit limit’ – everything else is working fine, including my feed from nr for temp/humidity.
    petesstatlog.log is only showing timing 0-169 , 170 is not saved.
    Any ideas appreciated.

    1. See latest update as of 5 mins ago – all appears well now and I’ve made some changes – read the comment under the snippet.

      1. Peter,
        I’m still have the same issue with the latest code – I reinstalled your code and deleted log file.
        Dehum still showing ‘undefined%’ instead of 40%, after doing a ‘save’ checked log file and it did not have 40 at the end, just default away temp of 14 – but your script in function(process control) has added 40 to context.global.timing.
        I added 40 to the log file, did a save and rechecked log file and it had been removed.
        Thanks in advance

        1. Can you clarify – are you saying it works but the code is wrong on the page? I’m off shopping – if you can clarify that I can fix it later.

          1. I am unable to set the Humid value, as it always displays ‘undefined%’ – trying to increment/decrement the value fails because it is not seen as a numerical value.
            Your script in function(process control) shows 40 added to the context.global.timing array, but if I do a save, the humid value is not at the end of the petesstatlog.log.
            Had a quick look at the code, but couldn’t see where the issue is.

        2. Allan – all I can suggest is to shut down Node-Red, delete the file with the stored values and start up again at which point the file won’t exist and the array won’t exist so it will be created with defaults… as I can see no reason why you cannot write that value. The array is big enough… unless you had an earlier version running and you’re restoring from that. I can’t reproduce that issue here.

          That of course is always a possibility and will continue to be so as what you see is merely intended as a starting point for others – it will mutate and change as I learn more.

Comments are closed.