Heat pump controller · intent, not registers
Thermaestro
Thermaestro plans a home's heating and hot water around electricity prices, the weather and the household's needs. The household says what it wants (warm rooms, hot water by seven, cost before comfort within limits), and Thermaestro works out how, tells each device only what it needs, and checks that it happened.
- One plan for every device in the house: heat pumps, cascades, air/air units, hot-water tanks, pool, sensors and meters.
- Goals in household terms, a ranking of what gives way, and plain reports when a goal can't be met.
- The house and the hot-water tank used as heat storage, within limits the household sets.
It is brand-neutral: devices come in through plugins, whatever the brand and however they are reached. Nibe is the first. Thermaestro is meant to replace NibePi, and is open source under the AGPL.
Operating principle
How it works
How to read this page: it describes the design. proposal not settled yet. later planned, not designed or built. Unmarked items are settled design. Where it stands says what is built today.
Thermaestro works from what the household wants, not from pump settings. The household states its goals and what may give way when not all of them can be met. A planner turns them into a schedule. Thermaestro changes the few settings the schedule needs, then checks what actually happens and learns from it. The household gets reports and can adjust its goals. The approach follows intent-based management as described in IRTF RFC 9315 and 9316.
Each device stays in charge of itself. Thermaestro supervises; it doesn't replace a device's own control. A heat pump keeps its own regulation, defrosting, compressor protection and the regular extra-hot heating of the hot-water tank against legionella. Thermaestro only adjusts the settings each device offers, such as a heating curve offset, the hot-water mode, pausing or forcing hot-water heating, or a temperature setpoint. Setting the flow temperature directly, on pumps that allow it, comes later. later
One controller per setting. If a device has its own feature that changes the same setting (a maker's price function, the pump's own schedule, or its room control while Thermaestro regulates the heating), that feature has to be turned off. Otherwise Thermaestro leaves the setting alone and says why.
Fail-safe
When Thermaestro shuts down, when a room sensor stops reporting, or when its watchdog trips, it puts back the settings it found. Missing price data alone doesn't do this: Thermaestro then stops moving heat to cheaper hours but keeps the rooms comfortable. Before changing a setting, Thermaestro takes it over, notes its current value, changes it and reads it back. If the pump accepts a value but doesn't keep it, Thermaestro reports that instead of trying again and again. If something else changes a setting Thermaestro is using, it reports the change and doesn't fight it. A watchdog in the gateway, which puts the settings back if Thermaestro itself goes silent, is planned. later
Functions
What it does
The planner looks one to two days ahead in 15-minute steps and plans again whenever something changes. It weighs the heat each climate system needs, hot water, prices, the weather, the heat stored in the house and the hot-water tank, and the heat pump's efficiency at each hour, then picks the actual settings for the next hours, counting every change of a setting as a small cost.
Intents
Standing intents apply all the time: a comfort range per climate system on a weekly schedule, hot water ready by set times, a lowest hot-water temperature, how much to favor cost over comfort, when the electric heater may help, the pool, a limit on peak power, quiet hours.
Temporary intents always have an end: warmer or cooler, please; a bath by 19:30; guests until Sunday; away until the 12th, ready when back; hands off for at most 48 hours; boost now. The newest one wins; when it ends, the one before it applies again. A "fireplace on" intent is proposed. proposal
Levels are the household's own: named settings such as "Comfort, 21–22 °C" or "Hot water, 50 °C". The weekly schedule uses levels, so changing one changes it everywhere. A new installation starts with levels taken from the devices' own settings.
When intents conflict, a fixed order decides: protection first, then the limits on changing settings, then "hands off", then temporary intents, then standing intents, and last the devices' own settings. proposal
A ranking decides what gives way, most important first: protective minimum temperatures, the lower edge of each comfort range, hot water marked must, then should, the upper edge of each comfort range, the power peak. One slider sets what is left: saving money against staying close to the target, shown as real limits ("may go 1.5 °C below your target") rather than a number from 1 to 10. proposal Where a goal falls short, the report says by how much: "the bath will be ready 40 minutes late".
Comfort and hot water
A comfort range per climate system, measured by room sensors from Home Assistant or MQTT. Thermaestro regulates the room temperature itself, through the setting each device offers for it, so the pump's own room control must be off. How air/air units in single rooms fit in is still to be designed. later
No room sensor? Then the pump heats on its own heating curve, adjusted ahead of weather changes, and Thermaestro may move heat by up to a set amount toward cheaper hours.
Hot water as °C at the top of the hot-water tank by a time. Liters or showers come once the hot-water tank model is calibrated. later Thermaestro pauses or forces hot-water heating in whatever way each pump allows. If a pump can't pause it, Thermaestro can only make it heat when power is cheap, and says so.
A learned demand profile. Thermaestro notices when hot water is used and learns a typical week. Patterns that repeat are suggested as standing intents, never applied without asking.
Cost, and the house as storage
Prices built from their parts: the spot price, the supplier's surcharges, energy tax, grid fees and VAT, the same arithmetic in every country, checked against the supplier's own total. Grid tariffs are stored as data. Prices are handled in 15-minute steps.
A reasonably insulated house is storage. Thermaestro learns each climate system's heat capacity and losses. Heating ahead is worth it only when the price difference pays for the extra heat lost, given the heat pump's efficiency at that hour.
Slow heating systems. Underfloor heating in a slab can take a day or more to respond. The planner looks far enough ahead, pre-heats in time, and says how long a request will take: "the floor heating will reach +1 °C in about 9 hours".
Seasons and the real world. Compressor starts, the ground cooling over the winter, defrosting, sun, open windows, quiet hours and holidays are all part of the plan. Goals marked must keep a safety margin in case the forecast is wrong. Cooling is still to be designed. later
Reports, wear and shadow mode
Plain reports. When an intent is entered, the plan answers at once: the shortfall in time or degrees, what gives way, or what isn't known yet ("the plan firms up when tomorrow's prices are published"), with a choice where there is one. proposal While running: what's in control now, and why, against the real prices; who set an override and until when; a daily summary, and savings only ever compared with a reference the household can check. proposal
Settings are changed sparingly. Some pumps store settings in memory that tolerates only a limited number of writes. Thermaestro counts every change as a cost, never rewrites a value that is already right, and has a hard daily limit per setting.
Shadow mode. Thermaestro plans as usual but changes nothing, and shows what it would do. Coming from NibePi, run it alongside to evaluate it and let it learn your house before you switch.
One installation, many devices
Devices and plugins
Several devices, one plan. An installation is a tree of devices, each handled by a plugin. One planner covers every heat source, climate system, hot-water tank and pool in the house: a cascade of heat pumps, a heat pump with air/air units in some rooms, several climate systems with their own room sensors. A plugin declares shared limits, such as one compressor serving either heating or hot water at a time. Other heat sources (a boiler or district-heating addition, a wood stove as a known source) can join the same plan where a plugin can reach them. later
Many brands, many connections. A plugin reaches its devices whichever way they allow: a bus gateway, Modbus TCP, a local REST gateway, a cloud API, infrared, relay contacts such as SG Ready, or MQTT. Planning never deals with registers or protocols, only with what each device can report and which settings it offers, and how well each of these is known.
Nibe first. The first plugin is for Nibe pumps: F-series and related models through a small gateway on the pump's accessory bus, and S-series over their built-in Modbus TCP. Other brands, air/air units and other heat sources follow as plugins. later
Gateways for Nibe's bus. Thermaestro's fork of esphome-nibe runs on an ESP32 with RS485, and thermaestro-gateway on Linux with an RS485 adapter. Both speak plain NibeGW and the Thermaestro gateway protocol, which adds a report of what happened to every request, timing from the bus, health statistics and optional authentication. Plain NibeGW gateways work too, with less information.
Home Assistant and MQTT
To Home Assistant, Thermaestro is a device like any other: it publishes its state over MQTT and appears through MQTT discovery. It takes room sensors and other values from Home Assistant or MQTT. Thermaestro is not a Home Assistant add-on.
Users and security
Everyone logs in, on the home network too. Users and groups get rights per kind of action, so a household member can ask for more warmth without being able to change minimum temperatures. Plain HTTP and HTTPS with a self-signed certificate by default. Secrets live in their own file and are never shown back. The project runs no cloud service of its own.
Coming from NibePi
Upload NibePi's config.json: the gateway, the MQTT broker, sensors, location, prices and secrets come over, and its control settings become draft intents to confirm. Before switching, run Thermaestro in shadow mode beside NibePi. not built yet
Installation
Running it
Today: a Docker Compose file builds Thermaestro from its source on GitHub. See running it in Docker.
At release: Docker images for amd64 and arm64, and .deb packages for Raspberry Pi OS, 32-bit and 64-bit, from the project's own apt repository. thermaestro-gateway is its own small package, so it can run alone on a Pi next to the pump with the core elsewhere.
Setup adds each device through its plugin, detects its model, firmware, climate systems, hot-water tanks and pool, asks what heats each climate system, and takes room and outdoor sensors, the location and the price source, suggested from the bidding zone. Starting levels come from the pump, so on day one it behaves like the pump on its own.
Technical data
In short
| Core | Python 3.13 |
|---|---|
| License | AGPL-3.0-or-later (test vectors also MIT) |
| Web interface | Server-rendered; every action has an API counterpart; a command line |
| Languages | English, Swedish, German |
| Plugin interface | JSON lines with a JSON Schema, in the core or over a Unix socket |
| Time step | 15 minutes |
|---|---|
| Horizon | 24–48 hours, as far as the slowest climate system needs proposal |
| Method | Linear programming (HiGHS), goals solved in order of rank |
| How goals are treated | They can give way, with any shortfall stated in minutes or degrees; only physics, device limits and protections are absolute proposal |
| Setting changes | About 50 per device and day planned; a hard stop at 200 per setting and day; both configurable |
| Prices, no account | Energy-Charts, Beneficial Apps' Nordic price sites, OMIE (Spain, Portugal) |
|---|---|
| Prices, own token | Tibber, ENTSO-E (every European zone) |
| Great Britain | Octopus Agile |
| Weather | MET Norway, SMHI, Open-Meteo, each scored against the house's own outdoor sensor; Home Assistant as a fallback |
| Docker | A Compose file that builds from source today; amd64 and arm64 images at release |
|---|---|
| Raspberry Pi OS | 32-bit and 64-bit packages at release |
| Heat pumps | Nibe F-series and related models; Nibe S-series over Modbus TCP; other brands by plugin later |
| Other heat sources | In the same plan where a plugin reaches them later |
| Sensors and meters | Home Assistant and MQTT, indoors and outdoors |
| Smallest host for everything | To be measured later |
Where it stands
Planning built, control next
Thermaestro reads, and changes nothing on a pump yet. It runs in Docker on its first test pump, a Nibe F1245, read-only beside NibePi. The planner is built and tested against a simulated house; the household switching its settings to shadow and then control comes next.
Built
- The core: plugins, every value with its quality and history, an audit log, the command line.
- The Nibe plugin: both gateway protocols; F-series read on a real F1245; S-series from Nibe's documentation, not yet tried on a real pump.
- Room and outdoor sensors from Home Assistant and MQTT, each with its reporting rhythm learned.
- Prices and weather from the sources above, the price built from its parts.
- Home Assistant discovery over MQTT.
- The web interface: logins, users, groups and rights, setup, charts, an API for every action.
- A read-only probe that reports what Thermaestro reads from a pump, for testers.
- Intents: the household's goals and requests kept, checked and ranked; the first ones taken from how the pump runs.
- A rule-based planner: every 15 minutes, what each setting should be and why.
- Safe changes: settings taken over, checked, read back, limited and put back; shadow mode deciding the same and changing nothing.
- A simulated house, hot-water tank and pump the planner is tested against over simulated days.
Being built
- Control in the web UI and over MQTT: each setting off, in shadow or in control; intents entered; the plan and its reasons shown.
- Shadow beside NibePi on the first test pump, then control.
- Grid tariffs as data, and importing NibePi's settings.
Later
- Learning: the house and hot-water tank models and the optimizer.
- Release images, Raspberry Pi OS packages and a beta channel.
- Testers on other pump models, once it runs reliably on the first.
- Other brands and heat sources, by plugin.
Code and documentation
Links
- github.com/fnordpojk/thermaestro
The core, the plugins, and thermaestro-gateway ingateway/ - github.com/fnordpojk/esphome-nibe
Thermaestro's fork of esphome-nibe, for an ESP32 on the pump's bus