Skip to main content

A software thermostat and heating control system

Project description

The BoilerIO Software Thermostat

BoilerIO can control heating in a zone of your home. Code is provided here to connect with Danfoss RF receivers though other implementations could easily be added, and to receive temperature updates over MQTT in a format described later in this README.

This has been tested with the Danfoss RF transciever code in the thermostat.git repository at

No warranty is provided: please be careful if you are messing with your own heating system.

For more information, please see


Check out the repository, then install using pip:

$ git clone
$ cd boilerio
$ pip install .

Use -e to pip to install in development mode (i.e. just link to the checked-out source instead of installing it).

The scheduler

The scheduler comes in four parts:

  1. The database. You need to be running postgres; once you have installed postgres you can create a database user and database for the scheduler, then user scheduler.sql to create the requisite tables. (This currently assumes the databsae and a role exists called scheduler.)
  2. The controller. This is the scheduler Python script. Ensure this daemon is running to push target temperature updates to the boiler controller (the maintaintemp script) and update the cache of the current temperature in the backend web app.
  3. The web app. This is the schedulerweb Flask app. The recommended configuration is for this to be proxied through nginx and run inside uwsgi.
  4. The web-based UI. This talks to the schedulerweb app and presents a UI where the current temperature and schedule can be configured.

You’ll need to the running the maintaintemp service also described below to issue commands to your boiler.

Example uWSGI configuration for schedulerweb (assuming you have the Python package installed) - this can be placed in /etc/uwsgi/apps-available on Ubuntu’s version of uwsgi:

socket = /var/www/boilerio/thermostat.sock
module = boilerio.schedulerweb:app
logto = /var/log/uwsgi/boilerio/thermostat.log
uid = boilerio
gid = www-data
chmod-socket = 664


The boiler_to_mqtt script implements an MQTT-topic based interface on top of the serial protocol provided in the thermostat.git repository. In short: it turns the boiler on and off via MQTT. The serial interface in thermostat.git is designed to interact with a Danfoss RF thermostat receiver; if you wanted to use a different receiver you can substitute a different service.

Ordinarily you’d leave this service running so that other services can turn the boiler on/off as needed.

This service and others in this repository use a common configuration file. See below for more information.


This is the main script and implements a PID controller to maintain a given set temperature.

Example usage:

$ maintaintemp emon_sensors/emonth5 0xBAB1

The first argument is an MQTT topic from which to get temperature updates. These updates should have a JSON payload with an object with at least a temperature value. The temperature updates can be at any frequency, but I’ve mostly tested with updates being sent every minute.

The second argument is the thermostat ID to use in messages to the boiler. For the Danfoss RF receiver I’ve been testing with, you will independently need to send a ‘learn’ command; this should be transmitted repeatedly (with the correct thermostat ID) while you hold the ‘PROG’ and ‘CH1/2’ button and wait until the light flashes green on the controller.

You can send learn packets in a loop with a simple shell loop, if you have the mosquitto clients installed and are running the script:

echo -n "Learning mode - program boiler then hit enter... "
while ! read -t 1 ; do
    mosquitto_pub -h <host> -u <username> -P <passwd> -t heating/zone/demand \
                  -m '{"command": "L", "thermostat": 47793}'

The heating/deamnd topic should match the configuration file you set up - see below for more information.

The scheduler, mentioend above, will issue commands to this script to set the target temperature. If you don’t want to use the scheduler, you can publish messages to the MQTT topic listed as the target_temp_topic in your configuration file. These should be of the form:

{target: 19.5}

For a broad description of the behaviour of this program, please see the blog entry on the website mentioned above.


This is a trivial simulator intended to help debug and improve maintaintemp. It follows a really simple heating/cooling model and generates a table as output.

To run, use a command-line such as:

$ boilersim -r 18 19.5 600

The -r option introduces some random noise into the temperature readings generated by the simulation when passing them to the controller.

The first positional argument is the starting indoor temperature to simulate. The second argument is the target temperature. The third argument is the simulated runtime in minutes.

This program produces logging output to stderr, and a space-separated output to stdout. The output is similar to:

1.0 0 0 17.9964773317 17.9876417779 0 0 0

The columns are:

  1. The time into the simulation, in minutes
  2. The amount of time in that minute that the boiler was on for in the simulation.
  3. The current duty cycle of the boiler in the simulation.
  4. The current simulated room temperature
  5. The fake temperature reading passed to the controller including any error introduced by the -r option.
  6. The current value of the proportional term of the PID controller.
  7. The current value of the integral term of the PID controller.
  8. The current value of the differential term of the PID controller.

You can use the plot\_sim.gpi gnuplot script to plot the output of the simulation. E.g.:

$ boilersim -r 18 19.5 600  2>log >sim_data
$ gnuplot plot_sim.gpi

The gnuplot script assumes the simulation output is saved to a file called sim\_data.

Config file

Other than boilersim, a config file is needed for the programs here. This is to help make them usable as daemons.

Here is a sample configuration file, to be placed in /etc/sensors/config:

host = mqtt.lan
user = user
password = imnottellingyou

# Various MQTT topic names to use.  These can be anything but are specified in
# the config in case you have other software that constrains your choices, and
# ensures they are consistent across apps.
info_basetopic = heating/zone/info
demand_request_topic = heating/zone/demand
temperature_sensor_topic = emon_sensors/emonth5
target_temp_topic = heating/thermostat/target_temp
thermostat_status_topic = heating/thermostat/status
thermostat_schedule_change_topic = heating/thermostat_control/update

scheduler_db_host = hub.lan
scheduler_db_name = scheduler
scheduler_db_user = scheduler
scheduler_db_password = imnottellingyou

scheduler_url = http://localhost/api

# Optional username and password.  If provided, they are used with HTTP basic
# auth to talk to the scheduler.
scheduler_username = username
scheduler_password = imnottellingyou

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for boilerio, version 0.0.2
Filename, size File type Python version Upload date Hashes
Filename, size boilerio-0.0.2.tar.gz (17.1 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page