Skip to content

Commit c9aad57

Browse files
committed
Reframe optimistic, lambdas, and actions in docs
1 parent dbe8211 commit c9aad57

File tree

1 file changed

+114
-119
lines changed

1 file changed

+114
-119
lines changed

src/content/docs/components/climate/template.mdx

Lines changed: 114 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,32 @@ title: "Template Climate"
55

66
import 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
1727
climate:
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
14555
globals:
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
16272
climate:
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

Comments
 (0)