My hot water cylinder is heated using a schedule, but sometimes I need to heat it up for an additional period. I wanted something that emulates the traditional “+1 hour” button that simple Sundial (or similar) controllers have.
After a lot of trial end error, I came up with the following solution:
Or when running:
Each press on +10 / +30 adds 10 / 30 minutes to the timer, the right most button cancels the timer. Obviously this can also work for lights, or anything really.
The frontend uses Paper Buttons Row, the backend uses a simple timer which is manipulated as inspired by Add time to an already running timer - #4 by 123.
Lovelace yaml:
type: entities
entities:
- entity: timer.manual_hot_water
name: Boost Hot Water
extend_paper_buttons_row:
buttons:
- entity: script.manual_hot_water_add_time
icon: mdi:timer-plus
name: 10m
tap_action:
action: call-service
service: script.manual_hot_water_add_time
service_data:
time: 10
preset: mushroom
- entity: script.manual_hot_water_add_time
name: 30m
icon: mdi:timer-plus
tap_action:
action: call-service
service: script.manual_hot_water_add_time
service_data:
time: 30
preset: mushroom
- entity: script.manual_hot_water_add_time
name: false
icon: mdi:timer-cancel
tap_action:
action: call-service
service: script.manual_hot_water_add_time
service_data:
time: 0
preset: mushroom
styles:
button:
margin-right: 0px
title: Heating
show_header_toggle: false
heating.yaml
package:
timer:
manual_hot_water:
restore: true
automation heating:
- id: hot_water_boost_off
alias: Turn hot water off as boost requires
trigger:
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.manual_hot_water
action:
- service: switch.turn_off
target:
entity_id: switch.boiler_l2
- id: hot_water_boost_on
alias: Turn hot water on as boost requires
trigger:
- platform: event
event_type: timer.start
event_data:
entity_id: timer.manual_hot_water
action:
- service: switch.turn_on
target:
entity_id: switch.boiler_l2
script:
manual_hot_water_add_time:
description: "Add x minutes to hot water timer, or cancel it by adding 0 minutes"
fields:
time:
description: "How much time?"
default: "30"
selector:
number:
min: 0
max: 120
mode: queued
sequence:
- choose:
- conditions:
- condition: template
value_template: "{{int(time) == 0}}"
sequence:
- service: timer.cancel
target:
entity_id: timer.manual_hot_water
- service: automation.trigger
target:
entity_id: automation.turn_hot_water_off_as_boost_requires
default:
- service: timer.start
data_template:
entity_id: timer.manual_hot_water
duration: >-
{% set f = state_attr('timer.manual_hot_water', 'finishes_at') %}
{{ int(time)*60 if f == none else (as_datetime(f) - now()).total_seconds() + int(time)*60 }}
- service: automation.trigger
target:
entity_id: automation.turn_hot_water_on_as_boost_requires
I am also using this for heating our living room (which we only occasionally use, and therefore we don’t have a set schedule):
heating_living_room.yaml
package:
input_number:
living_room_heating_temperature:
name: Living Room Heating Target Temperature
min: 17
max: 22
step: 1
living_room_min_temperature:
name: Living Room Minimum Temperature
min: 8
max: 16
step: 1
timer:
living_room_heated:
restore: true
automation:
- id: living_room_heating_update_min
alias: Update Living Room Heating Min Temp
trigger:
platform: state
entity_id: input_number.living_room_min_temperature
condition:
condition: state
entity_id: timer.living_room_heated
state: "idle"
action:
- service: climate.set_temperature
target:
entity_id: climate.thermostat_living_room
data:
temperature: "{{ states('input_number.living_room_min_temperature') | int }}"
- id: living_room_heating_update_heated
alias: Update Living Room Heating Heated Temperature
trigger:
platform: state
entity_id: input_number.living_room_heating_temperature
condition:
condition: state
entity_id: timer.living_room_heated
state: "active"
action:
- service: climate.set_temperature
target:
entity_id: climate.thermostat_living_room
data:
temperature: "{{ states('input_number.living_room_heating_temperature') | int }}"
- id: living_room_heating_off
alias: Turn Living Room Heating Off
trigger:
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.living_room_heated
action:
- service: climate.set_temperature
target:
entity_id: climate.thermostat_living_room
data:
temperature: "{{ states('input_number.living_room_min_temperature') | int }}"
- id: living_room_heating_on
alias: Turn Living Room Heating On
trigger:
- platform: event
event_type: timer.start
event_data:
entity_id: timer.living_room_heated
action:
- service: climate.set_temperature
target:
entity_id: climate.thermostat_living_room
data:
temperature: "{{ states('input_number.living_room_heating_temperature') | int }}"
script:
update_living_room_heating_timer:
description: "Add x minutes to timer, or cancel it by adding 0 minutes"
fields:
time:
description: "How much time?"
default: "30"
selector:
number:
min: 0
max: 120
mode: queued
sequence:
- choose:
- conditions:
- condition: template
value_template: "{{int(time) == 0}}"
sequence:
- service: timer.cancel
target:
entity_id: timer.living_room_heated
- service: automation.trigger
target:
entity_id: automation.turn_living_room_heating_off
default:
- service: timer.start
data_template:
entity_id: timer.living_room_heated
duration: >-
{% set f = state_attr('timer.living_room_heated', 'finishes_at') %}
{{ int(time)*60 if f == none else (as_datetime(f) - now()).total_seconds() + int(time)*60 }}
- service: automation.trigger
target:
entity_id: automation.turn_living_room_heating_on
This works very well for me - let me know what you think and how it could be improved even further!