Skip to content

Instantly share code, notes, and snippets.

@Samywamy10
Created June 2, 2025 12:12
Show Gist options
  • Save Samywamy10/d39d4a5f3ca9176b7f9e90650dc01663 to your computer and use it in GitHub Desktop.
Save Samywamy10/d39d4a5f3ca9176b7f9e90650dc01663 to your computer and use it in GitHub Desktop.
Living room controls
# usage:
# packages:
# living_room_controls: !include
# file: shared_living-room-controls.yaml
# vars:
# light_entity: light.living_kitchen_lights
# media_player_entity: media_player.living_room
# light_sensor_entity: sensor.living_room_presence_sensor_light_sensor_light_level_2
# temperature_entity: sensor.living_room_temperature_humidity_sensor_temperature
# ac_entity: climate.living_room_ac
# lock_entity: lock.lock_pro_7294
# lock_entity_2: button.apartment_building_relays_unlock_from_doorbell
# tv_entity: media_player.77_oled_3
esphome:
on_boot:
then:
- script.execute: set_ac_mode
- script.execute: set_lock
- script.execute: set_fan_mode
script:
- id: set_ac_mode
then:
- if:
condition:
- text_sensor.state:
id: living_room_ac_state
state: "heat"
then:
- lvgl.widget.show: mode_selector
- lvgl.widget.show: btn_ac_off
- lvgl.widget.show: lbl_ac_on_living_room_ac_temp
- lvgl.widget.hide: lbl_ac_off_living_room_ac_temp
- lvgl.widget.hide: btn_ac_on
- lvgl.widget.show: btn_ac_fan
- lvgl.image.update:
id: img_ac_mode
src: fire
- lvgl.widget.update:
id: btn_ac
state:
checked: true
checked:
bg_color: 0xff2525
- lvgl.widget.update:
id: ac_page
bg_color: 0x610c01
bg_opa: "100%"
- if:
condition:
- text_sensor.state:
id: living_room_ac_state
state: "cool"
then:
- lvgl.widget.show: mode_selector
- lvgl.widget.show: btn_ac_off
- lvgl.widget.show: lbl_ac_on_living_room_ac_temp
- lvgl.widget.hide: lbl_ac_off_living_room_ac_temp
- lvgl.widget.hide: btn_ac_on
- lvgl.widget.show: btn_ac_fan
- lvgl.image.update:
id: img_ac_mode
src: ice
- lvgl.widget.update:
id: btn_ac
state:
checked: true
checked:
bg_color: 0x4546ff
- lvgl.widget.update:
id: ac_page
bg_color: 0x001c5c
bg_opa: "100%"
- if:
condition:
- text_sensor.state:
id: living_room_ac_state
state: "off"
then:
- lvgl.widget.show: lbl_ac_off_living_room_ac_temp
- lvgl.widget.show: btn_ac_on
- lvgl.widget.hide: mode_selector
- lvgl.widget.hide: btn_ac_off
- lvgl.widget.hide: lbl_ac_on_living_room_ac_temp
- lvgl.widget.hide: btn_ac_fan
- lvgl.widget.update:
id: btn_ac
state:
checked: false
- lvgl.widget.update:
id: ac_page
bg_color: 0x000000
bg_opa: 0
- id: set_lock
then:
- if:
condition:
- text_sensor.state:
id: front_door_lock_state
state: "locked"
then:
- lvgl.label.update:
id: lock_lbl
text: "\U0000e897"
- lvgl.widget.update:
id: btn_lock
bg_color: 0x00bd2c
text_color: 0xffffff
- if:
condition:
- text_sensor.state:
id: front_door_lock_state
state: "unlocked"
then:
- lvgl.label.update:
id: lock_lbl
text: "\U0000e898"
- lvgl.widget.update:
id: btn_lock
bg_color: 0xb01515
text_color: 0xffffff
- id: set_fan_mode
then:
- if:
condition:
- text_sensor.state:
id: living_room_ac_fan_mode
state: "low"
then:
- lvgl.label.update:
id: lbl_ac_fan
text: "\U0000f168\U0000e145" # fan and plus
- if:
condition:
- text_sensor.state:
id: living_room_ac_fan_mode
state: "medium"
then:
- lvgl.label.update:
id: lbl_ac_fan
text: "\U0000f168\U0000e145" # fan and plus
- if:
condition:
- text_sensor.state:
id: living_room_ac_fan_mode
state: "high"
then:
- lvgl.label.update:
id: lbl_ac_fan
text: "\U0000f168\U0000e15b" # fan and minus
binary_sensor:
- platform: homeassistant
id: living_room_lights
entity_id: ${light_entity}
publish_initial_state: true
on_state:
- lvgl.widget.update:
id: btn_lights
state:
checked: !lambda return x;
- platform: homeassistant
id: living_room_receiver
entity_id: ${media_player_entity}
publish_initial_state: true
on_state:
- lvgl.widget.update:
id: btn_vol
state:
checked: !lambda return x;
sensor:
- platform: homeassistant
id: living_room_lights_brightness
entity_id: ${light_entity}
attribute: brightness
filters:
- multiply: !lambda return 0.392; # to get it to be 0 to 100 instead of 0 to 255
on_value:
- lvgl.widget.update:
id: btn_lights
checked:
bg_opa: !lambda return std::max((x / 0.392), 150.0); # to get it back to be 0 to 255
- light.turn_on:
id: back_light
brightness: !lambda return std::max((x / 100.0) - 0.2, 0.2); # minimum of 0.2; but also max of 80% (-0.2 from 1)
- platform: homeassistant
id: living_room_light_sensor
entity_id: ${light_sensor_entity}
filters:
- calibrate_linear:
datapoints:
# Map 0.0 (from sensor) to 1.0 (true value)
- 4 -> 0.4
- 30 -> 0.8
- clamp:
min_value: 0.2
max_value: 0.8
on_value:
- light.turn_on:
id: back_light
brightness: !lambda return x;
- platform: homeassistant
id: living_room_temperature
entity_id: ${temperature_entity}
internal: true
on_value:
then:
- lvgl.label.update:
id: lbl_ac_off_living_room_ac_temp
text:
format: "%.1f°"
args: [ 'id(living_room_temperature).state' ]
- lvgl.label.update:
id: lbl_ac_on_living_room_temp
text:
format: "%.1f°"
args: [ 'id(living_room_temperature).state' ]
- platform: homeassistant
id: living_room_ac_temperature
entity_id: ${ac_entity}
attribute: temperature
internal: true
on_value:
then:
- lvgl.label.update:
id: lbl_ac_on_living_room_ac_temp
text:
format: "%.1f°"
args: [ 'id(living_room_ac_temperature).state' ]
- platform: homeassistant
id: living_room_receiver_volume
entity_id: ${media_player_entity}
attribute: volume_level
on_value:
- lvgl.arc.update:
id: arc_living_room_receiver
value: !lambda return (x * 100);
text_sensor:
- platform: homeassistant
id: living_room_ac_state
entity_id: ${ac_entity}
internal: true
on_value:
then:
- script.execute: set_ac_mode
- platform: homeassistant
id: living_room_ac_fan_mode
entity_id: ${ac_entity}
attribute: fan_mode
internal: true
on_value:
then:
- script.execute: set_fan_mode
- platform: homeassistant
id: front_door_lock_state
entity_id: ${lock_entity}
internal: true
on_value:
then:
- script.execute: set_lock
lvgl:
touchscreens:
- my_touchscreen
disp_bg_color: 0x000000
on_idle:
timeout: 3s
then:
- lvgl.page.show:
id: main_page
animation: fade_in
pages:
- id: main_page
bg_opa: 0
align: CENTER
layout:
type: grid
grid_columns: [FR(1), FR(1)]
grid_rows: [FR(1), FR(1)]
widgets:
- button:
id: btn_ac
bg_color: 0xa4d4d4d
text_color: 0x000000
shadow_color: 0x1a1919
checked:
bg_color: 0x4546ff
grid_cell_column_pos: 0
grid_cell_row_pos: 0
grid_cell_x_align: STRETCH
grid_cell_y_align: STRETCH
layout:
type: flex
flex_align_main: end
flex_align_track: end
on_press:
then:
- if: # turn on when off on button press here
condition:
- text_sensor.state:
id: living_room_ac_state
state: "off"
then:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: ${ac_entity}
hvac_mode: cool
- lvgl.page.show:
id: ac_page
animation: fade_in
widgets:
- label:
text: "\U0000f168"
text_font: icons_80
- button:
id: btn_lock
bg_color: 0xa4d4d4d
text_color: 0x000000
shadow_color: 0x1a1919
grid_cell_column_pos: 1
grid_cell_row_pos: 0
grid_cell_x_align: STRETCH
grid_cell_y_align: STRETCH
layout:
type: flex
flex_align_main: start
flex_align_track: end
on_press:
then:
- if:
condition:
- text_sensor.state:
id: front_door_lock_state
state: "locked"
then:
- homeassistant.action:
action: button.press
data:
entity_id: ${unlock_entity_2}
- homeassistant.action:
action: lock.unlock
data:
entity_id: ${lock_entity}
- if:
condition:
- text_sensor.state:
id: front_door_lock_state
state: "unlocked"
then:
- homeassistant.action:
action: lock.lock
data:
entity_id: ${lock_entity}
widgets:
- label:
id: lock_lbl
text: "\U0000e897"
text_font: icons_80
- button:
id: btn_vol
bg_color: 0xa4d4d4d
text_color: 0x000000
shadow_color: 0x1a1919
checked:
bg_color: 0xfd29ca
grid_cell_column_pos: 0
grid_cell_row_pos: 1
grid_cell_x_align: STRETCH
grid_cell_y_align: STRETCH
layout:
type: flex
flex_align_main: end
flex_align_track: start
on_press:
then:
- if:
condition:
- binary_sensor.is_on:
id: living_room_receiver
then:
- lvgl.page.show:
id: set_volume_page
animation: fade_in
widgets:
- label:
text: "\U0000e050"
text_font: icons_80
- button:
id: btn_lights
bg_color: 0xa4d4d4d
text_color: 0x000000
shadow_color: 0x1a1919
grid_cell_column_pos: 1
grid_cell_row_pos: 1
grid_cell_x_align: STRETCH
grid_cell_y_align: STRETCH
layout:
type: flex
flex_align_main: start
flex_align_track: start
checked:
bg_color: 0xffd63e
widgets:
- label:
text: "\U0000e0f0"
text_font: icons_80
on_click:
then:
- if:
condition:
- sensor.in_range:
id: living_room_lights_brightness
above: 31
then:
- homeassistant.action:
action: light.turn_on
data:
entity_id: ${light_entity}
brightness_pct: "30"
- if:
condition:
- sensor.in_range:
id: living_room_lights_brightness
below: 30
then:
- homeassistant.action:
action: light.turn_off
data:
entity_id: ${light_entity}
- if:
condition:
- binary_sensor.is_off:
id: living_room_lights
then:
- homeassistant.action:
action: light.turn_on
data:
entity_id: ${light_entity}
brightness_pct: "100"
- id: ac_page
bg_opa: 0
scrollbar_mode: "off"
layout:
type: flex
flex_align_main: center
flex_align_cross: center
flex_align_track: center
pad_row: 0
widgets:
- obj:
id: mode_selector
pad_all: 0
bg_opa: 0
border_width: 0
width: size_content
height: size_content
layout:
type: flex
flex_flow: row
flex_align_main: center
flex_align_cross: center
flex_align_track: center
widgets:
- label:
id: lbl_ac_on_living_room_temp
text_font: montserrat_40
text_color: 0x808080 # Grey color
text: "22°"
- button:
id: btn_change_mode
bg_opa: 0
shadow_width: 0
width: size_content
pad_all: 0
widgets:
- image:
src: fire
id: img_ac_mode
antialias: true
on_press:
then:
- if:
condition:
- text_sensor.state:
id: living_room_ac_state
state: "heat"
then:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: ${ac_entity}
hvac_mode: cool
- if:
condition:
- text_sensor.state:
id: living_room_ac_state
state: "cool"
then:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: ${ac_entity}
hvac_mode: heat
- label:
id: lbl_ac_on_living_room_ac_temp
text_font: montserrat_80
text_color: 0xFFFFFF # White color
text: "22°"
on_press:
then:
- lvgl.page.show:
id: set_temp_page
animation: fade_in
- label:
id: lbl_ac_off_living_room_ac_temp
text_font: montserrat_80
text_color: 0x808080 # Grey color
text: "22°"
gesture_bubble: true
- obj:
id: ac_buttons
pad_all: 0
bg_opa: 0
border_width: 0
width: size_content
height: size_content
layout:
type: flex
flex_flow: row
flex_align_main: center
flex_align_cross: center
flex_align_track: center
widgets:
- button:
id: btn_ac_fan
bg_color: 0xa6fcff
text_color: 0x000000
shadow_width: 0
# shadow_color: 0x1a1919
# height: 40
pad_all: 10
width: size_content
height: 50
layout:
type: flex
flex_align_main: center
flex_align_track: center
on_press:
then:
- if:
condition:
- text_sensor.state:
id: living_room_ac_fan_mode
state: "low"
then:
- homeassistant.action:
action: climate.set_fan_mode
data:
entity_id: ${ac_entity}
fan_mode: "medium"
- if:
condition:
- text_sensor.state:
id: living_room_ac_fan_mode
state: "medium"
then:
- homeassistant.action:
action: climate.set_fan_mode
data:
entity_id: ${ac_entity}
fan_mode: "high"
- if:
condition:
- text_sensor.state:
id: living_room_ac_fan_mode
state: "high"
then:
- homeassistant.action:
action: climate.set_fan_mode
data:
entity_id: ${ac_entity}
fan_mode: "low"
widgets:
- label:
id: lbl_ac_fan
text: "\U0000f168"
text_font: icons_30
- button:
id: btn_ac_off
bg_color: 0xd64b4b
text_color: 0xFFFFFF
shadow_width: 0
# shadow_color: 0x1a1919
# height: 40
pad_all: 10
width: size_content
height: 50
layout:
type: flex
flex_align_main: center
flex_align_track: center
on_press:
then:
- homeassistant.action:
action: climate.turn_off
data:
entity_id: ${ac_entity}
widgets:
- label:
text: "Off"
text_font: montserrat_30
- button:
id: btn_ac_on
bg_color: 0x404040
text_color: 0xbab8b8
shadow_color: 0x1a1919
height: 40
width: 130
layout:
type: flex
flex_align_main: center
flex_align_track: center
on_press:
then:
- homeassistant.action:
action: climate.set_hvac_mode
data:
entity_id: ${ac_entity}
hvac_mode: cool
widgets:
- label:
text: "On"
text_font: montserrat_20
- id: set_temp_page
bg_opa: 0
align: CENTER
layout:
type: flex
flex_flow: column
flex_align_main: center
flex_align_cross: center
flex_align_track: center
pad_row: 0
widgets:
- button:
id: btn_increase_temp
bg_color: 0xff525d
text_color: 0xbab8b8
shadow_color: 0x1a1919
height: "50%"
width: "100%"
radius: 0
layout:
type: flex
flex_align_main: center
flex_align_track: center
on_press:
then:
- homeassistant.action:
action: climate.set_temperature
data:
entity_id: climate.living_room_ac
data_template:
temperature: "{{ state_attr('climate.living_room_ac', 'temperature') | float + 1 }}"
- lvgl.page.show:
id: ac_page
animation: fade_in
widgets:
- label:
text: "+"
text_color: 0x000000
text_font: montserrat_80
- button:
id: btn_decrease_temp
bg_color: 0x4670fa
text_color: 0xbab8b8
shadow_color: 0x1a1919
height: "50%"
width: "100%"
radius: 0
layout:
type: flex
flex_align_main: center
flex_align_track: center
on_press:
then:
- homeassistant.action:
action: climate.set_temperature
data:
entity_id: ${ac_entity}
data_template:
temperature: "{{ state_attr('${ac_entity}', 'temperature') | float - 1 }}"
- lvgl.page.show:
id: ac_page
animation: fade_in
widgets:
- label:
text: "-"
text_color: 0x000000
text_font: montserrat_80
- id: set_volume_page
bg_opa: 0
align: CENTER
text_color: 0xFFFFFF
widgets:
- arc:
id: arc_living_room_receiver
width: "100%"
height: "100%"
arc_width: 40
indicator:
arc_color: 0x18bcf2
arc_width: 40
value: 75
min_value: 20
max_value: 70
adjustable: true
adv_hittest: true
align: CENTER
on_change:
- homeassistant.action:
action: media_player.volume_set
data:
entity_id: ${media_player_entity}
volume_level: !lambda return (x / 100);
- button:
align: CENTER
bg_color: 0xb01515
shadow_color: 0x1a1919
on_press:
then:
- homeassistant.action:
action: media_player.turn_off
data:
entity_id: ${tv_entity}
widgets:
- label:
text: "\U0000e647"
text_font: icons_50
align: CENTER
image:
- file: "images/fire.png"
id: "fire"
type: RGB565
transparency: alpha_channel
resize: "36x36"
- file: "images/ice.png"
id: "ice"
type: RGB565
transparency: alpha_channel
resize: "36x36"
font:
- file: "gfonts://Montserrat"
id: montserrat_80
size: 80
bpp: 8
glyphs: ["0","1","2","3","4","5","6","7","8","9",".","°", "+", "-"]
- file: "gfonts://Material+Symbols+Outlined"
id: icons_80
size: 65
bpp: 8
glyphs: ["\U0000e898", "\U0000e897", "\U0000e050", "\U0000f168", "\U0000e0f0"] # tv off, lock open, lock, volume up, mode fan, light bulb
- file: "gfonts://Material+Symbols+Outlined"
id: icons_50
size: 50
bpp: 8
glyphs: ["\U0000e647"] # tv off
- file: "gfonts://Material+Symbols+Outlined"
id: icons_30
size: 30
bpp: 8
glyphs: ["\U0000f168", "\U0000e145", "\U0000e15b"] #fan, minus, plus
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment