Controlling Home Assistant Heating by Presence: Heating and Ventilating with the Presence Sensor

Controlling Home Assistant Heating by Presence: Heating and Ventilating with the Presence Sensor

The heating season is under way, and most radiator thermostats work to a schedule. The schedule does not know, however, whether the living room is really in use on Tuesday evening or whether everyone is sitting in the kitchen. With a presence sensor, Home Assistant lowers the temperature when the room has been empty for a while and heats up again as soon as someone stays. If the humidity rises, Home Assistant tells you to air the room, turns the heating off for the airing time and then reminds you to close the windows. In the bathroom, the same reading switches the fan.

The Senvolon presence sensors KL, KL LD and KL MZ do not only detect whether someone is in the room. In the same device they also measure temperature, humidity and air pressure, right where the sensor is mounted, in the room rather than directly at the radiator. Our previous guides covered lighting by presence and brightness and the siren as an alarm system. This time it is about the indoor climate. A single sensor gives Home Assistant everything that heating by presence needs: whether someone is in the room, how warm it is there and how humid the air is.

Tested with Home Assistant 2026.10.2, the KL MZ presence sensor and two thermostats · as of 23 October 2026

Requirements

  • A presence sensor with a room climate sensor: KL, KL LD or KL MZ, connected to Home Assistant via MQTT. Setup is shown in Integrating a presence sensor into Home Assistant. The Basis model does not measure room climate, but it can be upgraded with the climate multisensor.
  • A radiator thermostat that Home Assistant can control. It appears there as a climate.… entity, whether it is connected via Zigbee, Matter, Wi-Fi or the manufacturer's integration. In this guide it is called climate.wohnzimmer.
  • Home Assistant version 2024.10 or later.
  • For step 5: a switchable bathroom fan (Badlüfter), for example via a flush-mounted switch actuator (switch.badluefter).
  • For the notifications: the Home Assistant Companion app on your smartphone (notify.mobile_app_ihr_smartphone).

Note: The examples use the entity IDs that MQTT discovery creates for the KL MZ (multi_zone_presence_sensor_…). On the KL and KL LD, and after a rename, they are named differently. You can find your actual IDs under Developer tools → States.

What the presence sensor knows better than the thermostat

A schedule defines when each room should be warm, and daily life rarely sticks to it. The study heats from 8 a.m., although today you are working at the kitchen table. And in the living room the heating runs from 5 p.m. while everyone is still sitting in the kitchen. Home Assistant often already knows via your smartphone whether someone is at home. It does not know which room is in use at the moment, and for that it needs a sensor in the room. A motion detector would be the obvious choice. But it only reacts to movement: anyone reading quietly on the sofa is gone for it after a few minutes, and the heating is lowered in the middle of the evening. The radar in the presence sensor also detects people who sit still or sleep. On the KL MZ, stay zones additionally hold the presence at the sofa or the desk.

Then there is the temperature. The thermostat measures right next to the radiator. Its 22 °C is not the 22 °C on the sofa, and a fixed correction value only half helps: when the heating is running the difference is large, when it is off it shrinks. The presence sensor measures where you sit, and from step 3 the thermostat regulates by this value. The same applies to humidity. Relative humidity depends on the air temperature, so right at a warm radiator it reads lower than in the middle of the room. In our living room, two radiator thermostats, the wall thermostat and the presence sensor reported 58, 65, 61 and 66 % at the same time. The ventilation notifications therefore follow the value from the sensor.

Which values do we use?

There is no single correct room temperature. Some people are cold at 20 °C, others sleep best with the window open. You decide which values suit you, which is why in this guide they are stored in helpers that you can change at any time. For simplicity, the examples follow the German Environment Agency (UBA). It recommends a maximum of 20 °C in living areas (in German), 18 °C in the kitchen and 17 °C in the bedroom. If you are out for a few hours, lower it to about 18 °C. For bedrooms the UBA gives 16 °C as the lower limit, and rooms that are rarely used should also stay slightly heated: if a room cools down, the relative humidity rises, and mould can grow on cold walls.

