This new helper is ideal for controlling devices such as a water heater which just requires an on/off control. I have set this up and it works fine. The advantage for my family is that it is easy for them to change it, as they have no wish to start messing with automations!
However, my home heating system is divided into zones for each room, and I would like the ability to schedule not just turning the heating on or off, but also set the temperature of each room throughout the day.
At the moment, I do not see a simple way of implementing this, so I would be interested in any thoughts you might have.
I have an automation that lowers or raises my thermostat temperature based on the current energy rate (peak or off-peak) and if the unit is heating or cooling. It changes the set temperature by an even greater amount if the house is empty or everyone is in bed. In winter at my house this is actually cheaper than switching the heat pump off and scheduling it to come on before people get out of bed or get home. Not letting everything in the house cool down actually lets the heat pump work less. This is generally only the case in winter. In summer, spring and autumn I can schedule the heat pump power to save money.
This is unlikely to suit everyone.
As well as the peak/off-peak or away/home temperatures I also have a boost schedule that warms the house before everyone gets up or arrives home.
The automation also turns the heat pump back on if it was turned off because someone left a door or window open (there is another automation for the turn off action).
Here’s how I do it:
- id: 8ee62b46-d5e6-439c-a89f-31a29da2d20b
alias: 'Upstairs Aircon Temperature Adjustment'
variables:
delta_mode: >
{{ -1 if is_state('climate.upstairs', 'heat') else 1 }}
set_point: >
{% if is_state('climate.upstairs', 'cool') %}
{{ states('input_number.upstairs_ac_temp_set_cool')|int(22) }}
{% else %}
{{ states('input_number.upstairs_ac_temp_set_heat')|int(20) }}
{% endif %}
away: >
{{ is_state('alarm_control_panel.alarmo', 'armed_away') or states('binary_sensor.everyone_in_bed')|bool(0) }}
peak: >
{{ states('binary_sensor.peak_rate')|bool(1) }}
boost: >
{{ states('schedule.upstairs_ac_boost')|bool(0) }}
delta: >
{# AWAY #}
{% if away and not boost %}
{{ states('input_number.away_or_in_bed_delta')|int(3) * delta_mode }}
{# PEAK #}
{% elif (peak and boost) or (peak and not away) %}
{{ states('input_number.peak_rate_delta')|int(1) * delta_mode }}
{# BOOST #}
{% elif boost and not peak %}
{{ states('input_number.boost_delta')|int(0) * delta_mode * -1 }}
{# OFF PEAK #}
{% else %}
0
{% endif %}
set_temp: >
{{ set_point + delta }}
trigger:
- platform: state
entity_id: binary_sensor.peak_rate
to:
- "on"
- "off"
id: peak
- platform: state
entity_id: binary_sensor.everyone_in_bed
to:
- "on"
- "off"
id: away_night
- platform: state
entity_id: alarm_control_panel.alarmo
to:
- "disarmed"
- "armed_away"
id: alarm
- platform: state
entity_id: schedule.upstairs_ac_boost
to:
- "on"
- "off"
id: boost
- platform: state
entity_id: input_number.upstairs_ac_temp_set_heat
to:
id: heat_set_point
- platform: state
entity_id: input_number.upstairs_ac_temp_set_cool
to:
id: cool_set_pint
- platform: state
entity_id: input_number.away_or_in_bed_delta
to:
id: away_delta
- platform: state
entity_id: input_number.peak_rate_delta
to:
id: peak_delta
- platform: state
entity_id: input_number.boost_delta
to:
id: boost_delta
- platform: state
entity_id: group.upstairs_doors_and_windows
from: "on"
to: "off"
for:
minutes: 5
id: doors_closed
condition:
- condition: or
conditions:
- "{{ states('climate.upstairs') in ['heat', 'cool'] }}"
- condition: trigger
id: doors_closed
action:
- continue_on_error: true
service: notify.telegram_system
data:
title: "🌡️ *Upstairs Heatpump Temperature Change*"
message: >
From {{ state_attr('climate.upstairs', 'temperature')}}°C to {{ set_temp }}°C
Trigger: {{ trigger.id | replace('_', ' ') }} from {{ trigger.from_state.state }} to {{ trigger.to_state.state }}
- service: climate.set_temperature
target:
entity_id: climate.upstairs
data:
temperature: "{{ set_temp }}"
Breaking it down, first I determine if I should be adjusting the temperature up or down:
delta_mode: >
{{ -1 if is_state('climate.upstairs', 'heat') else 1 }}
Then grab the current temperature I would like the house to be, depending on if it is being cooled or heated:
set_point: >
{% if is_state('climate.upstairs', 'cool') %}
{{ states('input_number.upstairs_ac_temp_set_cool')|int(22) }}
{% else %}
{{ states('input_number.upstairs_ac_temp_set_heat')|int(20) }}
{% endif %}
Then I check to see if everyone is in bed or away, if the boost schedule is active or if the peak electricity rate is on:
away: >
{{ is_state('alarm_control_panel.alarmo', 'armed_away') or states('binary_sensor.everyone_in_bed')|bool(0) }}
peak: >
{{ states('binary_sensor.peak_rate')|bool(1) }}
boost: >
{{ states('schedule.upstairs_ac_boost')|bool(0) }}
It can be all three at once or any mix of these things.
Then I calculate how much the temperature should be changed based on those states:
delta: >
{# AWAY #}
{% if away and not boost %}
{{ states('input_number.away_or_in_bed_delta')|int(3) * delta_mode }}
{# PEAK #}
{% elif (peak and boost) or (peak and not away) %}
{{ states('input_number.peak_rate_delta')|int(1) * delta_mode }}
{# BOOST #}
{% elif boost and not peak %}
{{ states('input_number.boost_delta')|int(0) * delta_mode * -1 }}
{# OFF PEAK #}
{% else %}
0
{% endif %}
set_temp: >
{{ set_point + delta }}
Then we get to the automation. It can be triggered by many things changing, including if I change any of the temperature settings:
trigger:
- platform: state
entity_id: binary_sensor.peak_rate
to:
- "on"
- "off"
id: peak
- platform: state
entity_id: binary_sensor.everyone_in_bed
to:
- "on"
- "off"
id: away_night
- platform: state
entity_id: alarm_control_panel.alarmo
to:
- "disarmed"
- "armed_away"
id: alarm
- platform: state
entity_id: schedule.upstairs_ac_boost
to:
- "on"
- "off"
id: boost
- platform: state
entity_id: input_number.upstairs_ac_temp_set_heat
to:
id: heat_set_point
- platform: state
entity_id: input_number.upstairs_ac_temp_set_cool
to:
id: cool_set_pint
- platform: state
entity_id: input_number.away_or_in_bed_delta
to:
id: away_delta
- platform: state
entity_id: input_number.peak_rate_delta
to:
id: peak_delta
- platform: state
entity_id: input_number.boost_delta
to:
id: boost_delta
- platform: state
entity_id: group.upstairs_doors_and_windows
from: "on"
to: "off"
for:
minutes: 5
id: doors_closed
We only run the actions if the heat pump is cooling or heating or if the doors and windows were closed:
condition:
- condition: or
conditions:
- "{{ states('climate.upstairs') in ['heat', 'cool'] }}"
- condition: trigger
id: doors_closed
The actual actions are simple, log why the heating was changed, and from what to what:
action:
- continue_on_error: true
service: notify.telegram_system
data:
title: "🌡️ *Upstairs Heatpump Temperature Change*"
message: >
From {{ state_attr('climate.upstairs', 'temperature')}}°C to {{ set_temp }}°C
Trigger: {{ trigger.id | replace('_', ' ') }} from {{ trigger.from_state.state }} to {{ trigger.to_state.state }}
Then actually change the temperature:
- service: climate.set_temperature
target:
entity_id: climate.upstairs
data:
temperature: "{{ set_temp }}"
Here are the dashboard controls (keeping in mind that the adjustments are up or down depending on the heat pump state):
Thanks @tom_l , I currently am using oil fired heating but I hope to switch to air-water heat pump shortly so I’ll give it a try them.