The climate_template platform creates climate devices that combine integrations and provides the ability to run scripts or invoke services for each of the set_* commands of a climate entity.
This is a fork of the original repository jcwillox/hass-template-climate, which appears to be unmaintained at the time and had several pull requests pending. As those were very useful for my usage, I decided to fork and merge the work of the corresponding authors to allow for simple usage of the integration through HACS. Therefore, all the corresponding rights belong to the original authors. I also started fixing additional user issues and adding functionality while trying to maintain compatibility, but please note that there are some breaking changes from the original version.
- Config parameter
modesrenamed tohvac_modes hvac_modeslist is set only to["off", "heat"]by default.preset_modes,fan_modesandswing_modesare now not set by default and shall be configured only if being used and set to the used miminum list of modes.
For a long time, I wanted climate preset modes to function as profiles. So you can have a profile that defines any climate attributes such as HVAC mode, fan mode, swing mode, target temperatures, and humidity, and by a single click activate that profile. Users should be able to modify any given preset attribute value using both the HA GUI and service calls. Also, set preset attribute values should be preserved across HA restarts. Now all of this is possible! To control this feature, three new configuration options — presets_features, presets_template, and set_presets — were introduced.
presets_features is a bit flag used to identify which parameters (HVAC mode, fan mode, swing mode, target temperatures, and humidity) you would like to manage with presets:
1 - preset attributes are changeable via HA
2 - preset attributes are preserved across HA restarts
4 - HVAC mode is a preset attribute
8 - fan mode is a preset attribute
16 - swing mode is a preset attribute
32 - target temperature is a preset attribute
64 - high/low temperature are preset attributes
128 - target humidity is a preset attribute
The presets_features value should be the sum of all active feature values as above. If set to 0, presets are disabled.
presets_template — if it is possible to set or change preset attributes directly on the managed device and you need to sync changes back to HA, you need to provide presets_template, which returns a dictionary object containing all presets, each containing every preset attribute. Example of the return object with all preset attributes managed:
'some_preset_name': {
'hvac_mode': 'heat',
'fan_mode": 'on',
'swing_mode": 'fast',
'target_temperature': 22,
'target_temperature_low': 19,
'target_temperature_high': 23
},
'other_preset_name': {
'hvac_mode': 'off',
....
}, ...
set_presets - it is template to set / synchronize managed device presets atributes to the values managed in HomeAssistant. Therefore if you change preset attribute value in HA it will be propagated to the managed device. This template is called with two variables, presets variable contains complete list of all presets, each will all managed presets attributes i.e.:
'some_preset_name': {
'hvac_mode': 'heat',
'fan_mode": 'on',
'swing_mode": 'fast',
'target_temperature': 22,
'target_temperature_low': 19,
'target_temperature_high': 23
},
'other_preset_name': {
'hvac_mode': 'off',
....
}, ...
The other valiable changed only contains the preset mode and attribute which triggered the run:
{'some_preset_name': { 'target_temperature': 24 } }
Please check example presets configuration bellow to see how to both construct required dictionary objects and how to prase those in template.
All configuration variables are optional. If you do not define a template or its corresponding action, the climate device will not register the given attribute/function in HA. For example, either swing_mode_template or set_swing_mode should be defined (together with allowed swing_modes) for the climate entity to have working swing mode functionality.
| Name | Type | Description | Default Value |
|---|---|---|---|
| name | string |
The name of the climate device. | "Template Climate" |
| unique_id | string |
The unique id of the climate entity. | None |
| mode_action | string |
Possible values: parallel, queued, restart, single. For explanation, see the script documentation. |
single |
| max_action | positive_int |
Limits the number of concurrent runs of actions. Used together with parallel and queued mode_action, set to a positive number greater than 1. For explanation, see the script documentation. |
1 |
| presets_features | positive_int |
Define the feature flags supported by the preset_mode feature as bit flags. See example for options. Default value 0 means presets are disabled. |
0 |
| icons | dict |
Defines the icon mapping for this entity, used to generate icons.json on startup. Requires unique_id or a plain-string name so the entity has a stable identifier to key the mapping by. See icons for details. |
|
| translations | dict |
Defines per-language state text translations for this entity, keyed by language code, used to generate translations/<lang>.json on startup. Requires the same stable identifier as icons. See translations for details. |
|
| icon_template | template |
Defines a template for the icon of the sensor. | |
| entity_picture_template | template |
Defines a template for the entity picture of the sensor. | |
| availability_template | template |
Defines a template to get the available state of the component. If the template returns true, the device is available. If it returns any other value, the device is unavailable. If availability_template is not configured, the component will always be available. |
true |
| current_temperature_template | template |
Defines a template to get the current temperature. | |
| current_humidity_template | template |
Defines a template to get the current humidity. | |
| min_temp_template | template |
Defines a template to dynamically set the minimum allowed target temperature. | |
| max_temp_template | template |
Defines a template to dynamically set the maximum allowed target temperature. | |
| min_humidity_template | template |
Defines a template to dynamically set the minimum allowed target humidity. | |
| max_humidity_template | template |
Defines a template to dynamically set the maximum allowed target humidity. | |
| target_temperature_template | template |
Defines a template to get the target temperature of the climate device. | |
| target_temperature_low_template | template |
Defines a template to get the low target temperature of the climate device in heat_cool mode. |
|
| target_temperature_high_template | template |
Defines a template to get the high target temperature of the climate device in heat_cool mode. |
|
| precision_template | template |
Defines a template to dynamically set the desired precision for this device. Supported values are 0.1, 0.5, and 1. |
|
| temp_step_template | template |
Defines a template to dynamically set the temperature step size. | |
| presets_template | template |
Defines a template to get all preset values as a dictionary or JSON object. Please see example for the required data structure. | |
| target_humidity_template | template |
Defines a template to get the target humidity of the climate device. | |
| hvac_mode_template | template |
Defines a template to get the HVAC mode of the climate device. | |
| fan_mode_template | template |
Defines a template to get the fan mode of the climate device. | |
| preset_mode_template | template |
Defines a template to get the preset mode of the climate device. | |
| swing_mode_template | template |
Defines a template to get the swing mode of the climate device. | |
| hvac_action_template | template |
Defines a template to get the hvac action of the climate device. |
|
| set_temperature | action |
Defines an action to run when the climate device is given the set temperature command. Can use temperature, target_temp_high, target_temp_low, and hvac_mode variables. |
|
| set_humidity | action |
Defines an action to run when the climate device is given the set humidity command. Can use the humidity variable. |
|
| set_hvac_mode | action |
Defines an action to run when the climate device is given the set HVAC mode command. Can use the hvac_mode variable. |
|
| set_fan_mode | action |
Defines an action to run when the climate device is given the set fan mode command. Can use the fan_mode variable. |
|
| set_preset_mode | action |
Defines an action to run when the climate device is given the set preset mode command. Can use the preset_mode variable. |
|
| set_swing_mode | action |
Defines an action to run when the climate device is given the set swing mode command. Can use the swing_mode variable. |
|
| set_presets | action |
Defines an action to run when any activated preset feature value is changed. It should use the presets variable (all preset feature values) or the changed variable (only the values changed for the triggering update). See example for the variable format. |
|
| hvac_modes | list |
A list of supported HVAC modes. Needs to be a subset of the default climate device hvac_modes values: off, heat, cool, heat_cool, auto, dry, fan |
["off", "heat"] |
| preset_modes | list |
A list of supported preset modes. Custom preset modes are allowed. Default list of HA preset_modes. |
|
| fan_modes | list |
A list of supported fan modes. Custom fan modes are allowed. Default list of HA fan_modes. |
|
| swing_modes | list |
A list of supported swing modes. Custom swing modes are allowed. Default list of HA swing_modes. |
|
| min_temp | float |
Minimum temperature set point available. | 7 |
| max_temp | float |
Maximum temperature set point available. | 35 |
| min_humidity | float |
Minimum humidity set point available. | 30 |
| max_humidity | float |
Maximum humidity set point available. | 99 |
| precision | float |
The desired precision for this device. | 0.1 for Celsius and 1.0 for Fahrenheit. |
| temp_step | float |
Step size for the temperature set point. | 1 |
Home Assistant's icon translations let an integration assign a custom mdi icon per entity state and per state attribute value (e.g. hvac_mode, fan_mode, preset_mode, swing_mode), but they only work from a static icons.json file shipped with the integration. Since this integration's entities are entirely user-defined in YAML, icons.json can't be hand-written up front, so this file is generated automatically from your configuration instead.
To opt in, define icons on the entity, mirroring the shape of an icons.json entry: a top-level default/state map for the entity's own state (hvac_mode), plus a state_attributes map with default/state for fan_mode, preset_mode, and/or swing_mode. There's no separate translation-key option to set — the key used in icons.json is derived automatically for you, preferring unique_id (slugified) and falling back to a plain-string name (slugified) when unique_id isn't set. If neither gives a stable value (e.g. no unique_id and a templated name), the entity is skipped and keeps the default icons. On every Home Assistant startup, this integration collects the icons option from all climate_template entities and (re)writes custom_components/climate_template/icons.json from scratch. Entities that resolve to the same key (e.g. without unique_id and/or without or with same name) share the same icon mapping.
climate:
- platform: climate_template
name: AC
unique_id: ac # used as the icons.json key; falls back to a slug of `name` if omitted
icons:
default: mdi:thermostat
state:
off: mdi:power
cool: mdi:snowflake
heat: mdi:fire
state_attributes:
fan_mode:
default: mdi:fan
state:
auto: mdi:fan-auto
low: mdi:fan-speed-1
medium: mdi:fan-speed-2
high: mdi:fan-speed-3
preset_mode:
default: mdi:tune
state:
eco: mdi:leaf
boost: mdi:rocket-launch
swing_mode:
default: mdi:arrow-up-down
state:
auto: mdi:auto-mode
up: mdi:arrow-up
down: mdi:arrow-down
hvac_modes: ["off", "cool", "heat"]
fan_modes: ["auto", "low", "medium", "high"]
preset_modes: ["eco", "boost"]
swing_modes: ["auto", "up", "down"]Note
icons.json is only regenerated at Home Assistant startup, so restart Home Assistant after adding or changing icons configuration for the new icons to take effect.
Home Assistant entity translations let an integration display translated text for an entity's state and state attribute values (hvac_mode, fan_mode, preset_mode, swing_mode), but like icons, they only work from static translations/<lang>.json files shipped with the integration. Since this integration's entities are entirely user-defined in YAML, these files are generated automatically from your configuration, the same way icons.json is.
To opt in, define translations on the entity as a map of language code to an entry with an optional name (the entity's own display name) and/or state/state_attributes value-to-text maps for hvac_mode, fan_mode, preset_mode, and/or swing_mode — the same shape as icons, minus the default fallback (text has no generic fallback, only exact per-value translations). The entity's key is derived the same way as for icons (unique_id, falling back to a static name). On every Home Assistant startup, this integration collects the translations option from all climate_template entities and (re)writes custom_components/climate_template/translations/<lang>.json for every language referenced in your configuration.
climate:
- platform: climate_template
name: AC
unique_id: ac
translations:
en:
name: AC
state:
off: "Off"
cool: "Cooling"
heat: "Heating"
state_attributes:
fan_mode:
state:
auto: "Automatic"
low: "Low"
medium: "Medium"
high: "High"
cs:
name: "Klimatizace"
state:
off: "Vypnuto"
cool: "Chlazení"
heat: "Topení"
state_attributes:
fan_mode:
state:
auto: "Automaticky"
low: "Nízké"
medium: "Střední"
high: "Vysoké"
hvac_modes: ["off", "cool", "heat"]
fan_modes: ["auto", "low", "medium", "high"]Note
translations/<lang>.json files are only regenerated at Home Assistant startup, so restart Home Assistant after adding or changing translations configuration. Unlike icons.json, removing a language from your configuration does not delete its previously generated translations/<lang>.json file — delete it manually if needed.
Warning
Known limitation: Home Assistant preloads an integration's translations/<lang>.json in the background before this integration's own startup code runs, so there is a narrow window where Home Assistant can read the file before it has been regenerated for the current configuration. Once loaded, translations are cached in memory for the rest of that Home Assistant session and are not re-read even after we finish rewriting the file. In practice this only becomes visible right after the on-disk file was reset to a stale/placeholder state just before that particular restart (for example, immediately after updating this integration via HACS, which reinstalls the file shipped in the release). When it happens, entity/preset/state text falls back to the raw, untranslated value for that session only — icons are unaffected, since they are loaded on demand rather than preloaded at startup. Restarting Home Assistant a second time resolves it, since the file already holds the correct, current content by then.
climate:
- platform: climate_template
name: Bedroom Aircon
hvac_modes:
- "auto"
- "dry"
- "off"
- "cool"
- "fan_only"
min_temp: 16
max_temp: 30
# get current temp.
current_temperature_template: "{{ states('sensor.bedroom_temperature') }}"
# get current humidity.
current_humidity_template: "{{ states('sensor.bedroom_humidity') }}"
# swing mode switch for UI.
swing_mode_template: "{{ states('input_boolean.bedroom_swing_mode') }}"
# available based on esphome nodes' availability.
availability_template: "{{ is_state('binary_sensor.bedroom_node_status', 'on') }}"
# example action
set_hvac_mode:
# allows me to disable sending commands to aircon via UI.
- condition: state
entity_id: input_boolean.enable_aircon_controller
state: "on"
# send the climates current state to esphome.
- service: esphome.bedroom_node_aircon_state
data:
temperature: "{{ state_attr('climate.bedroom_aircon', 'temperature') | int }}"
operation_mode: "{{ states('climate.bedroom_aircon') }}"
fan_mode: "{{ state_attr('climate.bedroom_aircon', 'fan_mode') }}"
swing_mode: "{{ is_state_attr('climate.bedroom_aircon', 'swing_mode', 'on') }}"
light: "{{ is_state('light.bedroom_aircon_light', 'on') }}"
# could also send IR command via broadlink service calls etc.climate:
- platform: climate_template
# ...
set_hvac_mode:
# allows you to control an existing Home Assistant HVAC device
- service: climate.set_hvac_mode
data:
entity_id: climate.bedroom_ac_nottemplate
hvac_mode: "{{ states('climate.bedroom_ac_template') }}"Example of using presets modes to control boiler with multiple heating modes with independent temperatures
climate:
- platform: climate_template
name: "Heating Circuit 1"
unique_id: "climate_template_heating_hc1"
mode_action: "queued"
max_action: 3
# only heat mode is defined (no off mode), as boiler uses freeze 'protection' preset mode as off
hvac_modes:
- "heat"
# custom defined presets to match boiler mode
preset_modes:
- "automatic"
- "comfort"
- "reduced"
- "protection"
# active preset features set as bits: 1 (presets are editable via HA) + 2 (presets are saved and restore in HA) + 32 (preset allowed for target temperature) = 35
presets_features: 35
min_temp: 10
max_temp: 30
temp_step: 0.5
# get current boiler target temperature
current_temperature_template: "{{ states('sensor.boiler_hc1_room_temperature_actual_value') }}"
# just to init default hvac mode (only 'heat' mode is used)
hvac_mode_template: "heat"
# get current active preset mode if changed on boiler controller
preset_mode_template: "{{ states('select.boiler_hc1_operating_mode') | lower }}"
# updates integration presets temperatures if changed on boiler controller
presets_template: "{{ {'automatic': { 'target_temperature': states('number.boiler_hc1_room_temperature_comfort_setpoint')}, 'comfort': { 'target_temperature': states('number.boiler_hc1_room_temperature_comfort_setpoint')}, 'reduced': { 'target_temperature': states('number.boiler_hc1_room_temperature_reduced_setpoint')}, 'protection': { 'target_temperature': states('number.boiler_hc1_room_temperature_protection_setpoint')}} }}"
hvac_action_template: "{% if 'Heating' in states('sensor.boiler_hc1_status') %}heating{% else %}idle{% endif %}"
# updates boiler controller temperatures if changed via HomeAssistant
set_presets:
# set boiler comfort preset temperature
- if:
- condition: template
value_template: "{{ ( 'automatic' in changed and 'target_temperature' in changed.automatic ) or ( 'comfort' in changed and 'target_temperature' in comfort.automatic ) }}"
then:
- service: number.set_value
target:
entity_id: "number.boiler_hc1_room_temperature_comfort_setpoint"
data:
value: "{% if 'automatic' in changed and 'target_temperature' in changed.automatic %}{{ changed.automatic.target_temperature }}{% else %}{{ changed.automatic.target_temperature }}{% endif %}"
# set boiler reduced preset temperature
- if:
- condition: template
value_template: "{{ ( 'reduced' in changed and 'target_temperature' in reduced.automatic ) }}"
then:
- service: number.set_value
target:
entity_id: "number.boiler_hc1_room_temperature_reduced_setpoint"
data:
value: "{{ changed.reduced.target_temperature }}"
# set boiler freeze protection temperature
- if:
- condition: template
value_template: "{{ ( 'protection' in changed and 'target_temperature' in protection.automatic ) }}"
then:
- service: number.set_value
target:
entity_id: "number.boiler_hc1_room_temperature_protection_setpoint"
data:
value: "{{ changed.protection.target_temperature }}"
# set boiler current preset mode
set_preset_mode:
- service: select.select_option
target:
entity_id: select.boiler_hc1_operating_mode
data:
option: "{{ preset_mode | title }}"
climate:
- platform: climate_template
name: Better Aircon
# The better_aircon unique_id is assigned so we can call it later when setting the hvac modes, etc.
unique_id: better_aircon
hvac_modes:
- "off"
- "cool"
- "heat"
- "fan_only"
- "dry"
fan_modes:
- "auto"
- "low"
- "medium"
- "high"
min_temp: 16
max_temp: 30
# In this example, sensor.average_house_temperature and sensor.average_house_humidity are existing in my home
current_temperature_template: "{{ states('sensor.average_house_temperature') }}"
# The climate.ac sensor is the existing AC sensor we are adding sensors to
target_temperature_template: "{{ state_attr('climate.ac', 'temperature') | int }}"
current_humidity_template: "{{ states('sensor.average_house_humidity') }}"
hvac_mode_template: "{{ states('climate.ac') }}"
fan_mode_template: "{{ state_attr('climate.ac', 'fan_mode') }}"
set_temperature:
- service: climate.set_temperature
data:
entity_id: climate.ac
temperature: "{{ state_attr('climate.better_aircon', 'temperature') | int }}"
set_fan_mode:
- service: climate.set_fan_mode
data:
entity_id: climate.ac
fan_mode: "{{ state_attr('climate.better_aircon', 'fan_mode') }}"
set_hvac_mode:
- service: climate.set_hvac_mode
data:
entity_id: climate.ac
hvac_mode: "{{ states('climate.better_aircon') }}"- Merge multiple components into one climate device (just like any template platform).
- Control optimistic climate devices such as IR aircons via service calls.