According to the German Environment Agency, the optimum humidity in a home is 40 to 60 per cent relative humidity. If it stays well above that for days, mould can form on cool walls. If you want to avoid mould and improve the room climate, ventilate by measured value rather than by feel. In winter, correct ventilation means: two to three times a day, open the windows wide for about five minutes and turn the heating off for that time. After showering or cooking, the UBA advises ventilating for five to ten minutes straight afterwards. A window left permanently tilted cools the wall next to it, wastes heating energy and brings in little fresh air.

Step 1: Create helpers

The temperatures do not belong in the automation itself but in helpers. That way you can change them later on the dashboard without touching YAML. Under Settings → Devices & services → Helpers → Create helper → Number, create two helpers:

  • Komforttemperatur (comfort temperature): minimum 16, maximum 24, step size 0.5, unit °C, starting value 20. Home Assistant creates input_number.komforttemperatur from it.
  • Absenktemperatur (setback temperature): same limits, starting value 18. This becomes input_number.absenktemperatur.

In addition, create a helper of type Toggle named Heizen nach Anwesenheit (heating by presence; input_boolean.heizen_nach_anwesenheit). With it you switch off the whole control, for example in summer or when guests are sleeping in the room.

A second toggle named Wohnzimmer belegt (living room occupied; input_boolean.wohnzimmer_belegt) remembers whether step 2 last rated the room as occupied or as empty. Step 3 reads it. You do not switch it yourself, so it does not need to be on the dashboard either.

Step 2: Lower the heating by presence

The automation has two triggers. If the room is empty for 30 minutes, it sets the thermostat to the setback temperature. If the presence sensor detects someone for five minutes in a row, it sets it back to the comfort temperature. Both times it also sets the helper Wohnzimmer belegt.

Why 30 minutes? If you only pop into the kitchen briefly, you should not come back to a cooling room. A radiator takes a while to get warm again, and frequent back and forth achieves nothing. On the device itself, the “Room timeout” can only be set up to 120 seconds. Home Assistant therefore takes over the longer wait.

The quickest way is the blueprint “Heizen nach Anwesenheit” (heating by presence). A blueprint is an automation with placeholders. When you create it, Home Assistant asks in a form for the presence sensor, the thermostat and the helpers from step 1, and you also set the waiting times of 5 and 30 minutes there. You do not have to change any entity ID in the YAML. After the import, go to Settings → Automations & scenes → Blueprints and click the blueprint to create the automation, one more for every further room. All blueprints for this guide are openly available on GitHub. Their names and descriptions are in German.

Import blueprint “Heizen nach Anwesenheit” into Home Assistant

Without a blueprint, or if you want to adapt the automation, go to Settings → Automations & scenes → Create automation → Create new automation, open the menu ⋮ → Edit in YAML at the top right and paste in:

Note: The automations use the note: field for comments on the individual steps. If your Home Assistant version does not know the field, delete the note: lines. Nothing changes in how it works.

alias: "Heating: living room by presence"
description: >
  Lowers the temperature when the living room has been empty for 30 minutes,
  and heats up again when someone has been in the room for five minutes.
mode: restart
triggers:
  - trigger: state
    entity_id: binary_sensor.multi_zone_presence_sensor_presence
    to: "off"
    for:
      minutes: 30
    id: leer
    note: "Adjust the waiting time as needed. Use your own entity ID."
  - trigger: state
    entity_id: binary_sensor.multi_zone_presence_sensor_presence
    to: "on"
    for:
      minutes: 5
    id: belegt
    note: "Someone just passing through, or a device that triggers briefly, does not heat up the room."
conditions:
  - condition: state
    entity_id: input_boolean.heizen_nach_anwesenheit
    state: "on"
    note: "Main switch from step 1."
actions:
  - choose:
      - conditions:
          - condition: trigger
            id: leer
        sequence:
          - action: input_boolean.turn_off
            target:
              entity_id: input_boolean.wohnzimmer_belegt
          - action: climate.set_temperature
            target:
              entity_id: climate.wohnzimmer
            data:
              temperature: "{{ states('input_number.absenktemperatur') | float }}"
      - conditions:
          - condition: trigger
            id: belegt
        sequence:
          - action: input_boolean.turn_on
            target:
              entity_id: input_boolean.wohnzimmer_belegt
          - action: climate.set_temperature
            target:
              entity_id: climate.wohnzimmer
            data:
              temperature: "{{ states('input_number.komforttemperatur') | float }}"

The setback of 2 °C is deliberately small. In half an hour the room only cools down slowly anyway, and when you come back it is warm again after a short time. If you lower it further, you save more while the room is empty but wait longer for the warmth.

Short detections do not heat up the room. If someone just walks through the room or a device moves for a few seconds, the thermostat stays at the setback temperature thanks to the five minutes on the “belegt” (occupied) trigger. The half hour until the setback nevertheless starts again from the beginning with every detection. In our test, a 3D printer running in the same room kept triggering the sensor, so the room was never lowered. On the KL MZ you can mask out such sources with an interference zone. If you want warmth faster when you enter, shorten the five minutes. A radiator needs a few minutes to get warm anyway.

If the thermostat runs its own schedule, it can overwrite the setpoint again at the next switching point. In that case, switch off the schedule in the thermostat or its app and leave the control to Home Assistant. Our thermostats ran without a schedule in the test, so this case was not part of the test.

For further rooms, duplicate the automation, swap the presence sensor and thermostat, and create a separate helper for each room, such as Schlafzimmer belegt (bedroom occupied). In the bedroom, create your own helpers with lower values, for example 17 °C and 16 °C. The radar also detects people who are asleep, so the heating does not stay off at night because of a lack of movement.

Step 3: Let the thermostat regulate by room temperature

It is cleanest if the thermostat itself accepts an external temperature value. Some models offer a setting for this in their integration, such as “external temperature” or “remote sensor”. Check under Settings → Devices & services whether your thermostat has such an entity, and write the value of the presence sensor into it with an automation.

If your thermostat cannot do this, Home Assistant compensates for the difference. The following automation compares the temperature at the thermostat with the one at the presence sensor every 15 minutes and shifts the setpoint by exactly this difference. If the thermostat measures 23 °C and the sensor on the sofa 20 °C, but you want 20 °C on the sofa, it sets the thermostat to 23 °C.

As a blueprint it is called “Heizen nach Raumtemperatur regeln” (regulate by room temperature). You set the maximum offset on the setpoint there, the default is 4 °C.

Import blueprint “Heizen nach Raumtemperatur regeln” into Home Assistant

alias: "Heating: regulate living room by room temperature"
description: >
  Shifts the thermostat setpoint by the difference
  between radiator and room.
mode: single
triggers:
  - trigger: time_pattern
    minutes: /15
variables:
  ziel: >
    {{ states('input_number.komforttemperatur') | float
       if is_state('input_boolean.wohnzimmer_belegt', 'on')
       else states('input_number.absenktemperatur') | float }}
  am_thermostat: "{{ state_attr('climate.wohnzimmer', 'current_temperature') | float(0) }}"
  im_raum: "{{ states('sensor.multi_zone_presence_sensor_temperature') | float(0) }}"
  sollwert: "{{ [[ziel + am_thermostat - im_raum, ziel] | max, ziel + 4] | min | round(1) }}"
conditions:
  - condition: state
    entity_id: input_boolean.heizen_nach_anwesenheit
    state: "on"
  - condition: not
    conditions:
      - condition: state
        entity_id: climate.wohnzimmer
        state: "off"
    note: "Leave a switched-off thermostat alone, for example while ventilating."
  - condition: template
    value_template: "{{ am_thermostat > 0 and im_raum > 0 }}"
    note: "Only calculate if both values are available."
  - condition: template
    value_template: >
      {{ (sollwert - state_attr('climate.wohnzimmer', 'temperature') | float(0)) | abs >= 0.5 }}
    note: "Skip small changes, this spares the thermostat's battery."
actions:
  - action: climate.set_temperature
    target:
      entity_id: climate.wohnzimmer
    data:
      temperature: "{{ sollwert }}"

Two limits are built in. The setpoint never falls below your desired temperature and rises at most 4 °C above it. If the presence sensor fails or delivers no value, the automation does not calculate and the thermostat keeps its last setpoint.

Whether the comfort or the setback temperature currently applies is read by the control from the helper Wohnzimmer belegt. This way the 30 and 5 minutes from step 2 apply here too. In the first test run, the control still evaluated the sensor itself and lowered the temperature as soon as the room had been empty for one minute, which made the waiting time from step 2 pointless. After a restart of Home Assistant, the helper keeps its state. The half hour from step 2 does start again from the beginning, though, so the room stays at comfort temperature for at most half an hour longer. The automation leaves a switched-off thermostat alone so that it does not interfere with the ventilation described below.

Step 4: Ventilate when the humidity rises

Cooking, showering, drying laundry and even breathing bring moisture into the room air. This automation notifies you when the humidity in the room has been above 60 % for 15 minutes and someone is there who can ventilate. If nobody is in the room, it waits until someone comes.

In the blueprint “Lüften nach Luftfeuchte (Hinweis)” (airing notification) you set the threshold, duration, pause and the room name for the message.

Import blueprint “Lüften nach Luftfeuchte (Hinweis)” into Home Assistant

alias: "Ventilation: notification living room"
description: >
  Reports high humidity as soon as someone is in the room.
mode: single
max_exceeded: silent
triggers:
  - trigger: numeric_state
    entity_id: sensor.multi_zone_presence_sensor_humidity
    above: 60
    for:
      minutes: 15
    note: "Threshold according to the UBA. Use your own entity ID."
  - trigger: state
    entity_id: binary_sensor.multi_zone_presence_sensor_presence
    to: "on"
conditions:
  - condition: numeric_state
    entity_id: sensor.multi_zone_presence_sensor_humidity
    above: 60
  - condition: state
    entity_id: binary_sensor.multi_zone_presence_sensor_presence
    state: "on"
actions:
  - action: notify.mobile_app_ihr_smartphone
    data:
      title: "Please ventilate"
      message: >
        Humidity in the living room:
        {{ states('sensor.multi_zone_presence_sensor_humidity') | round(0) }} %.
        Open the windows wide for five minutes.
  - delay:
      hours: 2
    note: "At most one notification every two hours."

The presence trigger makes sure the notification is not lost: if the humidity rises while everyone is out, the message arrives as soon as someone enters the room. The pause at the end prevents you from being reminded again every time you enter. While it is running, Home Assistant discards further triggers; max_exceeded: silent ensures that the warning “Already running” does not end up in the log every time.

Ventilating with the heating off

So that the radiator does not heat against the open window during airing, the dashboard gets a “Lüften” (ventilate) button. One press turns the heating off, after five minutes Home Assistant reminds you to close the window and sets the heating back. To do this, create a helper of type Button named Wohnzimmer lüften (living room ventilate). Home Assistant forms the entity ID from the name and reduces umlauts to the base letter: this gives input_button.wohnzimmer_luften, not wohnzimmer_lueften.

The matching blueprint is called “Lüften mit abgedrehter Heizung (Taste)” (airing button), and the airing time is adjustable there.

Import blueprint “Lüften mit abgedrehter Heizung (Taste)” into Home Assistant

alias: "Ventilation: heating off while ventilating"
description: >
  Turns the heating off for five minutes and then reminds you
  to close the windows.
mode: restart
triggers:
  - trigger: state
    entity_id: input_button.wohnzimmer_luften
actions:
  - action: climate.set_hvac_mode
    target:
      entity_id: climate.wohnzimmer
    data:
      hvac_mode: "off"
  - delay:
      minutes: 5
    note: "In winter, about five minutes is enough according to the UBA."
  - action: notify.mobile_app_ihr_smartphone
    data:
      title: "Close the windows"
      message: "The heating in the living room is running again."
  - action: climate.set_hvac_mode
    target:
      entity_id: climate.wohnzimmer
    data:
      hvac_mode: heat
  - action: climate.set_temperature
    target:
      entity_id: climate.wohnzimmer
    data:
      temperature: "{{ states('input_number.komforttemperatur') | float }}"
    note: "Whoever ventilates is in the room: comfort temperature."

If your thermostat has no “off” mode, set the lowest temperature it accepts for the five minutes instead, and then the comfort temperature again.

