Files
hassos_config/esphome/widgets/air_conditioner/air_conditioner_widget.yaml
2026-03-26 12:10:21 +01:00

1823 lines
63 KiB
YAML

# https://esphome.io/components/climate/thermostat.html
substitutions:
air_conditioner_entity: "climate.hvac"
air_conditioner_icon: "\U0000e93b"
temperature_icon: "\U0000e939"
heat_icon: "\U000F0238"
cool_icon: "\U000F0717"
fan_icon: "\U000F0210"
auto_icon: "\U000F1B18"
off_icon: "\U000F0425"
globals:
- id: air_conditioner_temp_hum_mode
type: bool
initial_value: "false"
restore_value: false
sensor:
# Air conditioner target temperature
- platform: homeassistant
id: air_conditioner_sensor_target_temp
entity_id: "${air_conditioner_entity}"
attribute: temperature
on_value:
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
value: !lambda return x;
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text: !lambda |-
static char buf[10];
int whole_part = static_cast<int>(id(air_conditioner_sensor_target_temp).state);
snprintf(buf, 10, "%d", whole_part);
return buf;
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text: !lambda |-
static char buf[10];
int whole_part = static_cast<int>(id(air_conditioner_sensor_target_temp).state);
int fractional_part = static_cast<int>((id(air_conditioner_sensor_target_temp).state - whole_part) * 10);
snprintf(buf, 10, ".%01d", fractional_part);
return buf;
- if:
condition:
lambda: 'return id(air_conditioner_sensor_state).state == "cool";'
then:
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < x;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_blue
- lvgl.label.update:
id: ac_status
text_color: color_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_blue
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_light_blue
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_state).state == "heat";'
then:
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < x;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_deep_orange
- lvgl.label.update:
id: ac_status
text_color: color_deep_orange
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_deep_orange
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_deep_orange
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_deep_orange
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_orange
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_state).state == "dry";'
then:
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < x;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_yellow
- lvgl.label.update:
id: ac_status
text_color: color_yellow
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_yellow
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_yellow
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_yellow
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_light_yellow
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_state).state == "auto";'
then:
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < x;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_light_green
- lvgl.label.update:
id: ac_status
text_color: color_light_green
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_light_green
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_light_green
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_light_green
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_green
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_state).state == "fan_only";'
then:
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < x;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_mint
- lvgl.label.update:
id: ac_status
text_color: color_mint
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_mint
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_mint
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_mint
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_light_mint
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_state).state == "off";'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_steel_blue
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
# Air conditioner current temperature
- platform: homeassistant
id: air_conditioner_sensor_current_temp
entity_id: "${air_conditioner_entity}"
attribute: current_temperature
on_value:
- delay: 500ms
- lvgl.label.update:
id: air_conditioner_target_temperature_value
text: !lambda |-
char buf[8];
sprintf(buf, "%.1f", x);
return std::string(buf);
- lvgl.arc.update:
id: air_conditioner_arc_current_temp
value: !lambda return x;
# Air conditioner target humidity
- platform: homeassistant
id: air_conditioner_sensor_target_hum
entity_id: "${air_conditioner_entity}"
attribute: humidity
on_value:
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_humidity
value: !lambda return x;
- lvgl.label.update:
id: air_conditioner_target_humidity_whole
text: !lambda |-
static char buf[10];
int whole_part = static_cast<int>(id(air_conditioner_sensor_target_hum).state);
snprintf(buf, 10, "%d", whole_part);
return buf;
- lvgl.label.update:
id: air_conditioner_target_humidity_fraction
text: !lambda |-
static char buf[10];
int whole_part = static_cast<int>(id(air_conditioner_sensor_target_hum).state);
int fractional_part = static_cast<int>((id(air_conditioner_sensor_target_hum).state - whole_part) * 10);
snprintf(buf, 10, ".%01d", fractional_part);
return buf;
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_hum).state < x;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_humidity
indicator:
arc_color: color_dark_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_whole
text_color: color_dark_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_fraction
text_color: color_dark_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_measurement
text_color: color_dark_blue
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_humidity
indicator:
arc_color: color_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_measurement
text_color: color_steel_blue
# Air conditioner current humidity
- platform: homeassistant
id: air_conditioner_sensor_current_hum
entity_id: "${air_conditioner_entity}"
attribute: current_humidity
on_value:
- delay: 500ms
- lvgl.label.update:
id: air_conditioner_target_humidity_value
text: !lambda |-
char buf[8];
sprintf(buf, "%.1f", x);
return std::string(buf);
- lvgl.arc.update:
id: air_conditioner_arc_current_hum
value: !lambda return x;
text_sensor:
# Air conditioner state
- platform: homeassistant
id: air_conditioner_sensor_state
entity_id: "${air_conditioner_entity}"
on_value:
- if:
condition:
lambda: 'return x == "cool";'
then:
- lvgl.label.update:
id: air_conditioner_auto_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_heat_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_cool_mode_label
text_color: color_blue
- lvgl.label.update:
id: air_conditioner_dry_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_fan_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_off_mode_label
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < id(air_conditioner_sensor_target_temp).state;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_blue
- lvgl.label.update:
id: ac_status
text_color: color_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_blue
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_light_blue
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return x == "heat";'
then:
- lvgl.label.update:
id: air_conditioner_auto_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_heat_mode_label
text_color: color_deep_orange
- lvgl.label.update:
id: air_conditioner_cool_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_dry_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_fan_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_off_mode_label
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < id(air_conditioner_sensor_target_temp).state;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_deep_orange
- lvgl.label.update:
id: ac_status
text_color: color_deep_orange
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_deep_orange
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_deep_orange
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_deep_orange
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_orange
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return x == "dry";'
then:
- lvgl.label.update:
id: air_conditioner_auto_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_heat_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_cool_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_dry_mode_label
text_color: color_yellow
- lvgl.label.update:
id: air_conditioner_fan_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_off_mode_label
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < id(air_conditioner_sensor_target_temp).state;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_yellow
- lvgl.label.update:
id: ac_status
text_color: color_yellow
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_yellow
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_yellow
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_yellow
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_light_yellow
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return x == "auto";'
then:
- lvgl.label.update:
id: air_conditioner_auto_mode_label
text_color: color_green
- lvgl.label.update:
id: air_conditioner_heat_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_cool_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_dry_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_fan_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_off_mode_label
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < id(air_conditioner_sensor_target_temp).state;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_light_green
- lvgl.label.update:
id: ac_status
text_color: color_light_green
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_light_green
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_light_green
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_light_green
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_green
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return x == "fan_only";'
then:
- lvgl.label.update:
id: air_conditioner_auto_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_heat_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_cool_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_dry_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_fan_mode_label
text_color: color_mint
- lvgl.label.update:
id: air_conditioner_off_mode_label
text_color: color_steel_blue
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_temp).state < id(air_conditioner_sensor_target_temp).state;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_mint
- lvgl.label.update:
id: ac_status
text_color: color_mint
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_mint
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_mint
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_mint
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_light_mint
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
- if:
condition:
lambda: 'return x == "off";'
then:
- lvgl.label.update:
id: air_conditioner_auto_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_heat_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_cool_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_dry_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_fan_mode_label
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_off_mode_label
text_color: color_steel_blue
- lvgl.arc.update:
id: air_conditioner_arc_main_temperature
indicator:
arc_color: color_steel_blue
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_temperature_measurement
text_color: color_steel_blue
# Air conditioner name
- platform: homeassistant
id: air_conditioner_sensor_name
entity_id: "${air_conditioner_entity}"
attribute: friendly_name
on_value:
- lvgl.label.update:
id: air_conditioner_name_label
text: !lambda return x;
# Air conditioner hvac action
- platform: homeassistant
id: air_conditioner_sensor_hvac_action
entity_id: "${air_conditioner_entity}"
attribute: hvac_action
on_value:
- script.execute:
id: air_conditioner_get_and_set_translated_state
state_str: !lambda 'return id(air_conditioner_sensor_hvac_action).state;'
lvgl:
pages:
- id: air_conditioner_page
bg_color: color_slate_blue_gray
widgets:
# State
- obj:
id: air_conditioner_state
x: 20
y: 20
width: 400
height: 60
align: TOP_LEFT
pad_all: 0
bg_color: color_steel_blue
bg_opa: 20%
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: air_conditioner_state_label
x: 20
align: LEFT_MID
text_font: nunito_18
text_color: color_misty_blue
text: " "
# Controls
- obj:
id: air_conditioner_controls_hvac_modes
x: 20
y: 100
width: 360
height: 160
align: TOP_LEFT
pad_all: 0
bg_color: color_steel_blue
bg_opa: 20%
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
# AUTO
- obj:
id: air_conditioner_auto_mode_btn
x: 10
y: 10
width: 60
height: 60
align: top_left
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- label:
id: air_conditioner_auto_mode_label
align: center
text_font: mdi_icons_28
text_color: color_misty_blue
text: "${auto_icon}"
on_press:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: "${air_conditioner_entity}"
hvac_mode: auto
# HEAT
- obj:
id: air_conditioner_heat_mode_btn
x: 80
y: 10
width: 60
height: 60
align: top_left
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- label:
id: air_conditioner_heat_mode_label
align: center
text_font: mdi_icons_28
text_color: color_misty_blue
text: "${heat_icon}"
on_press:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: "${air_conditioner_entity}"
hvac_mode: heat
# COOL
- obj:
id: air_conditioner_cool_mode_btn
x: 150
y: 10
width: 60
height: 60
align: top_left
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- label:
id: air_conditioner_cool_mode_label
align: center
text_font: mdi_icons_28
text_color: color_misty_blue
text: "${cool_icon}"
on_press:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: "${air_conditioner_entity}"
hvac_mode: cool
# DRY
- obj:
id: air_conditioner_dry_mode_btn
x: 10
y: 90
width: 60
height: 60
align: top_left
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- label:
id: air_conditioner_dry_mode_label
align: center
text_font: icons_28
text_color: color_misty_blue
text: "${humidity_icon}"
on_press:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: "${air_conditioner_entity}"
hvac_mode: dry
# FAN
- obj:
id: air_conditioner_fan_mode_btn
x: 80
y: 90
width: 60
height: 60
align: top_left
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- label:
id: air_conditioner_fan_mode_label
align: center
text_font: mdi_icons_28
text_color: color_misty_blue
text: "${fan_icon}"
on_press:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: "${air_conditioner_entity}"
hvac_mode: fan_only
# OFF
- obj:
id: air_conditioner_off_mode_btn
x: 150
y: 90
width: 60
height: 60
align: top_left
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- label:
id: air_conditioner_off_mode_label
align: center
text_font: mdi_icons_28
text_color: color_misty_blue
text: "${off_icon}"
on_press:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: "${air_conditioner_entity}"
hvac_mode: "off"
- obj:
id: air_conditioner_controls
x: 20
y: 280
width: 360
height: 100
align: TOP_LEFT
pad_all: 0
bg_opa: transp
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
# Temperature or humidity controls (plus)
- obj:
x: 20
width: 90
height: 90
align: left_mid
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 70
height: 70
align: center
clickable: true
radius: 50
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 8
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
then:
- if:
condition:
lambda: 'return id(air_conditioner_temp_hum_mode);'
then:
- lambda: |-
auto current_hum = id(air_conditioner_sensor_target_hum).state;
auto new_hum = current_hum + 1;
if (new_hum > 99) {new_hum = 99;}
id(air_conditioner_sensor_target_hum).publish_state(new_hum);
- homeassistant.action:
action: climate.set_humidity
data:
entity_id: "${air_conditioner_entity}"
humidity: !lambda return static_cast<int>(id(air_conditioner_sensor_target_hum).state);
else:
- lambda: |-
auto current_temp = id(air_conditioner_sensor_target_temp).state;
auto new_temp = current_temp + 0.5;
if (new_temp > 35.0) {new_temp = 35.0;}
id(air_conditioner_sensor_target_temp).publish_state(new_temp);
- homeassistant.action:
action: climate.set_temperature
data:
entity_id: "${air_conditioner_entity}"
temperature: !lambda 'return id(air_conditioner_sensor_target_temp).state;'
- obj:
width: 60
height: 60
align: center
clickable: false
radius: 45
pad_all: 0
bg_opa: transp
border_opa: transp
shadow_width: 4
shadow_color: 0xFFFFFF
shadow_ofs_x: -4
shadow_ofs_y: -2
shadow_opa: 30%
- obj:
width: 65
height: 65
pad_all: 0
align: center
clickable: false
radius: 50
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
y: -2
align: center
text_font: nunito_48
text_color: color_misty_blue
text: "+"
# Temperature or humidity controls (minus)
- obj:
x: 130
width: 90
height: 90
align: left_mid
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 70
height: 70
align: center
clickable: true
radius: 50
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 8
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
then:
- if:
condition:
lambda: 'return id(air_conditioner_temp_hum_mode);'
then:
- lambda: |-
auto current_hum = id(air_conditioner_sensor_target_hum).state;
auto new_hum = current_hum - 1;
if (new_hum < 30) {new_hum = 30;}
id(air_conditioner_sensor_target_hum).publish_state(new_hum);
- homeassistant.action:
action: climate.set_humidity
data:
entity_id: "${air_conditioner_entity}"
humidity: !lambda return static_cast<int>(id(air_conditioner_sensor_target_hum).state);
else:
- lambda: |-
auto current_temp = id(air_conditioner_sensor_target_temp).state;
auto new_temp = current_temp - 0.5;
if (new_temp < 7.0) {new_temp = 7.0;}
id(air_conditioner_sensor_target_temp).publish_state(new_temp);
- homeassistant.action:
action: climate.set_temperature
data:
entity_id: "${air_conditioner_entity}"
temperature: !lambda 'return id(air_conditioner_sensor_target_temp).state;'
- obj:
width: 60
height: 60
align: center
clickable: false
radius: 45
pad_all: 0
bg_opa: transp
border_opa: transp
shadow_width: 4
shadow_color: 0xFFFFFF
shadow_ofs_x: -4
shadow_ofs_y: -2
shadow_opa: 30%
- obj:
width: 65
height: 65
pad_all: 0
align: center
clickable: false
radius: 50
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
y: -2
align: CENTER
text_font: nunito_48
text_color: color_misty_blue
text: "-"
# Name
- obj:
id: air_conditioner_name
x: 100
y: 400
width: 360
height: 60
align: TOP_LEFT
pad_all: 0
bg_color: color_steel_blue
bg_opa: 20%
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: air_conditioner_name_label
x: 20
align: LEFT_MID
text_font: nunito_16
text_color: color_misty_blue
text: "friendly name"
# TEMPERATURE WIDGET
- obj:
id: air_conditioner_bg_main_temperature
hidden: false
width: 250
height: 480
align: RIGHT_MID
pad_all: 0
bg_opa: TRANSP
scrollable: false
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- obj:
id: air_conditioner_bg_placeholder_temperature
radius: 240
x: 235
width: 480
height: 480
align: RIGHT_MID
bg_color: color_slate_blue_gray
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
- obj:
id: air_conditioner_temp_arc_bg
radius: 230
x: 230
width: 460
height: 460
align: RIGHT_MID
bg_color: color_steel_blue
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
- meter:
id: air_conditioner_meter_temperature
x: 200
height: 400
width: 400
border_width: 0
bg_color: color_slate_blue_gray
align: RIGHT_MID
text_color: color_steel_blue
scales:
- range_from: 10
range_to: 30
angle_range: 130
rotation: 108.0
ticks:
width: 1
count: 21
length: 10
major:
stride: 5
width: 5
length: 15
label_gap: 15
indicators:
tick_style:
start_value: 10
end_value: 30
color_start: color_steel_blue
color_end: color_steel_blue
width: 1
- arc:
id: air_conditioner_arc_main_temperature
align: RIGHT_MID
arc_width: 30
x: 234
width: 464
height: 460
min_value: 7
max_value: 35
adjustable: true
adv_hittest: true
rotation: 90.0
start_angle: 0
end_angle: 180
arc_opa: TRANSP
indicator:
arc_color: color_deep_orange
arc_width: 30
knob:
border_color: color_white
border_width: 7
bg_opa: TRANSP
on_release:
- homeassistant.action:
action: climate.set_temperature
data:
entity_id: "${air_conditioner_entity}"
temperature: !lambda return x;
- arc:
id: air_conditioner_arc_current_temp
clickable: false
align: RIGHT_MID
arc_width: 10
x: 229
width: 450
height: 444
min_value: 7
max_value: 35
adjustable: true
adv_hittest: true
rotation: 90.0
start_angle: 0
end_angle: 180
arc_opa: transp
indicator:
arc_opa: transp
knob:
bg_color: color_white
border_width: 0
border_opa: TRANSP
- obj:
width: 140
height: 120
align: RIGHT_MID
bg_color: color_slate_blue_gray
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
widgets:
- label:
id: air_conditioner_target_temperature_whole
x: -40
y: 0
align: RIGHT_MID
text_font: nunito_84
text_color: color_steel_blue
text: " "
- label:
id: air_conditioner_target_temperature_fraction
x: -10
y: 15
align: RIGHT_MID
text_font: nunito_36
text_color: color_steel_blue
text: " "
- label:
id: air_conditioner_target_temperature_measurement
x: -12
y: -20
align: RIGHT_MID
text_font: nunito_30
text_color: color_steel_blue
text: "°C"
- label:
id: air_conditioner_target_temperature_value
x: -10
y: 80
align: RIGHT_MID
text_font: nunito_30
text_color: color_steel_blue
text: " "
# HUMIDITY WIDGET
- obj:
id: air_conditioner_bg_main_humidity
hidden: true
width: 250
height: 480
align: RIGHT_MID
pad_all: 0
bg_opa: TRANSP
scrollable: false
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- obj:
id: air_conditioner_bg_placeholder_humidity
radius: 240
x: 235
width: 480
height: 480
align: RIGHT_MID
bg_color: color_slate_blue_gray
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
- obj:
id: air_conditioner_hum_arc_bg
radius: 230
x: 230
width: 460
height: 460
align: RIGHT_MID
bg_color: color_steel_blue
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
- meter:
id: air_conditioner_meter_humidity
x: 200
height: 400
width: 400
border_width: 0
bg_color: color_slate_blue_gray
align: RIGHT_MID
text_color: color_steel_blue
scales:
range_from: 35
range_to: 95
angle_range: 156
rotation: 103.0
ticks:
width: 1
count: 61
length: 10
major:
stride: 10
width: 5
length: 15
label_gap: 15
indicators:
tick_style:
start_value: 35
end_value: 95
color_start: color_steel_blue
color_end: color_steel_blue
width: 1
- arc:
id: air_conditioner_arc_main_humidity
align: RIGHT_MID
arc_width: 30
x: 234
width: 464
height: 460
min_value: 30
max_value: 99
adjustable: true
adv_hittest: true
rotation: 90.0
start_angle: 0
end_angle: 180
arc_opa: TRANSP
indicator:
arc_color: color_steel_blue
arc_width: 30
knob:
border_color: color_white
border_width: 7
bg_opa: TRANSP
on_release:
- homeassistant.action:
action: climate.set_humidity
data:
entity_id: "${air_conditioner_entity}"
humidity: !lambda return (int)round(x);
- arc:
id: air_conditioner_arc_current_hum
clickable: false
align: RIGHT_MID
arc_width: 10
x: 229
width: 450
height: 444
min_value: 30
max_value: 99
adjustable: true
adv_hittest: true
rotation: 90.0
start_angle: 10
end_angle: 170
arc_opa: TRANSP
indicator:
arc_opa: transp
knob:
bg_color: color_white
border_width: 0
border_opa: TRANSP
- obj:
width: 140
height: 120
align: RIGHT_MID
bg_color: color_slate_blue_gray
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
widgets:
- label:
id: air_conditioner_target_humidity_whole
x: -40
y: 0
align: RIGHT_MID
text_font: nunito_84
text_color: color_steel_blue
text: " "
- label:
id: air_conditioner_target_humidity_fraction
x: -10
y: 15
align: RIGHT_MID
text_font: nunito_36
text_color: color_steel_blue
text: " "
- label:
id: air_conditioner_target_humidity_measurement
x: -12
y: -20
align: RIGHT_MID
text_font: nunito_30
text_color: color_steel_blue
text: "%"
- label:
id: air_conditioner_target_humidity_value
x: -10
y: 80
align: RIGHT_MID
text_font: nunito_30
text_color: color_steel_blue
text: " "
# Air conditioner humidity/temperature mode select
- obj:
id: air_conditioner_select_hum_temp_mode_btn
x: -5
y: -90
width: 80
height: 80
align: RIGHT_MID
bg_color: color_slate_blue_gray
pad_all: 0
border_opa: transp
border_width: 0
shadow_opa: TRANSP
radius: 50
widgets:
- label:
id: air_conditioner_state_icon
align: center
text_font: icons_48
text_color: color_steel_blue
text: "${temperature_icon}"
on_click:
- lambda: |-
id(air_conditioner_temp_hum_mode) = !id(air_conditioner_temp_hum_mode);
- if:
condition:
lambda: 'return id(air_conditioner_temp_hum_mode);'
then:
- lvgl.label.update:
id: air_conditioner_state_icon
text: "${humidity_icon}"
- lvgl.widget.hide: air_conditioner_bg_main_temperature
- lvgl.widget.show: air_conditioner_bg_main_humidity
- if:
condition:
lambda: 'return id(air_conditioner_sensor_current_hum).state < id(air_conditioner_sensor_target_hum).state;'
then:
- lvgl.arc.update:
id: air_conditioner_arc_main_humidity
indicator:
arc_color: color_dark_blue
- lvgl.label.update:
id: ac_status
text_color: color_dark_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_whole
text_color: color_dark_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_fraction
text_color: color_dark_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_measurement
text_color: color_dark_blue
else:
- lvgl.arc.update:
id: air_conditioner_arc_main_humidity
indicator:
arc_color: color_blue
- lvgl.label.update:
id: ac_status
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_whole
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_fraction
text_color: color_steel_blue
- lvgl.label.update:
id: air_conditioner_target_humidity_measurement
text_color: color_steel_blue
else:
- lvgl.label.update:
id: air_conditioner_state_icon
text: "${temperature_icon}"
- lvgl.widget.show: air_conditioner_bg_main_temperature
- lvgl.widget.hide: air_conditioner_bg_main_humidity
# Return
- button:
id: air_conditioner_back
x: 20
y: 400
width: 60
height: 60
align: TOP_LEFT
bg_color: color_steel_blue
bg_opa: 20%
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: air_conditioner_back_label
align: CENTER
text_font: icons_28
text_color: color_misty_blue
text: "${exit_icon}"
on_press:
- lvgl.page.show: devices_page
- lvgl.widget.show: menu_controls_main
script:
- id: air_conditioner_get_and_set_translated_state
parameters:
state_str: string
then:
- lambda: |-
std::string state = state_str;
auto it = id(climate_translations).find(state);
std::string translated_state = (it != id(climate_translations).end()) ? it->second : state;
lv_label_set_text(id(air_conditioner_state_label), translated_state.c_str());
select:
- platform: lvgl
widget: language_dropdown
id: air_conditioner_select_language
on_value:
then:
- delay: 300ms
- script.execute:
id: air_conditioner_get_and_set_translated_state
state_str: !lambda 'return id(air_conditioner_sensor_hvac_action).state;'
esphome:
on_boot:
priority: -100
then:
- if:
condition:
lambda: 'return id(air_conditioner_sensor_hvac_action).has_state();'
then:
- script.execute:
id: air_conditioner_get_and_set_translated_state
state_str: !lambda 'return id(air_conditioner_sensor_hvac_action).state;'
api:
on_client_connected:
- if:
condition:
lambda: 'return id(air_conditioner_sensor_hvac_action).has_state();'
then:
- script.execute:
id: air_conditioner_get_and_set_translated_state
state_str: !lambda 'return id(air_conditioner_sensor_hvac_action).state;'