[APP][Pro] Adaptive Thermostat - proportional heating from any sensor and any heater

Adaptive Thermostat — any sensor. any heater. real regulation.

Turn any temperature sensor and any heater into a thermostat that actually regulates.


A radiator valve measures the radiator, not the room — it reads warm and closes too early. A simple thermostat switches fully on and fully off, so the room swings around the setpoint instead of settling on it.

This app puts a real proportional regulator between a sensor that measures the temperature you care about, and a heater that has no idea where it is.

Pick the sensor in the room. Pick what heats that room. :white_check_mark: That is the whole setup.


Available in the App Store


What it does

  • :thermometer: Proportional regulation, not on/off — it works out how much heat the room needs, and corrects what it sends to your heater, continuously
  • :electric_plug: Three kinds of heater — anything with a target temperature, a radiator valve driven by its opening, or a plain switch, where the power becomes time: 30% of a ten-minute cycle is 3 minutes on and 7 off
  • :sunny: Presets — frost protection, eco, comfort, boost, manual. Each with its own temperature, and its own away temperature
  • :snowflake: Open window detection — from a contact sensor, or from a sudden drop in temperature, with a delay so a ten-second airing does not count
  • :footprints: Presence and motion — nobody home, and every preset falls back to its away temperature. In a single room, motion can switch between two presets on its own
  • :fire: Central boiler control — it counts how many rooms are calling for heat and starts your boiler when enough of them are. Never switched twice within a minute, and never delayed on the way off: a boiler running against closed valves builds pressure
  • :battery: Dead sensor safety — a Flow card fires when the room sensor goes quiet, and a safety mode keeps a minimum going until it comes back. That is the warning you want when a battery dies in January

Requirements

  • :house: Homey Pro — the app reads and controls the devices you point it at, which needs an API permission Homey Cloud does not offer
  • :thermometer: A temperature sensor and a heater — from any app. Zigbee, Z-Wave, Wi-Fi, it does not matter

Optional, and each one the app has makes it better: a contact sensor, a motion sensor, a presence sensor, an outdoor temperature sensor, and a switch that starts your boiler. None of them is required.


Going further with Zigbee2MQTT

If your valves are exposed through Zigbee2MQTT, give the app access to the same broker in its settings. It then:

  • drives valve opening directly, instead of only sending a setpoint
  • pushes the real room temperature into the valve, so it stops regulating on its own thermometer

There is a test button that tells you exactly what is wrong when the connection fails. Without this, the app still works in full — it simply sends setpoints.


What is not in this version

  • :x: No load shedding by power, and no predictive auto start/stop. Both exist in Versatile Thermostat; neither matched hardware I could test against, and I am not shipping heating logic I have not run
  • :x: No cooling mode
  • :x: Valves exposed only as a number, without a climate entity

Languages

  • :uk: English
  • :fr: French
  • :netherlands: Dutch

Credits :pray:

This app owes its existence to Versatile Thermostat, the Home Assistant integration by Jean-Marc Collin.

The regulation algorithms are ported from it, under its MIT licence: the TPI proportional algorithm, the PI self-regulation modes and their coefficients, the slope-based window detection, and the central boiler aggregation. Reading that code is what made a faithful port possible at all — thank you for writing it, and for publishing it openly.

This is an independent implementation for Homey. It does not connect to, and does not require, Home Assistant. Any bug here is mine, not Versatile Thermostat’s.


Feedback welcome :speech_balloon:

Running on my own Homey Pro against five Sonoff TRVZB valves, SNZB-02 sensors, a gas boiler relay and an electric radiator on a smart plug. The full chain — sensor, regulation, valve, aggregated demand, boiler relay — has been verified end to end on that installation, including the return to idle.

:warning: What it has not seen yet is a real heating day: it went into service in August. The default coefficients suit a normally insulated room. If yours oscillates around the setpoint, or never reaches it, say so here — the settings explain which coefficient to move and in which direction.

The app also has a diagnostics endpoint that reports exactly what it sees, which usually settles a problem in one round trip.


:arrow_right: How it works, and how to set it up

How it works, and how to set it up

The first post says what the app does. This one says how, and how to live with it.


:one: How much heat does this room need?

