Driving Electric Heaters with OpenHAB, Pilot Wire and Wi-Fi Sensors

Until recently, my heating control system relied on a combination of old “dumb” electric heaters, Oregon temperature sensors, and Chacon on/off modules. Everything communicated over 433 MHz using homemade RFLink gateways running my RFLink2MQTT software on my home made box.

On the software side, I had implemented a custom control system based on target temperatures (Comfort, Eco and Away modes), current room temperature, and a small hysteresis of 0.2°C. The logic was simple: switch heaters on and off to maintain the desired temperature. It worked surprisingly well and served me reliably for many years.

While the software side has proven to be robust, the hardware started to show its age:

  • Oregon temperature sensor readings are not always received reliably.
  • The mechanical relays inside Chacon DIO modules tend to fail after three to four years of continuous use.
  • My heaters are now more than 15 years old. Besides their poor cosmetic condition, they lack the comfort and thermal inertia offered by modern electric heaters.

As I recently had to replace several heaters, I decided it was the perfect opportunity to redesign the whole system. The new version combines modern Wi-Fi temperature sensors, pilot-wire capable heaters, and OpenHAB automation while keeping the same philosophy: simple, reliable and fully automated heating control.

This is the story of my refreshed heating system…

Approach

Problem to solve

Unfortunately, replacing the heaters also meant redesigning the control system in OpenHAB.

Modern electric heaters contain much more electronics than older models, and it is becoming increasingly difficult to find units that behave correctly when their power supply is simply switched off and back on. Most of them require user interaction before resuming operation, such as setting the date and time. Some even emit an annoying “beep” every time power is restored.

As a result, cutting the mains power was no longer a viable control method. I needed a way to drive modern heaters while keeping them permanently powered, without relying on any cloud-based solution.

Another issue is that I have never found a heater with an integrated thermostat capable of maintaining a truly accurate room temperature. When the weather becomes very cold, the actual temperature often ends up below the configured target. For this reason, I wanted to keep my OpenHAB control logic based on external temperature sensors and a hysteresis algorithm.

At the same time, I wanted to move away from my aging 433 MHz infrastructure. While it served me well for years, a Wi-Fi based solution would provide better reliability, easier integration, and one less custom hardware platform.

The concept

My goal was to keep the same temperature + hysteresis approach that had worked well for years, but replace the crude on/off power switching with a more subtle control mechanism based on the pilot wire available on modern electric heaters.

In my setup, I use three temperature profiles:

  • Eco / Low: when nobody is using the room or during the night
  • Comfort / High: when the room is occupied during normal daytime hours
  • Away: when the house is unoccupied for more than one day

The idea is to continue using external temperature sensors while driving the heater through its pilot wire. Depending on the measured temperature and the selected target profile, OpenHAB switches the heater between the following states:

  • Stop: when the room temperature exceeds the target temperature plus the hysteresis value
  • Comfort: when the room temperature is outside the hysteresis range and the selected profile is Comfort / High
  • Eco: same logic as Comfort, but for the Eco / Low profile

This approach combines the best of both worlds. OpenHAB remains responsible for room temperature regulation using accurate external sensors, while the heater itself can still use its built-in control logic and optimized heating modes.

The heaters are never completely powered off, and with properly configured Comfort and Eco temperatures, pilot-wire mode changes occur relatively infrequently. This results in a more elegant and reliable system while preserving the temperature control accuracy of the original setup.

Implementation

Temperature Sensor: Shelly Plus H&T

To replace my aging 433 MHz Oregon sensors, I chose Shelly Plus H&T devices. They provide temperature and humidity measurements over Wi-Fi and provide a simple yet nice display.

My initial goal was to run them on batteries, just like the Oregon sensors. Unfortunately, when battery-powered, the Shelly Plus H&T only reports new values every two hours, or when the temperature changes by more than 0.5°C. This is perfectly acceptable for monitoring, but not for heating control.

The problem appears when the temperature changes slowly. For example, if the temperature changes by less than 0.5°C every few minutes, the sensor may wait nearly two hours before reporting a new value. The resulting gap between the actual and reported temperatures is simply too large for accurate heater control.

I therefore tried the USB-powered trick described here.

The idea is to force the sensor to report itself as externally powered, resulting in much more frequent updates. It worked very well, but battery life dropped to only three or four weeks, far from the six to eight months I used to get with my Oregon sensors.

In the end, I decided to power all Shelly sensors from USB.

For OpenHAB integration, I first experimented with the official Shelly binding, which relies on WebSockets. While it works, I eventually switched to MQTT. MQTT is easier to debug, easier to monitor, and avoids introducing additional complexity into my k3s-based infrastructure.
 
 
 
