I’ve achieved this using a combination of a timer helper, script, automations and a conditional mushroom chip. I’m very happy with the outcome, although my YAML and jinja may be ugly as I figured out how to do this on the way and tripped up a few times.
timer code in configuration.yaml - you can do this through helpers UI if you prefer
timer:
ac_off_countdown:
name: "AC Off Countdown"
restore: true
Script that can be called to start, increment or cancel the timer, depending on A/C conditions. This goes in scripts.yaml.
timer_increment_or_reset:
alias: AC sleep increment or reset
sequence:
- choose:
- conditions: # timer isn't running already and A/C is on
- condition: not
conditions:
- condition: state
entity_id: timer.ac_off_countdown
state: active
- condition: not
conditions:
- condition: state
entity_id: climate.xx # your AC entity here
state: 'off'
sequence: # start timer
- service: timer.start
data:
duration: '00:30:00'
target:
entity_id: timer.ac_off_countdown
- conditions: # A/C is on and timer is less than 12 hours - 30 minutes)
- condition: not
conditions:
- condition: state
entity_id: climate.xx # your AC entity here
state: 'off'
- condition: template
value_template: >-
{{ (as_timestamp(state_attr('timer.ac_off_countdown', 'finishes_at')) - now().timestamp()) < 39600 }}
sequence: # add 30 minutes to existing timer
- service: timer.start
data:
duration: >
{% set s = as_timestamp(state_attr('timer.ac_off_countdown', 'finishes_at')) - now().timestamp() %} 00:00:{{ s | int + 1800 }}
entity_id: timer.ac_off_countdown
default: # cancel the timer
- service: timer.cancel
data: {}
target:
entity_id: timer.ac_off_countdown
mode: restart
icon: mdi:sleep
Automation to do something when the timer finishes
alias: Air off
description: Turn off AC
trigger:
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.ac_off_countdown
condition:
- condition: not
conditions:
- condition: state
state: "off"
entity_id: climate.xx # your AC entity here
action:
- service: climate.turn_off
data: {}
target:
entity_id: climate.xx # your AC entity here
mode: single
This automation simply cancels a running timer if the A/C is turned off some other way
alias: Reset AC timer on AC off
description: ''
trigger:
- platform: state
entity_id:
- climate.xx # your AC entity here
to: 'off'
condition:
- condition: state
entity_id: timer.ac_off_countdown
state: active
action:
- service: timer.cancel
data: {}
target:
entity_id: timer.ac_off_countdown
mode: single
Dashboard card, you can do this however. I’m using a mushroom conditional chip so the card is only there where needed.
type: custom:mushroom-chips-card
chips:
- type: conditional
conditions:
- entity: climate.xx # your AC entity here
state_not: 'off'
chip: # chip contents either show 'sleep', seconds remaining, minutes remaining or hh:mm depending on context
type: template
icon: mdi:sleep
content: |
{% if states('timer.ac_off_countdown') != 'active'%}
Sleep
{% else %}
{% set s = (as_timestamp(state_attr('timer.ac_off_countdown','finishes_at')) - as_timestamp(now()) ) | int %}
{% set m = (s / 60) | round(0) %}
{% if s < 60 %}
{{s}} secs
{% elif m > 60 %}
{{ m // 60 }}:{{ '{:0>2d}'.format(m%60) }} hours
{% else %}
{{ m }} mins
{% endif %}
{% endif %}
tap_action: # run the script when tapped
action: call-service
service: script.timer_increment_or_reset
data: {}
target: {}
hold_action: # cancel the timer if held
action: call-service
service: timer.cancel
data: {}
target:
entity_id: timer.ac_off_countdown
double_tap_action:
action: none
entity: timer.ac_off_countdown
alignment: center