Every few seconds the app asks each thermostat that single question. The answer is one number, between 0 and 100%. It comes from two terms:

  • the gap between the room and your setpoint, times the indoor coefficient
  • the gap between your setpoint and outdoors, times the outdoor coefficient — this one anticipates how fast the room loses heat, and it only exists if you gave the app an outdoor sensor

:two: Where that number goes

  • :gear: A valve driven by its opening — the number is the opening
  • :hourglass: A plain switch — the number becomes time: 30% of a ten-minute cycle is 3 minutes on and 7 off
  • :thermometer: A heater you give a temperature to — the one case that number does not drive

That last case runs a second regulator: a PI loop that watches the error accumulate over time and adds an offset to your setpoint. The app then asks for more than you did while the room is behind, which is what stops the heater’s own valve from closing early.

:bulb: It needs an outdoor sensor, and it comes in five strengths from slow to strong, plus off, in the advanced settings.


:three: And then the boiler

The app does not ask the calculation whether a room wants heat. It looks at what the emitter is actually doing — the valve’s real opening, the relay’s real state, or what the heater reports about itself.

That is added up across every room, and your boiler relay follows.


:vertical_traffic_light: What overrides what

When several things could decide the temperature, the first one that applies wins:

  1. Off — the device is switched off. Frost protection setpoint, valve closed, switch cut
  2. Central mode — everything off, heating only, or frost protection, for the whole home
  3. Open window — detected and confirmed
  4. Safety — the room sensor has gone quiet
  5. Away — nobody home, presets use their away temperature
  6. Activity — motion decides between two presets
  7. The preset you chose

:bulb: The Status field on the tile shows which one is currently in charge. Your selected preset never changes on its own — only what the thermostat aims for.


:wrench: Setting it up

One thermostat per room:

  1. Add device :arrow_right: Adaptive Thermostat :arrow_right: Thermostat
  2. Pick the room sensor — the thermometer that reads the temperature you care about. :warning: Not the one inside the radiator valve: that one reads the radiator
  3. Pick what heats that room
  4. Optional sources — outdoor temperature, window contact, motion, presence. Every one of them can stay empty

Then, once for the whole home, the Boiler device. That is where you point at the switch that starts your boiler. It also carries the central mode — everything off, heating only, or frost protection — which applies to every thermostat.

If you heat only with electric radiators and never want that home-wide switch, you can skip it.


:calendar: Day to day

Presets are the intended way to drive it — set the preset, not the temperature.

From a Flow you can set a preset, set one for a duration (Boost for 45 minutes, then it returns on its own — and that survives an app restart), set a temperature, force presence, or tell a room to ignore its window sensor for a while.

:arrows_counterclockwise: To change which devices a thermostat uses, once it exists: Homey :arrow_right: Settings :arrow_right: Apps :arrow_right: Adaptive Thermostat :arrow_right: Thermostats tab. Every source is changeable there and takes effect immediately.

A device that no longer exists is flagged in red — which is what happens when a Zigbee device is re-paired and comes back with a new identity.


:level_slider: Tuning, if you need it

The defaults suit a normally insulated room. Change one thing at a time, and give it a day.

Symptom What to do
Never reaches the setpoint at steady state Raise the outdoor coefficient
Overshoots at steady state Lower the outdoor coefficient
Warms up too slowly Raise the indoor coefficient
Oscillates around the setpoint Lower the indoor coefficient

:warning: Those two coefficients drive the power number, so they are the right lever on a valve or a switch. On a heater you give a temperature to, the power number is only a display — there the lever is the self-regulation strength. Start at slow, and move up a step only if the room keeps sitting below its target.

The recalculation period matters too: five minutes suits a radiator, fifteen to thirty a floor heating loop or a slow boiler circuit.

:bulb: Every group of device settings carries its own explanation, right in the page.


:satellite: The Zigbee2MQTT backend

Optional, and only useful if your valves come from Zigbee2MQTT. Second tab of the app settings: broker address, port, credentials, base topic.

The test button distinguishes four cases — connection refused, bad credentials, connected but wrong base topic, or connected and seeing N devices.

It unlocks two things:

  • valve opening driven directly, rather than only a setpoint
  • the real room temperature pushed into the valve, so it stops regulating on its own thermometer — the single biggest improvement for a TRV

:sos: When something is wrong

  • :cold_face: A room is cold and the tile says heating — open the device settings, Linked devices. If a source says the device no longer exists, re-point it from the app settings
  • :battery: A sensor warning appears — the battery is probably dead. The app keeps a minimum going for 24 hours, then gives up rather than run your boiler for days on a dead reading. Replace the battery and it resumes on its own
  • :fire: The boiler will not start — the Boiler device shows how many emitters are calling for heat. If that is zero while a room is cold, the room is not asking: look at that room’s power percentage
  • :mag: Anything else — the app has a diagnostics endpoint that reports exactly what it sees. Ask here and I will explain how to read it; it usually settles a question in one round trip

:arrow_left: Back to the app description

Please provide the source code of your app, it being both AI-generated and requiring full access to one’s Homey.

Hi,

Yes sure, off course, link to the code source here.

▎ The app builds a thermostat out of devices the user already owns: any temperature sensor as the input, any heater as the output — a radiator valve, a plain relay, a heat pump. Which devices those are is not knowable at build time; the user picks them during pairing and can re-point them later from the app settings. Those devices belong to other apps, and SDK v3 gives an app direct access only to its own devices. Reading a capability from another app’s device and writing to another is exactly what homey:manager:api provides, and the SDK offers no narrower scope — there is no per-device or per-capability permission.

▎ In practice the app reads only measure_temperature, alarm_contact, alarm_motion, alarm_presence and onoff, and writes only to the emitter and the boiler relay the user designated. Nothing leaves the Homey: the only outbound connection is the optional Zigbee2MQTT broker, which the user configures themselves and which is on their own network.

Tried to setup a termostat. On the last page where you can select an outdoor thermometer there is no „okay“ button just a „back“ or the cancel „X“. So no way to create a termostat. Am using an iPad.
Can you implement a search function when selecting the devices? On device name and zone? Then it’s easier to select the correct devices.
Boiler setup works..

Hi,

Please slide down the lastpage, you may have a other options to be configure and at end of page you find a button to create thermostat :wink:

Maybe need to have a dedicated page for all options

Worked. Didn‘t notice that I can / have to scroll. The first two times there was a page switch so I expected another one on page 3 too.

Now live in the App Store :tada:

Adaptive Thermostat has passed Athom’s review. It is out of test and available to everyone:

If you were running the test version, Homey updates you on its own — nothing to redo. Your thermostats, the devices you pointed them at and your Flows all stay exactly as they are.

What changed in 1.0.5

Reliability, mostly. A few ways the app could quietly stop heating a room are gone — the important one being that it now recovers by itself when it cannot reach Homey as it starts, which is what happens after a power cut.

@SingKT thanks for the report — glad it was only a scroll. That last pairing page does too much and it will get split up; a search box when picking devices is on the list too.

Heating season is nearly here and this app has not seen one yet. If a room swings around its setpoint, or never quite reaches it, say so here — that is exactly the feedback I need, and the second post has a small table saying which coefficient to move and in which direction.

Well actually now only the timetable for each device is missing. Or how to handle the night? I do not have presence detectors in each room. Beside that it’s a bit late to start heating when one enters a room.

Two separate questions there.

The timetable is Homey itself. There’s deliberately none in the app: When the time is 22:30 -> Set the preset to Eco already is a timetable, weekdays and sunset included. The cards are there - Set the preset, Set the preset for a while (the previous one comes back on its own), and Set the central mode for the whole house at once.

The night is a clock problem, not a presence one - it happens at the same time every day, so no detector is involved. Eco on the living rooms at 22:30, Comfort on the bedrooms, swapped back at 06:30. (Central mode “Frost protection” is for holidays, not for nights.)

“It’s a bit late to start heating when one enters a room” - you’re right, and that’s exactly why the Activity preset takes two presets rather than being an on/off. Under Presence and motion there is Preset when motion and Preset when still - the floor it falls back to. It defaults to Eco and should stay there; the mistake is setting it to Frost protection. From Eco the gap is 2-3 °C and the proportional algorithm closes it in minutes. From 7 °C, nothing can. Motion doesn’t start the heating, it finishes the climb.

To anticipate without a sensor in every room, trigger on something further upstream - front door, phone geofence, alarm disarmed - and Set the preset to Comfort for 2 hours.

And you did find a real gap: there was a condition for the preset but no trigger, so nothing could react to one changing. “The preset changes” and “The central mode changes” are in for the next build. Thanks for pushing on it.