Below is an example of the sensor configuration:

The rssi2signalstrength.js  transformation converts the Wi-Fi RSSI value (in dBm) into a more user-friendly signal strength indicator based on the Metageek reference scale:

Finally, here is an example of the corresponding OpenHAB items. Note that the Sensor_Updt  item is used as a timestamp indicating when the last update was received from the device:

Heater Driving with Shelly PM Mini and Shelly Plus 2PM

The pilot-wire control concept is well known in Europe and extensively documented on the Internet. I simply never had a reason to look into it before, as my previous on/off based solution worked well enough for many years.

The idea is to use a pair of diodes together with a Shelly Plus 2PM to generate the four standard pilot-wire modes supported by most “modern” electric heaters:

  • Comfort
  • Eco
  • Stop
  • Frost Protection (Anti-Freeze)

To monitor the actual heater power consumption, I also installed a Shelly PM Mini Gen3. This is necessary because the power reported by the Shelly Plus 2PM only reflects the consumption of the pilot-wire control circuit, not the heater itself.

Below are some real-world installation photos. One thing I particularly like about this setup is how compact it is. The Shelly Plus 2PM Mini, Shelly PM Mini Gen3 and the required wiring all fit inside a standard wall box using only three heater wires: phase, neutral and pilot wire.
 
 
With the way I wired the diodes, the pilot-wire modes are mapped to the Shelly Plus 2PM outputs as follows:
Mode SW1 SW2
Comfort Off Off
Eco On On
Frost Protection On Off
Stop Off On

While implementing this, I discovered an interesting inconsistency in the Shelly MQTT API. According to the official documentation the status and command topics do not use exactly the same format.

The status of an output is published on: <device-name>/status/switch:0 

The payload is a JSON document containing an output key whose value is either true  or false.

Commands, on the other hand, are sent to: <device-name>/command/switch:0 using the lowercase strings on  and off.

As a result, retrieving the current state requires a combination of a JSONPath extraction and a transformation map. Likewise, commands must be converted to lowercase because OpenHAB sends ON/OFF commands in uppercase by default.

Below are examples of the Thing and Channel definitions:

The true-false-on-off.map  transformation file looks like this:

And here is an example of the corresponding OpenHAB items:

Finally, the heater control logic itself is implemented using the following OpenHAB rules:

I’m not putting the temperature control logic here as it is too long and contains some room detection logic that would not help for the purpose of this article. But basicaly, it checks the temperature every 2 minutes and change the value of Heater_RoomName_PilotCtrl

Window sensors

In addition to temperature-based control, I also use window sensors as part of the heating automation logic. While most modern heaters provide some form of “open window” detection, I have found these built-in mechanisms to be rather unreliable. They usually react too slowly or fail to detect certain situations altogether.

As with my old Oregon temperature sensors, my previous window sensors relied on a 433 MHz infrastructure. Since one of the goals of this project was to retire all of that aging hardware, I replaced them with inexpensive Wi-Fi sensors based on the CB3S module (BK7231N).

One of the advantages of these devices is that it can be reflashed with a custom firmware through a simple serial connection with BK731Flasher

The pinout is documented here. The four pins required for flashing are:

  • 15 = rx
  • 16 = tx
  • 8 = vcc
  • 9 = gnd
  • 3 = CEN

I simply soldered a few Dupont wires to the module, connected it to a USB-to-Serial adapter, and flashed the firmware using the appropriate flashing tool.

Once flashed, the sensors can be configured to publish their state directly over MQTT.

Below is the configuration I use on my devices:

OpenHAB Thing definition is shown below:

And finally, here is an example Item definition:

Using dedicated window sensors allows OpenHAB to immediately stop heating when a window is opened and restore the appropriate heating mode when it is closed again. This approach has proven to be significantly more reliable than relying on the heater’s built-in open-window detection logic.

Sitemap

With all sensors and heater controls integrated into OpenHAB, creating a user-friendly interface becomes straightforward.

Below is an example sitemap representing a single room. It provides quick access to the most relevant information and controls:

  • Current temperature and humidity
  • Heater operating mode
  • Target temperature profile
  • Window status
  • Heater power consumption
  • Sensor health and connectivity information

The resulting interface looks like this:

One of the advantages of this approach is that all heating-related information is available in a single view. It becomes easy to understand why a heater is currently running (or not), verify that sensors are reporting correctly, and quickly identify any issue with the automation logic.

While the interface itself remains deliberately simple, it provides all the information required to monitor and troubleshoot the heating system without having to dig into logs or OpenHAB internals.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.