Skip to content

Instantly share code, notes, and snippets.

@baszalmstra
Created April 21, 2026 12:43
Show Gist options
  • Select an option

  • Save baszalmstra/951316ae59d769a5a6a1cd826d133a1a to your computer and use it in GitHub Desktop.

Select an option

Save baszalmstra/951316ae59d769a5a6a1cd826d133a1a to your computer and use it in GitHub Desktop.
auto disable ac
blueprint:
name: AC Auto-Off When At Setpoint
description: |
Turns off an air conditioner when the measured temperature has been
close to the setpoint for a configurable duration, subject to any
additional conditions (time of day by default).
**How it works**
The automation evaluates two triggers:
• The absolute delta between `current_temperature` and `temperature`
(setpoint) on the AC has stayed below the threshold for the
configured duration.
• A periodic safety re-check every 10 minutes.
On either trigger, all of these must be true:
• The AC is currently on (any non-off hvac mode).
• Its state has been unchanged for at least the minimum runtime.
• The current delta is still below the threshold.
• Your additional conditions pass (default: after 19:00).
**Requirements**
The AC climate entity must expose both `current_temperature` and
`temperature` attributes. This is the norm for single-setpoint modes
(cool, heat). In `heat_cool` / auto mode the setpoint is split into
`target_temp_low` / `target_temp_high`, which this blueprint does not
handle — use a fixed cool or heat mode on the AC for it to work.
domain: automation
input:
ac_entity:
name: Air conditioner
description: The climate entity to turn off.
selector:
entity:
domain: climate
proximity_threshold:
name: Proximity threshold (°C)
description: >
Maximum |current_temperature − setpoint| for the AC to count as
"at target". 0.5 °C is a reasonable starting point.
default: 0.5
selector:
number:
min: 0.1
max: 3.0
step: 0.1
unit_of_measurement: "°C"
mode: slider
proximity_duration_minutes:
name: Proximity duration (minutes)
description: >
How long the temperature must stay within the threshold before
the AC is considered at target.
default: 10
selector:
number:
min: 1
max: 120
step: 1
unit_of_measurement: minutes
mode: box
minimum_runtime_minutes:
name: Minimum runtime (minutes)
description: >
The AC's state must have been unchanged for at least this long
(i.e., it's been running continuously without any mode switch).
default: 60
selector:
number:
min: 1
max: 720
step: 1
unit_of_measurement: minutes
mode: box
additional_conditions:
name: Additional conditions
description: >
Extra conditions that must all pass. Defaults to "after 19:00".
Add time windows, weekday filters, presence checks, sun state,
or anything else using the condition builder.
default:
- condition: time
after: "19:00:00"
selector:
condition: {}
post_actions:
name: Additional actions (optional)
description: >
Run after the AC is turned off. Useful for notifications.
default: []
selector:
action: {}
mode: single
# Variables available in triggers
trigger_variables:
tv_ac_entity: !input ac_entity
# Variables available in conditions and actions
variables:
ac_entity: !input ac_entity
minimum_runtime_minutes: !input minimum_runtime_minutes
proximity_threshold: !input proximity_threshold
trigger:
# Delta has been below threshold for proximity_duration_minutes
- platform: numeric_state
entity_id: !input ac_entity
value_template: >
{% set cur = state_attr(tv_ac_entity, 'current_temperature') %}
{% set tgt = state_attr(tv_ac_entity, 'temperature') %}
{% if cur is none or tgt is none %}
999
{% else %}
{{ (cur | float - tgt | float) | abs }}
{% endif %}
below: !input proximity_threshold
for:
minutes: !input proximity_duration_minutes
# Periodic safety re-check
- platform: time_pattern
minutes: "/10"
condition:
# AC is currently on (any non-off hvac mode, and available)
- condition: template
value_template: >
{{ states(ac_entity) not in ['off', 'unavailable', 'unknown'] }}
# AC state has been unchanged for at least minimum_runtime_minutes
- condition: template
value_template: >
{{ (now() - states[ac_entity].last_changed).total_seconds()
> (minimum_runtime_minutes | int * 60) }}
# Current delta is below threshold (also guards the time_pattern path)
- condition: template
value_template: >
{% set cur = state_attr(ac_entity, 'current_temperature') %}
{% set tgt = state_attr(ac_entity, 'temperature') %}
{{ cur is not none
and tgt is not none
and (cur | float - tgt | float) | abs < (proximity_threshold | float) }}
# User-configurable conditions (default: after 19:00)
- condition: and
conditions: !input additional_conditions
action:
- service: climate.turn_off
target:
entity_id: !input ac_entity
- choose: []
default: !input post_actions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment