rWCHCd implements a versatile weather-compensated central heating controller. The goal is to provide smart, accurate and optimal temperature control based on outdoor temperature variations, building structure and occupant habits, in order to maximize comfort and reduce power usage (minimize both the impact on the environment and the energy bill). The system is designed to be scalable and remote operable (via internet connection).

rWCHCd was initially born as the the software part of the rWCHC project, but has eventually grown to become a standalone system now described on its own on this web page.

As is, this software is typically meant to run on a Raspberry Pi host accompanying the rWCHC hardware module to perform all computations and enhanced logic control, but it can operate on any system that supports basic C-library programming interface. Hardware control is implemented as modular drivers and as such this daemon is no longer strictly tied to the rWCHC hardware module. As this piece of software has eventually grown to c.15,000 lines of (well documented) code and has become a standalone creation, it is now described separately here.

This project stemmed from my need for a reliable and highly configurable controller after having had a bad experience with a brand-name device.

I have been operating this software for several years, in two separate locations:

  • One has a basic setup with a 25kW boiler with integrated DHWT and a single heating circuit, plus one additional electric DHWT;
  • The other has a slightly more complex setup featuring a 100kW boiler, 2 heating circuits (one with no indoor sensor, one with two), 2 DHWTs (one with with dual power input via integrated electric heating element), and a DHW recycling circuit.

It works well :)



Design goals

My design goals are simple. The system should be:

  • Safe
  • Reliable
  • Versatile
  • Affordable
  • KISS design

This is reflected in the list of software features.

The system is geared toward a “set and forget” approach, only requiring some attention at initial setup time.


The rWCHCd daemon – written in C and documented inline via doxygen – is the “brain” of the heating controller system. The CPU and memory footprint of the daemon are kept to the bare minimum, the code is written with efficiency in mind. By design, computations are performed in O(1) on discrete values (no use of arrays) in 32-bit integer arithmetics to reduce the load on the host, to improve scalability, and to facilitate implementation on a scaled-down MCU if that ever becomes desirable. The build system is modular, so that unwanted bits can be opted out at build time to trim down binary size.

In fact, while developed to manage the rWCHC hardware module from a Raspberry Pi, this control daemon is designed to be both hardware and platform independent:

  • A hardware abstraction layer allows for easy implementation of new hardware modules as “plugins”
  • The software’s only mandatory dependency is the C library

Last but not least, safety is critical when operating HVAC equipment: the code is designed with safety at its core. Two aspects are considered foremost: preventing frost (of the building and of the system itself) and ensuring absolute safety in case of failure. The latter has precedence over the former when it is not possible to guarantee both.

All safety-critical code is written with safe fail-overs in case of error: if anything goes unpredicatbly wrong (sensors failing, actuators not responding), the code will always fall back to the safest possible state. Should a catastrophic software failure happen, the daemon will abort and restart.


Presently, the following features are implemented (non-exhaustive list):

  • Weather-compensated operation, with virtually unlimited number of building models:
    • Building temperature behavior modelling via inertia time constant
    • Per-model outdoor temperature source
    • Per-model evaluation of frost or summer conditions
  • Virtually unlimited number of heating circuits with any of the following features:
    • Water-based circuits with radiators are supported
    • Per-circuit, independent target ambient temperature
    • Per-circuit building model assignment
    • Direct heating circuits
    • Mixed heating circuits, with mixing valve:
      • Support for multiple types of mixing valve control algorithms: bang-bang, successive approximations, PI controller
      • Support for temperature deadzone in all algorithms
      • Support for actuator deadband in all algorithms
      • Support for water temperature rate of rise control
    • Support for multiple types of heating curves (linear and bilinear approximations are implemented)
    • Support for ambient temperature modelisation in the absence of an ambient sensor
    • Support for accelerated cooldown and boost warmup transitions
    • Support for optional circuit ambient temperature sensor
    • Support for optional circuit water return temperature sensor
    • Support for automatic circuit turn-off based on indoor/outdoor temperature evolution
    • Support for timed cooldown at turn-off
    • Support for min/max limits on circuit water temperature
  • Virtually unlimited number of DHWT (Domestic Hot Water Tanks) with any of the following features:
    • Support for standalone as well as boiler-integrated tanks
    • Support for automatic switch-over to (optional) integrated electric heating, with or without thermostat
    • Support for single and dual sensor operation (top/bottom) with adaptive hysteresis strategies
    • Support for timed feedpump cooldown at untrip with temperature discharge protection
    • Support for 5 charge priority models (no priority, parallel or absolute; with heat request selection)
    • Support for forced manual charge
    • Support for 3 comfort mode charges forcing models (never force charge, force first charge of the day, force all comfort charges)
    • Support for charge duration cap
    • Support for DHW circulator pump
    • Support for min/max limits on DHW temperature
    • Support for maximum intake temperature limit
    • Support for anti-legionella high heat charge
    • Support for isolation valve
    • Support for DHWT cascade, with priority
  • Type-agnostic heat source support (currently only boiler type implemented) with any of the following features:
    • Support for overtemp signaling (to trigger maximum dissipation via connected consumers)
    • Support for consumer shift (e.g. to accelerate warmup after a cold start or to evacuate excess heat)
    • Support for consumer reduction delay signal (signal consumers to delay heat request reduction)
    • Boiler type heat source implements:
      • Automatic frost protection in all operation modes
      • Support for single-stage burner with minimum continuous on/off time to reduce wear
      • Support for adaptative trip/untrip hysteresis with low and high temperature limits
      • Support for burner turn-on anticipation (accounts for boiler temperature inertia)
      • Support for automatic boiler “sleeping” turn-off based on last heat request time
      • Support for several automatic turn-off strategies
      • Support for boiler minimum and maximum temperature (with signalling to consumers)
      • Support for return water minimum temperature (with or without return mixing valve)
      • Support for consummer delay after burner run (to prevent overheating)
      • Support for alarm if the burner fails, regardless of burner reporting capabilities
  • Support for virtually unlimited number of weekly schedules:
    • Each plant entity can be assigned an independent schedule for setting its run mode (comfort, eco, etc), and other parameters.
    • Schedules can be shared between multiple plant entities
  • Support for automatic summer switch-over based on outdoor temperature evolution, with summer maintenance of pumps and valves
  • Support for pump cool down timeout
  • Support for shared pumps (e.g. one feed pump common to several DHWTs)
  • Support for multiple types of valve motorisation (currently 3-way and 2-way wiring)
  • Support for several global operation modes (full off, comfort, eco, frost-free, test, scheduler, manual…)
  • Virtually unlimited number of hardware controllers (implemented as build-time plugins):
    • Hardware-agnostic input/output interface with logging support (adding support for new hardware is a simple matter of adding a driver for it)
    • Dummy hardware driver (for testing purposes)
    • MQTT-backend driver, implemented using Mosquitto supports:
      • Publishing relay states
      • Subscribing to temperature values and switch states
    • Driver for current prototype hardware supports:
      • Communication over SPI bus
      • Multiple RTD temperature sensors variants (currently Pt1000 and Ni1000 with various temperature coefficients)
      • Support for per-sensor fixed temperature offset
      • Time accounting of all triac/relay operations (i.e. “on/off since, total on/off time, number of cycles”, etc)
      • Basic user-hardware interaction:
        • Global operation mode change via tactile switch
        • Display of individual sensor temperature
  • Abstracted I/O system, which allows:
    • Grouping multiple hardware relays, for automatic failover and/or single command multiple outputs control
    • Grouping multiple temperature sources, for failover and/or min/max operations (e.g. indoor temp can be set to the minimum of several input sources)
  • Support for optional data logging via any of the following backends:
    • simple CSV files
    • rrdtool databases
    • StatsD over UDP, which makes it possible to log data to a whole range of backends and viewers such as Netdata or Graphite.
    • MQTT, implemented using Mosquitto, which publishes log data to an MQTT broker.
  • Support for a simple watchdog that will kick in on software lockup
  • Support for alarms collection and reporting
  • Support for optional ISC-style declarative configuration file format
  • Support for optional Berkeley DB-based persistent state storage
  • Support for optional D-Bus interface for full remote control via a proof of concept web application

Provisions in the software have been made to support the following additional features:

  • Support for other types of valve motorisation (0-10V, 4-20mA)
  • Circuits:
    • Support for transition timing optimisation (anticipated cooldown, boost warmup timing…)
  • Heat sources:
    • Support for virtually unlimited number of heat sources, with cascading and/or switch-over
    • Support for other types of heat sources (e.g. heat pumps or heat exchangers for district heating…)
    • Support for boilers with 2-stage burners
  • Support for smart scheduling

Also considered:

  • Support for air-based circuits
  • Support for cooling systems
  • Support for presence indicators to learn the occupants habits
  • Support for HomeKit integration


The daemon source code is available from the follwing git repository.

The daemon code documentation is available here.

Proof-of-concept web application

A basic, proof-of-concept yet configurable web interface has been developed in Python (relying on framework and Bootstrap) and is part of the daemon source.

It allows for setting various parameters and remote controlling the heating system (turning it off/on, setting heating mode, etc). When using the rrdtool logging backend, a small CGI script is available to display historical graphs of various datapoints.

Here’s a screenshot of the main control view, as seen on mobile (in French):

Fancy dashboard with Grafana

Using the StatsD log output with a time-series database and Grafana, it is possible to create very nice dashboards to show a lot of information about the system.

Here’s a quick example, click to expand:

grafana preview