@@ -5,35 +5,32 @@ title: "Template Climate"
55
66import APIRef from ' @components/APIRef.astro' ;
77
8- The ` template ` climate platform allows you to create a climate entity backed by lambda expressions
9- and automation actions. It is useful for wrapping custom UART/I²C climate controllers, integrating
10- hardware that lacks a dedicated ESPHome component, or prototyping climate integrations.
8+ The ` template ` climate platform lets you create a climate entity backed by lambda expressions
9+ and automation actions. It is useful for wrapping custom UART/I²C climate controllers,
10+ integrating hardware that lacks a dedicated ESPHome component, or prototyping climate
11+ integrations.
1112
12- Once defined, it will automatically appear in Home Assistant as a climate entity and can be
13- controlled through the frontend.
13+ ** Read lambdas** (` current_temperature ` , ` mode ` , ` target_temperature ` , etc.) are polled each
14+ ` loop() ` iteration to populate the entity with the device's current state. ** Set actions**
15+ (` set_mode_action ` , ` set_target_temperature_action ` , etc.) are fired when the frontend or an
16+ automation sends a command to the device.
17+
18+ Once defined, the entity will automatically appear in Home Assistant and can be controlled
19+ through the frontend.
20+
21+ ## Simple example
22+
23+ A minimal setup with no read lambdas. The entity state is updated immediately when set actions
24+ fire (` optimistic: true ` , the default).
1425
1526``` yaml
16- # Example configuration entry
1727climate :
1828 - platform : template
1929 name : " Living Room Climate"
20- current_temperature : !lambda "return id(my_temperature_sensor).state;"
2130 supported_modes :
2231 - " OFF"
2332 - HEAT
2433 - COOL
25- - FAN_ONLY
26- supported_fan_modes :
27- - AUTO
28- - LOW
29- - HIGH
30- supported_swing_modes :
31- - " OFF"
32- - VERTICAL
33- supported_presets :
34- - NONE
35- - ECO
36- - AWAY
3734 set_mode_action :
3835 - logger.log :
3936 format : " Mode: %d"
@@ -42,133 +39,46 @@ climate:
4239 - logger.log :
4340 format : " Target temperature: %.1f"
4441 args : ["x"]
45- set_fan_mode_action :
46- - logger.log :
47- format : " Fan mode: %d"
48- args : ["(int) x"]
49- set_swing_mode_action :
50- - logger.log :
51- format : " Swing mode: %d"
52- args : ["(int) x"]
53- set_preset_action :
54- - logger.log :
55- format : " Preset: %d"
56- args : ["(int) x"]
57- optimistic : true
5842 visual :
43+ min_temperature : 16.0
44+ max_temperature : 30.0
5945 temperature_step : 0.5
6046` ` `
6147
62- ## Configuration variables
63-
64- - **current_temperature** (*Optional*, [lambda](/automations/templates#config-lambda)):
65- Lambda evaluated repeatedly to get the current (measured) temperature. Return a ` float` value, or return
66- ` {}` to leave the current temperature unchanged. When this lambda is provided, the climate entity will
67- report a current temperature to the frontend.
68-
69- - **target_temperature** (*Optional*, [lambda](/automations/templates#config-lambda)):
70- Lambda evaluated repeatedly to get the target (setpoint) temperature. Return a `float` value, or return
71- ` {}` to leave the target temperature unchanged. Use this in non-optimistic mode when the target temperature
72- is owned by an external device.
73-
74- - **mode** (*Optional*, [lambda](/automations/templates#config-lambda)):
75- Lambda evaluated repeatedly to get the current operating mode. Return a `ClimateMode` value
76- (e.g. `climate::CLIMATE_MODE_HEAT`), or return `{}` to leave the mode unchanged.
77-
78- - **fan_mode** (*Optional*, [lambda](/automations/templates#config-lambda)):
79- Lambda evaluated repeatedly to get the current fan mode. Return a `ClimateFanMode` value
80- (e.g. `climate::CLIMATE_FAN_AUTO`), or return `{}` to leave the fan mode unchanged.
81-
82- - **swing_mode** (*Optional*, [lambda](/automations/templates#config-lambda)):
83- Lambda evaluated repeatedly to get the current swing mode. Return a `ClimateSwingMode` value
84- (e.g. `climate::CLIMATE_SWING_OFF`), or return `{}` to leave the swing mode unchanged.
85-
86- - **preset** (*Optional*, [lambda](/automations/templates#config-lambda)):
87- Lambda evaluated repeatedly to get the current preset. Return a `ClimatePreset` value
88- (e.g. `climate::CLIMATE_PRESET_ECO`), or return `{}` to leave the preset unchanged.
89-
90- - **optimistic** (*Optional*, boolean): Whether to operate in optimistic mode. When enabled, any command
91- sent to the template climate will immediately update the reported state without waiting for the external
92- device to confirm it. Defaults to `true`.
93-
94- - **supported_modes** (*Optional*, list): Static list of operating modes to expose to the frontend.
95- Valid values : ` OFF` , `HEAT`, `COOL`, `AUTO`, `HEAT_COOL`, `FAN_ONLY`, `DRY`.
96-
97- > [!NOTE]
98- > The list of `supported_modes` is static and evaluated at startup. It cannot be changed dynamically.
99-
100- - **supported_fan_modes** (*Optional*, list): Static list of fan modes to expose to the frontend.
101- Valid values : ` ON` , `OFF`, `AUTO`, `LOW`, `MEDIUM`, `HIGH`, `MIDDLE`, `FOCUS`, `DIFFUSE`, `QUIET`.
102-
103- - **supported_swing_modes** (*Optional*, list): Static list of swing modes to expose to the frontend.
104- Valid values : ` OFF` , `BOTH`, `VERTICAL`, `HORIZONTAL`.
105-
106- - **supported_presets** (*Optional*, list): Static list of presets to expose to the frontend.
107- Valid values : ` NONE` , `ECO`, `AWAY`, `BOOST`, `COMFORT`, `HOME`, `SLEEP`, `ACTIVITY`.
108-
109- - **set_mode_action** (*Optional*, [Action](/automations/actions#all-actions)):
110- Action executed when a mode change command is received. The requested mode is available as
111- the variable `x` of type `ClimateMode`.
48+ ## External device example
11249
113- - **set_target_temperature_action** (*Optional*, [Action](/automations/actions#all-actions)):
114- Action executed when a target temperature change command is received. The requested temperature
115- is available as the variable `x` of type `float`.
116-
117- - **set_fan_mode_action** (*Optional*, [Action](/automations/actions#all-actions)):
118- Action executed when a fan mode change command is received. The requested fan mode is available
119- as the variable `x` of type `ClimateFanMode`.
120-
121- - **set_swing_mode_action** (*Optional*, [Action](/automations/actions#all-actions)):
122- Action executed when a swing mode change command is received. The requested swing mode is
123- available as the variable `x` of type `ClimateSwingMode`.
124-
125- - **set_preset_action** (*Optional*, [Action](/automations/actions#all-actions)):
126- Action executed when a preset change command is received. The requested preset is available as
127- the variable `x` of type `ClimatePreset`.
128-
129- - All other options from [Climate](/components/climate#config-climate).
130-
131- > [!NOTE]
132- > Climate state (mode, target temperature, fan mode, swing mode, and preset) is automatically
133- > persisted to flash and restored on reboot via the standard ESPHome climate restore mechanism.
134-
135- # # Non-optimistic mode example
136-
137- In non-optimistic mode the external device owns the state. ESPHome reads it back via lambdas and
138- only fires the action hooks when commands arrive from the frontend or automations.
139-
140- The example below uses globals to simulate an external device that owns its own state. In a real
141- scenario, the `set_*_action` blocks would send commands to the device (e.g. over UART or I²C), and
142- the state lambdas would read back the current device state.
50+ A full example showing both read lambdas and set actions. The read lambdas poll the device
51+ state each loop; the set actions send new settings to the device. In a real scenario the actions
52+ would write over UART or I²C. The ` globals` here simulate that external device.
14353
14454` ` ` yaml
14555globals:
14656 - id: ext_mode
14757 type: int
148- initial_value: "0" # CLIMATE_MODE_OFF
58+ initial_value: "0" # CLIMATE_MODE_OFF
14959 - id: ext_target_temp
15060 type: float
15161 initial_value: "21.0"
15262 - id: ext_fan_mode
15363 type: int
154- initial_value: "2" # CLIMATE_FAN_AUTO
64+ initial_value: "2" # CLIMATE_FAN_AUTO
15565 - id: ext_swing_mode
15666 type: int
157- initial_value: "0" # CLIMATE_SWING_OFF
67+ initial_value: "0" # CLIMATE_SWING_OFF
15868 - id: ext_preset
15969 type: int
160- initial_value: "5" # CLIMATE_PRESET_ECO
70+ initial_value: "5" # CLIMATE_PRESET_ECO
16171
16272climate:
16373 - platform: template
16474 name: "External Heatpump"
165- optimistic: false
166- current_temperature: !lambda "return 22.5f;"
75+ current_temperature: !lambda "return id(temp_sensor).state;"
16776 target_temperature: !lambda "return id(ext_target_temp);"
16877 mode: !lambda "return static_cast<climate::ClimateMode>(id(ext_mode));"
16978 fan_mode: !lambda "return static_cast<climate::ClimateFanMode>(id(ext_fan_mode));"
17079 swing_mode: !lambda "return static_cast<climate::ClimateSwingMode>(id(ext_swing_mode));"
17180 preset: !lambda "return static_cast<climate::ClimatePreset>(id(ext_preset));"
81+ optimistic: true
17282 supported_modes:
17383 - "OFF"
17484 - HEAT
@@ -201,8 +111,93 @@ climate:
201111 temperature_step: 0.5
202112` ` `
203113
114+ # # Configuration variables
115+
116+ - **current_temperature** (*Optional*, [lambda](/automations/templates#config-lambda)):
117+ Lambda evaluated on every loop to get the measured (ambient) temperature. Return a `float`
118+ value, or `{}` to leave the current temperature unchanged.
119+
120+ - **target_temperature** (*Optional*, [lambda](/automations/templates#config-lambda)):
121+ Lambda evaluated on every loop to read the target (setpoint) temperature from the device.
122+ Return a `float` value, or `{}` to leave the target temperature unchanged.
123+
124+ - **mode** (*Optional*, [lambda](/automations/templates#config-lambda)):
125+ Lambda evaluated on every loop to read the current operating mode from the device. Return a
126+ ` ClimateMode` value (e.g. `climate::CLIMATE_MODE_HEAT`), or `{}` to leave the mode
127+ unchanged.
128+
129+ - **fan_mode** (*Optional*, [lambda](/automations/templates#config-lambda)):
130+ Lambda evaluated on every loop to read the current fan mode from the device. Return a
131+ ` ClimateFanMode` value (e.g. `climate::CLIMATE_FAN_AUTO`), or `{}` to leave the fan mode
132+ unchanged.
133+
134+ - **swing_mode** (*Optional*, [lambda](/automations/templates#config-lambda)):
135+ Lambda evaluated on every loop to read the current swing mode from the device. Return a
136+ ` ClimateSwingMode` value (e.g. `climate::CLIMATE_SWING_OFF`), or `{}` to leave the swing
137+ mode unchanged.
138+
139+ - **preset** (*Optional*, [lambda](/automations/templates#config-lambda)):
140+ Lambda evaluated on every loop to read the current preset from the device. Return a
141+ ` ClimatePreset` value (e.g. `climate::CLIMATE_PRESET_ECO`), or `{}` to leave the preset
142+ unchanged.
143+
144+ - **optimistic** (*Optional*, boolean): Controls whether the entity state is updated immediately
145+ after a set action fires (`true`, default) or only after the next read-lambda poll reflects the
146+ device's actual state (`false`).
147+
148+ - `true` (default) : Entity state updates immediately after a set action so the UI shows the
149+ new value right away. If the device does not accept the command, the read lambdas will
150+ correct it on the next loop.
151+ - `false` : Entity state does not update after a set action. The UI only updates when the
152+ read lambdas detect a change in the device state.
153+
154+ When no read lambdas are configured, entity state always updates immediately (there is nothing
155+ polling the device).
156+
157+ - **supported_modes** (*Optional*, list): List of operating modes to expose to the frontend.
158+ Valid values : ` OFF` , `HEAT`, `COOL`, `AUTO`, `HEAT_COOL`, `FAN_ONLY`, `DRY`.
159+
160+ > [!NOTE]
161+ > `supported_modes` is evaluated at compile time. It cannot be changed at runtime.
162+
163+ - **supported_fan_modes** (*Optional*, list): List of fan modes to expose to the frontend.
164+ Valid values : ` ON` , `OFF`, `AUTO`, `LOW`, `MEDIUM`, `HIGH`, `MIDDLE`, `FOCUS`, `DIFFUSE`,
165+ ` QUIET` .
166+
167+ - **supported_swing_modes** (*Optional*, list): List of swing modes to expose to the frontend.
168+ Valid values : ` OFF` , `BOTH`, `VERTICAL`, `HORIZONTAL`.
169+
170+ - **supported_presets** (*Optional*, list): List of presets to expose to the frontend.
171+ Valid values : ` NONE` , `ECO`, `AWAY`, `BOOST`, `COMFORT`, `HOME`, `SLEEP`, `ACTIVITY`.
172+
173+ - **set_mode_action** (*Optional*, [Action](/automations/actions#all-actions)):
174+ Action executed when a mode command is received. The requested mode is available as
175+ ` x` of type `ClimateMode`.
176+
177+ - **set_target_temperature_action** (*Optional*, [Action](/automations/actions#all-actions)):
178+ Action executed when a target temperature command is received. The requested temperature is
179+ available as `x` of type `float`.
180+
181+ - **set_fan_mode_action** (*Optional*, [Action](/automations/actions#all-actions)):
182+ Action executed when a fan mode command is received. The requested fan mode is available as
183+ ` x` of type `ClimateFanMode`.
184+
185+ - **set_swing_mode_action** (*Optional*, [Action](/automations/actions#all-actions)):
186+ Action executed when a swing mode command is received. The requested swing mode is available
187+ as `x` of type `ClimateSwingMode`.
188+
189+ - **set_preset_action** (*Optional*, [Action](/automations/actions#all-actions)):
190+ Action executed when a preset command is received. The requested preset is available as
191+ ` x` of type `ClimatePreset`.
192+
193+ - All other options from [Climate](/components/climate#config-climate).
194+
195+ > [!NOTE]
196+ > Climate state (mode, target temperature, fan mode, swing mode, and preset) is automatically
197+ > persisted to flash and restored on reboot via the standard ESPHome climate restore mechanism.
198+
204199# # See Also
205200
206201- [Climate Component](/components/climate/)
207- - [Automation ](/automations)
202+ - [Automations and Templates ](/automations)
208203- <APIRef text="template_climate.h" path="template/climate/template_climate.h" />
0 commit comments