Using the new Weekly Schedule helper to control temperature?

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):

Screenshot 2022-09-09 at 17-38-59 Overview – Home Assistant

Screenshot 2022-09-09 at 17-39-34 Overview – Home Assistant

2 Likes

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.