Skip to Content

Setting up smart heating control on the CTRL ONE - PID controllers

29 October 2026 by
Setting up smart heating control on the CTRL ONE - PID controllers
Elvin Luff
| No comments yet


ESPHome allows you control your heating system like the cruise control on a car. A traditional thermostat runs your heating at full gas until it reaches the setpoint, but a PID controller smoothly regulates your heating system to meet and hold the setpoint instead.

The CTRL ONE is not the only smart thermostat out there that does this, but it does give you absolute control over every setting. It also gives raw temperature readings down to 2 decimal places that don't try to smooth the graph or hide detail to make it look better than it is.

What is a PID controller?

A PID controller stands for Proportional, Integral and Derivative. They are three elements making up a mathematical model that takes an input, and then varies the output until the input matches a desired value. The main point is that there's no relation between the input and the output.

In our case the input is the current temperature, and the output is the amount of heating power applied to the system. It compares the current temperature against the desired temperature (setpoint) and measures the error (the difference between the actual temp and the setpoint) and applies a certain amount of power to reach that setpoint.

It's not like gears on a bike, where you know that a certain number of input pedals will equal a certain number of output wheel rotations. What the output does to the input has an infinite number of variables, many not in our control (the sun comes out, a window is opened, etc).

The values you tune (Proportional, Integral and Derivative) essentially dictate how hard it drives the output to reach the setpoint, how it should back off as it reaches the setpoint, and what it should do to prevent going past the setpoint (overshoot).

Implementing it in ESPHome

https://codeberg.org/elvinhome/ctrl-one/src/branch/main/esphome/addons/addon-24vac-thermostat.yaml is the simple bang-bang controller. It simply turns on the heating system when the temperature is lower than the setpoint, and turns it off once it goes past it. There's a small deadband so it doesn't constantly trigger when it's right on the edge.

It's all based on ESPHome's Bang Bang Climate Controller. It can also be tuned, for example the deadband, and how often the switch turns on and off. The issue with bang-bang controllers is that they tend to oscillate around the setpoint, as it only activates when it goes above or below.

If you're ready to try a PID controller, move over to https://codeberg.org/elvinhome/ctrl-one/src/branch/main/esphome/addons/addon-24vac-thermostat-pid.yaml! It uses a few elements:

  • The PID climate component calculates what percentage output power the heating system should give, from 0 to 100%.
  • The slow_pwm component turns that value into a series of on/off switches. If the output is 50%, then in the 30 minute period, the heating system will be on for 15 minutes of that time.
  • The switch takes the slow_pwm output and actually turns on/off the heating system.

What's the catch?

Any smart thermostat worth its salt on the market uses some algorithm that accounts for the characteristics of the heating system, and a PID controller is one form of that. The issue is that it first needs to "learn" what the PID values should be, as the heating system in every house reacts differently. Every house heats up at a different rate, heating systems take time to turn on, and external factors like sunlight heating the home is different in every case. I'd recommend starting with the bang-bang controller to get an idea of the characteristics of your home, and ensuring it works.

Also, while a PID controller gives a really accurate number on how much power the heating system should output, it will be limited by the capabilities of your heating system. If the system itself doesn't allow for granular control of the output, then that is the where the bottleneck lies. 

Valves and boilers are not meant to be turned on and off rapidly, and are rated for a certain number of actuations over their lifetime. They also take a few minutes to turn on/off.

By default the PID controller example in the above section uses a slow PWM cycle of 30 minutes for this reason. This means it will only cycle on/off every 30 minutes, and you should look up the specs on your heating system to make sure you're not cycling yours too frequently.

Making the cycle too fast could end up with an even less efficient system, if your system takes extra time and energy to get fired up and running.

How to tune it

There's two different tools that can help tune the controller. ESPHome's PID climate controller has a built-in autotune function that will repeatedly raise and lower the setpoint, and measure how your heating system responds.

Alternatively, AI is a really great tool for this! In my setup, I set up the CTRL ONE as a bang-bang controller for a week. I set up a schedule where the setpoint lowered in the evening, and went back up in the morning. This created that repeated raising and lowering action. I then gave an LLM access to the historical data of the CTRL ONE thermostat in Home Assistant, and asked it to recommend the correct tuning values.

After running it for a few days, I found that it was still overshooting the setpoint, so I asked it again to analyse the data and tune the values further. You can see the results in the video, and the result is about a 0.2 degree swing in temperature when it's on the setpoint. This is simply due to the limitations of my underfloor-heating as explained in the section above.

If you're looking to get a lot more granular control over your heating system, check out the CTRL ONE with its 24VAC addon! This is designed to control simple under-floor heating systems, electric heaters and older boilers. I'm currently working on a new solution for Opentherm boilers, more information on that in a month or so.

Check out the CTRL ONE >>

Sign in to leave a comment
Turning my DS Lite into a game controller - DSpico