Home Assistant living room dashboard (German interface): thermostat at 20 °C, Heizen nach Anwesenheit switch, Komforttemperatur 20 °C and Absenktemperatur 18 °C, ventilate button, below it presence, temperature and humidity from the presence sensor
This is what the living room looks like on the dashboard: thermostat, main switch, the two temperatures from step 1, the “Lüften” button and the readings of the presence sensor.

Step 5: Bathroom fan by humidity

In the bathroom, it is not presence that decides but the humidity after showering. The fan starts when the humidity rises above 70 % and switches off when it has been below 60 % for ten minutes. The gap between the two thresholds prevents the fan from switching on and off every minute.

For this, mount the presence sensor outside the splash area of the shower and washbasin. On the side, it detects whether someone is in the bathroom and can switch the light at the same time, as described in Light control with the KL MZ.

We only tested this automation with simulated readings, not in a bathroom. The thresholds 70 and 60 % are a starting value; after a few days, look at the humidity curve after showering and adjust them to your bathroom.

alias: "Bathroom: fan by humidity"
description: >
  Switches the fan on above 70 % and off again below 60 %.
mode: restart
triggers:
  - trigger: numeric_state
    entity_id: sensor.multi_zone_presence_sensor_humidity
    above: 70
    id: feucht
    note: "Use the entity ID of the sensor in the bathroom."
  - trigger: numeric_state
    entity_id: sensor.multi_zone_presence_sensor_humidity
    below: 60
    for:
      minutes: 10
    id: trocken
actions:
  - choose:
      - conditions:
          - condition: trigger
            id: feucht
        sequence:
          - action: switch.turn_on
            target:
              entity_id: switch.badluefter
      - conditions:
          - condition: trigger
            id: trocken
        sequence:
          - action: switch.turn_off
            target:
              entity_id: switch.badluefter

So that the readings are correct

  • Warm-up time: After switching on, temperature, humidity and air pressure need up to 30 minutes to settle. Only test the automations after that.
  • Mounting location: not directly above the radiator, not in the sun by the window and not next to the coffee machine. Otherwise the sensor measures the heat source instead of the room.
  • Seat within the presence area: If the sensor only detects you on the sofa now and then, the heating depends on these brief reports. If they stay away for longer than the waiting time, Home Assistant lowers the temperature although you are sitting in the room. Whether the sofa and armchair lie within the presence area is shown by the room planner before mounting. On the KL MZ, a stay zone at the sofa also holds the presence.
  • Calibration: If a value differs from a reference device, correct it in the sensor's interface under “System” with an offset, separately for temperature, humidity and air pressure.

Which presence sensor is right?

For living rooms, bedrooms and offices with a fixed seat, the KL MZ is the first choice: stay zones hold the presence at the sofa, interference zones mask out a fan or a curtain, and it distinguishes up to four people. For simple rooms, the KL with 6 m or the KL LD with 9 m range is enough. All three measure the room climate without a second device. If you already have a Basis model, upgrade it with the climate multisensor. You can find the comparison of all models in the overview of all presence sensors.

Frequently asked questions

Does controlling by presence save heating costs?

It heats rooms less when nobody is in them, and that saves energy. How much depends on the house, the heating and how often rooms are empty. We therefore do not give a fixed figure.

Does the presence sensor replace the thermostat?

No. The presence sensor measures and reports, the thermostat controls the radiator. Home Assistant connects the two.

Does this also work with underfloor heating?

The ventilation notifications do. Lowering the heating by presence brings little with underfloor heating, because it takes hours to reach a new temperature.

Can the presence sensor detect open windows?

Not directly. Window contacts exist for that. The “Lüften” button from this guide turns the heating off while you ventilate, without needing a contact.

Do I need the cloud?

No. The presence sensors send their values via MQTT directly to Home Assistant on your own network.

All data on the devices can be found on the product pages of the KL MZ presence sensor and the KL presence sensor with room climate sensor. How radar differs from a motion detector is explained in Presence sensor or motion detector?

See what your presence sensor covers before you buy

Draw your room with furniture and doors, place a sensor and see where it detects presence. In the browser, on your phone too, no sign-up.