Log 8: Control Software

A project log for SmartSoak

Maximize hot tub enjoyment, minimize cost

alexwhittemorealexwhittemore 09/15/2019 at 03:240 Comments

Finally, the meat and potatoes of hot tub control!

Here's my Node-RED flow. Every 5s, all four DS18B20s get queried and those messages are separated into four separate flows based on which sensor it is. Three of them are just telemetry and gauge channels. These get cleaned up and decimated to 1/min (all messages but one per minute get discarded), then passed along via MQTT to Adafruit.IO, which I use as a high-availability monitor and data logger that doesn't have to be behind VPN. One of the sensors is the water temp channel used for heater control. This also gets passed to AdafruitIO once per minute, but also feeds a heater control block, and some complicated logic to calculate the heating rate of the hot tub. This logic needs quite a bit of work, but it at least gives a sense on the dashboard of how fast the tub is heating or cooling. Eventually, I intend to use the calculation to determine if the propane has run out, so I can stop needlessly pumping water and possibly signal the need for intervention. 

The heater control block is from One disadvantage of this block is that it implements a schedule that can't be disabled. At least one schedule entry MUST be present, so the controller can't simply maintain the last set point indefinitely. In practicality, I just set the necessary schedule items to 0°F, and the hot tub begins cooling down. Since it's only about 2-3 hours worst case scenario to get it hot again, this has been an ideal scheme anyway, for now.

The DS18B20 library is a little tricky. There are a few to choose from, with various advantages and disadvantages. For instance, one I find more convenient to use, since it generates its own messages without input, but it doesn't handle multiple sensor busses. It worked fine when I had a couple sensors on one bus, but broke when I split each sensor out on its own. The one I'm using now is If I recall, I had to do some trickery to get the multiple busses set up right. I'll try to figure that out and add some post-facto documentation.


One of the most convenient things about Node-RED is that it comes out of the box with a whole infrastructure for building a web-based dashboard UI. This UI can in turn be accessed from anywhere - a cell phone, the device itself if it has a screen, and so on.

My plan was to use a cheap Android tablet, dedicated to the hot tub, rather than having to build some kind of custom physical UI. Unfortunately, all the usual cheapest suspects (Kindle Fire 7, etc) are actually too underpowered to tolerably load the web UI, since it's pretty javascript heavy. For now, I've just been using my phone. Eventually, I might build a touchscreen or button-based interface into the raspberry pi and cable box itself. 

Here's what the UI looks like as-is:

Where can I see the flow source?

Node-RED flows are stored as a JSON file on disk, representing all the nodes and connections of a flow. There's a new(ish?) scheme called "Projects" that abstracts flows into complete, packaged and portable "projects" that exist automatically under Git version control. But I haven't enabled this yet for this particular project, as it requires some reconfiguration of Node-RED that could be damaging.

Sometime this week or weekend I intend to

  1. Back-up the setup as-is by copying the flow off the disk, as well as by making a full copy of the SD card image for immediate roll-back
  2. Upgrade Node-RED to V0.20.8 (I'm on V0.20.7)
  3. Enable Projects
  4. Move this flow to a project

This will set me up nicely for upgrading to V1.0 when it comes out in a matter of weeks, which probably won't go smoothly and will likely require rollback to 0.20.8 while component compatibility bugs get fixed.