Appreciate this is an old thread. I was looking for something similar, couldn’t find anything that met my needs so created a script for this. Wanted to share in case it was still useful for anyone.
HELPERS
group.all_radiators
group of all TRV sensors (used when sleep mode is off)
group.upstairs_radiators
group of upstairs radiators (used when sleep mode is on)
input_boolean.auto_heating
enables the below automation
input_boolean.holiday_mode
used to set a frost mode (currently hard coded to 15 in script)
input_booemphasized textlean.sleep_mode
used to switch what radiators call for heating
AUTOMATION
This looks for changes in the TRV / radiators and calls the script.
Only works if input_boolean.auto_heating is “on”.
alias: "[Climate] Auto Switch Boiler Heating"
trigger:
- platform: state
entity_id:
- climate.lounge_trv
- climate.kitchen_trv
- climate.utility_trv
- climate.bedroom_trv
- climate.bed2_trv
- climate.ensuite_trv
- climate.nursery_trv
condition:
- condition: state
entity_id: input_boolean.auto_heating
state: "on"
action:
- service: script.boiler_heating
data: {}
mode: parallel
SCRIPT
This essentially loops through the radiators, and decides if any of them require heating.
If so the boiler is turned on, else it is turned off.
If the battery is too low for a radiator it skips it, as mine get stuck in a state when battery dies.
This stops heating being constantly on.
The battery levels on my TRVs are not an attribute but another sensor. So it is worth pointing out that my naming convention allows this to work as well.
For example if I have climate.lounge_trv, then the battery for this is named sensor.lounge_trv_battery_level.
There are also a few hard coded values / logic that I have not yet exposed to helpers:
- frost mode set to 15 (this is used as the cuttOff when holiday_mode is “on”)
- offset is set to 1 (this is how much lower a rad can go to before it requires heat)
- offset is set to 2 when sleep_mode is “on”
entity_id: switch.boiler_heating
service: >
{% set ns = namespace(value=0) %}
{% set currentlyHeating = states('switch.boiler_heating') %}#
{% set holiday_mode = states('input_boolean.holiday_mode') %}
{% set sleep_mode = states('input_boolean.sleep_mode') %}
{% if sleep_mode == 'on' %}
{% set rads = states.group.upstairs_radiators.attributes.entity_id %}
{% else %}
{% set rads = states.group.all_radiators.attributes.entity_id %}
{% endif %}
{% for rad in rads %}
{% set setPoint = state_attr(rad, 'temperature') %}
{% set name = rad.split(".")[1] %}
{# set temp to a float - defaults to 0 #}
{% set currentTemp = state_attr(rad, 'current_temperature') | float(0) %}
{# set battery to a float - defaults to 0 #}
{% set battery = states('sensor.' + name +'_battery_level') | float(0) %}
{# if battery is too low skip this rad #}
{% if battery <= 10 | float %}
{% continue %}
{% endif %}
{# if currentTemp is the default 0 then skip this rad #}
{# this also caters for an 'unknown' rad #}
{% if currentTemp == 0 | float %}
{% continue %}
{% endif %}
{# default offset and cuttoff #}
{% set offset = 1 %}
{% set cuttOff = setPoint - offset %}
{# mode overrides #}
{% if holiday_mode == 'on' %}
{# when away use a frost mode #}
{% set cuttOff = 15 %}
{% elif sleep_mode == 'on' %}
{# when asleep use a larger offset #}
{% set offset = 2 %}
{% set cuttOff = setPoint - offset %}
{% endif %}
{% if currentTemp < cuttOff | float %}
{% set ns.value = ns.value + 1 %}
{% endif %}
{% endfor %}
{% if ns.value | int > 0 %}
switch.turn_on
{% else %}
switch.turn_off
{% endif %}
Anyway, apologies for reviving an old thread but hopefully useful for someone.
I’m away a lot with work but hopefully I can answer any questions