Examples¶
I originally wrote a plugin for my air conditioner implementation using esphome if interested, you can source esphome-mqtt-climate the following is a configuration example for my air conditioner
type: custom:mini-climate
entity: climate.dahatsu
name: Кондиционер
fan_mode:
source:
auto: Авто
low: Слабый
medium: Средний
high: Сильный
# for my implementation fan_modes_al is an array of available fan modes of the selected hvac mode
__filter: >
(source, state, entity) => entity.attributes
.fan_modes_al.map(fan_mode => source.find(s => s.id === fan_mode))
.filter(fan_mode => fan_mode)
buttons:
swing_mode:
type: dropdown
icon: mdi:approximately-equal
state:
attribute: swing_mode
# the drop-down list will remain active until swing_mode is off
active: state => state !== 'off'
source:
'off': Выкл
horizontal: Вкл
change_action: >
(selected, state, entity) => this.call_service('climate', 'set_swing_mode', { entity_id: entity.entity_id, swing_mode: selected })
# turbo air conditioning button
turbo:
icon: mdi:weather-hurricane
# control topic
topic: 'dahatsu/turbo/set'
state:
attribute: turbo
# for my device, the turbo attribute returns boolean type, convert it to on or off
mapper: "(state, entity) => state ? 'on': 'off'"
# turbo button is not available for all modes, block it when it is not available
disabled: (state, entity) => !entity.attributes.turbo_al
# when you click on the button, send the event to mqtt
toggle_action: >
(state) => this.call_service('mqtt', 'publish', { payload: this.toggle_state(state), topic: this.topic, retain: false, qos: 1 })
# eco button configuration is the same as for turbo button
eco:
icon: mdi:leaf
topic: 'dahatsu/eco/set'
state:
attribute: eco
mapper: "(state, entity) => state ? 'on': 'off'"
disabled: (state, entity) => !entity.attributes.eco_al
toggle_action: >
(state) => this.call_service('mqtt', 'publish', { payload: this.toggle_state(state), topic: this.topic, retain: false, qos: 1 })
# health button configuration is the same as for turbo button
health:
icon: mdi:emoticon-happy-outline
topic: 'dahatsu/health/set'
state:
attribute: health
mapper: "(state, entity) => state ? 'on': 'off'"
disabled: (state, entity) => !entity.attributes.health_al
toggle_action: >
(state) => this.call_service('mqtt', 'publish', { payload: this.toggle_state(state), topic: this.topic, retain: false, qos: 1 })
# power off button
power_switch:
icon: mdi:power-plug
state:
entity: switch.air_conditioner_kitchen_switch_l1
indicators:
# humidity indicator
humidity:
icon: mdi:water
unit: '%'
round: 1
source:
entity: sensor.sensor_temp_hum_pre_kitchen_humidity
# power consumption indicator
power_consumption:
icon: mdi:flash
unit: 'W'
round: 1
source:
entity: sensor.dahatsu_power
# power indicator
power:
icon: mdi:power-plug
source:
entity: switch.air_conditioner_kitchen_switch_l1
values:
'on': 'вкл'
'off': 'выкл'
# localization of values
mapper: value => this.source.values[value]
Recipes¶
Five things this tracker has been asked for more than once, with the answer and what it looks like.
Each is also a card in the bench's manifest and an assertion in
test/e2e/answers.test.mjs, so an answer that stops being true fails a run
rather than sitting here reading well.
A card with nothing but the temperature¶
Everything that can be hidden, hidden - the icon, the name, the fan mode, the secondary info line and the toggle. What is left is the temperature and the buttons that change it.
type: custom:mini-climate
entity: climate.bedroom
name: ' '
hide_icon: true
toggle:
hide: true
fan_mode:
hide: true
secondary_info:
hide: '() => true'

An indicator with an icon and no value¶
There is no option for this, and none is needed: the value carries a style,
and a style can hide it. The unit goes with it.
indicators:
window:
source:
entity: binary_sensor.bedroom_window
icon:
template: "(value) => (value === 'on' ? 'mdi:window-open' : 'mdi:window-closed')"
style: "(value) => (value === 'on' ? { color: 'orange' } : {})"
value:
style: "() => ({ display: 'none' })"
![]()
A shortened value¶
A mapper runs on every value the indicator reads, so anything that is a
string can be cut, rounded or relabelled on the way to the card.
indicators:
clock:
icon: mdi:clock-outline
source:
entity: sensor.bedroom_clock
mapper: "value => (typeof value === 'string' ? value.slice(0, 5) : value)"

The mode icon coloured by what the unit is doing¶
hvac_action is what the unit is doing now - heating, cooling, idle - as
against state, which is what it was asked to do. The style template is handed
the entity, so both are available.
hvac_mode:
style: >
(value, entity) => ({
color: entity.attributes.hvac_action === 'cooling'
? 'blue'
: entity.attributes.hvac_action === 'heating'
? 'red'
: 'grey',
})
![]()
An indicator coloured by the mode¶
The third argument every template gets is the climate entity, whatever
entity the indicator itself is reading. That is what to reach for here: an
indicator on a floor sensor has no hvac_action of its own.
indicators:
floor:
source:
entity: binary_sensor.floor_demand
unit: '%'
icon:
template: "() => 'mdi:heating-coil'"
style: >
(value, entity, climate_entity) => ({
color: climate_entity.state === 'cool' ? 'blue' : 'red',
})

A row of preset buttons¶
One climate entity holds one preset at a time, so a row of preset buttons
is a set of switches rather than a list. Each button maps the attribute to
on/off and sends the chosen value on press; active decides which one is lit.
type: custom:mini-climate
entity: climate.pass_actuator_3
buttons:
eco:
icon: mdi:leaf
state:
attribute: preset_mode
mapper: state => state === 'eco' ? 'on' : 'off'
active: state => state === 'on'
toggle_action: >
(state, entity) => this.call_service('climate', 'set_preset_mode', { entity_id: entity.entity_id, preset_mode: state === 'on' ? 'none' : 'eco' })
boost:
icon: mdi:weather-hurricane
state:
attribute: preset_mode
mapper: state => state === 'boost' ? 'on' : 'off'
active: state => state === 'on'
toggle_action: >
(state, entity) => this.call_service('climate', 'set_preset_mode', { entity_id: entity.entity_id, preset_mode: state === 'on' ? 'none' : 'boost' })
Two things worth knowing:
- the buttons sit behind the toggle, like every other button;
- after pressing one there is a moment where no button is lit - the old preset goes out before the new one comes in. On a slow connection that is visible; it settles.
To show the selected preset's name as well, add an indicator reading
attribute: preset_mode - that is A shortened value's
values + mapper, applied to preset_mode.
