substitutions:
# Device customization
# Personalización del dispositivo
name: habbit-desk-pro
friendly_name: Habbit Desk PRO
background_color: 0x000000
text_color: 0xFFFFFF
text_color_secondary: 0x767676
iddle_time: 20s
animation_active: https://aguacatec.es/wp-content/uploads/2026/04/anim_active-1.png
animation_iddle: https://aguacatec.es/wp-content/uploads/2026/04/anim_iddle-1.png
animation_alert: https://aguacatec.es/wp-content/uploads/2026/04/notification-1.png
icon_ha: https://aguacatec.es/wp-content/uploads/2026/04/icon_ha.png
image_3dprinter: https://aguacatec.es/wp-content/uploads/2026/04/3dprinter_enclosed.png
image_vacuum: https://aguacatec.es/wp-content/uploads/2026/04/vacuum.png
# Entities
# Entidades
weather_condition: weather.openweathermap
room_temperature: sensor.sensor_temperatura_estudio_temperature
room_humidity: sensor.sensor_temperatura_estudio_humidity
room_co2: sensor.wifi_smart_switch_calidad_del_aire
notifications: input_text.notificaciones_habbit_desk
calendar: sensor.calendar
media: media_player.laptopchuwi
goal_current: sensor.aguacatec_suscriptores
goal_target: 3000
goal_text: "A por los 3000 subs"
light_ceiling: light.ventilador_estudio
cover1: cover.estor_estudio_1
cover2: cover.estor_estudio_2
climate: climate.salon
dehumidifier: humidifier.deshumidificador_estudio
fan_ceiling: fan.ventilador_estudio
light_bar: switch.regleta_usb_escritorio_l2
printer: switch.impresora
printer_3d: switch.impresora_3d
printer_3d_octoprint_status: switch.regleta_usb_herramientas_center
printer_3d_octoprint_file: sensor.octoprint_current_file
printer_3d_octoprint_temp_bed: sensor.octoprint_actual_bed_temp
printer_3d_octoprint_temp_hotend: sensor.octoprint_actual_tool0_temp
printer_3d_octoprint_operation: sensor.octoprint_current_state
printer_3d_octoprint_progress: sensor.octoprint_job_percentage
printer_3d_octoprint_finish: sensor.octoprint_estimated_finish_time
printer_3d_pause_button: button.octoprint_pause_job
printer_3d_resume_button: button.octoprint_resume_job
printer_3d_stop_button: button.octoprint_stop_job
vacuum: vacuum.roborock_qr_598
vacuum_water: binary_sensor.roborock_qr_598_escasez_de_agua
vacuum_error: sensor.roborock_qr_598_error_de_aspirador
vacuum_current_room: sensor.roborock_qr_598_habitacion_actual
vacuum_cleaning_progress: sensor.roborock_qr_598_progreso_de_la_limpieza
vacuum_cleaning_time: sensor.roborock_qr_598_tiempo_de_limpieza
vacuum_last_clean: sensor.roborock_qr_598_finalizacion_de_la_ultima_limpieza
# Other settings
# Otros ajustes
allowed_characters: " []¿?¡!#%'()+,-—_./:µ³°ªº0123456789ABCDEFGHIJKLMNÑOPQRSTUVWYZabcdefghijklmnñopqrstuvwxyzáéíóúÁÉÍÓÚäëïöü"
################################################################################################################
esphome:
name: ${name}
friendly_name: ${friendly_name}
on_boot:
priority: -100
then:
## Speaker
## Altavoz
- switch.turn_on: speaker_enable
- delay: 500ms
- select.set:
id: dac_output_select
option: LINE1
- delay: 500ms
- media_player.volume_set:
id: speaker_player
volume: 1
## Animation
## Animación
- lambda: |-
lv_obj_t* obj = id(animation_widget);
int32_t base_y = lv_obj_get_y(obj);
static lv_anim_t anim;
lv_anim_init(&anim);
lv_anim_set_var(&anim, obj);
lv_anim_set_exec_cb(&anim, [](void* o, int32_t v) {
lv_obj_set_y((lv_obj_t*)o, v);
});
lv_anim_set_values(&anim, base_y, base_y + 30);
lv_anim_set_duration(&anim, 2200);
lv_anim_set_playback_duration(&anim, 2200);
lv_anim_set_repeat_count(&anim, LV_ANIM_REPEAT_INFINITE);
lv_anim_set_path_cb(&anim, lv_anim_path_ease_in_out);
lv_anim_start(&anim);
- component.update: ina226_sensor
- delay: 500ms
- component.update: battery_percentage
esp32:
board: esp32-p4-evboard
flash_size: 16MB
framework:
type: esp-idf
advanced:
enable_idf_experimental_features: true
esp32_hosted:
variant: esp32c6
active_high: true
clk_pin: GPIO12
cmd_pin: GPIO13
d0_pin: GPIO11
d1_pin: GPIO10
d2_pin: GPIO9
d3_pin: GPIO8
reset_pin: GPIO15
slot: 1
logger:
hardware_uart: USB_SERIAL_JTAG
psram:
mode: hex
speed: 200MHz
api:
encryption:
key: "Fdasdas+OaKt1XvQV9pU6dsaadsads"
ota:
- platform: esphome
password: "2r3d3908b12744trgwds"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "M5Stack-Tab5 Fallback Hotspot"
password: "ewfef3Mt2rd"
audio_dac:
- platform: es8388
id: es8388_dac
audio_adc:
- platform: es7210
id: es7210_adc
bits_per_sample: 16bit
sample_rate: 16000
# Sensors configuration
# Configuración de sensores
binary_sensor:
- platform: gpio
id: charging
name: "Carga"
icon: mdi:battery-charging
pin:
pi4ioe5v6408: pi4ioe2
number: 6
mode: INPUT_PULLDOWN
filters:
- delayed_on: 2s
- delayed_off: 2s
on_state:
then:
- lvgl.label.update:
id: lbl_battery_percentage
text:
format: "%.0f%%"
args:
- id(battery_percentage).state
- lvgl.label.update:
id: battery_icon
text: !lambda |-
if (id(charging).state) return "\U0000f250";
float pct = x;
if (pct >= 70.0) return "\U0000f24f";
if (pct >= 30.0) return "\U0000f255";
return "\U0000f257";
text_color: !lambda |-
float pct = id(battery_percentage).state;
if (id(charging).state) return lv_color_hex(0xe6b854);
if (pct >= 70.0) return lv_color_hex(0xc9e654);
if (pct >= 30.0) return lv_color_hex(0xe65476);
return lv_color_hex(0x767676);
- platform: gpio
id: headphone_detect
name: "Headphone Detect"
internal: true
pin:
pi4ioe5v6408: pi4ioe1
number: 7
# Devices
# Dispositivos
# VACUUM
- platform: homeassistant
id: device_vacuum_water
entity_id: ${vacuum_water}
internal: true
filters:
- delayed_on: 10min
on_press:
then:
- lvgl.label.update:
id: lbl_device_vacuum_water
text_color: 0xe65470
- lvgl.image.update:
id: icon_vacuum_water_state
image_recolor: 0xe65470
on_release:
then:
- lvgl.label.update:
id: lbl_device_vacuum_water
text_color: 0x767676
- lvgl.image.update:
id: icon_vacuum_water_state
image_recolor: 0x767676
esp_ldo:
- voltage: 2.5V
channel: 3
font:
# Interface
# Interfaz
- file: "gfonts://Figtree"
id: font_clock
size: 160
glyphs: ${allowed_characters}
- file: "gfonts://Material+Symbols+Outlined"
id: font_info_icons
size: 40
glyphs: [
"\U0000f24f", # 100%
"\U0000f255", # 50%
"\U0000f257", # 10%
"\U0000f250", # Charging
"\U0000e98e", # Speaker ON
"\U0000e04f", # Speaker OFF
]
- file: "gfonts://Material+Symbols+Outlined"
id: font_info_icons_little
size: 40
glyphs: [
"\U0000f654", # Alert
"\U0000e63e", # Wifi ON
"\U0000e648", # Wifi OFF
"\U0000e1ff", # thermometer
"\U0000f87e", # water-percent
"\U0000e29c", # air
"\U0000e834", # check
"\U0000e62e", # assistant
]
- file: "gfonts://Figtree"
id: font_notification
size: 70
glyphs: ${allowed_characters}
# Weather
# Meteorología
- file: "gfonts://Material+Symbols+Outlined"
id: font_top_icons
size: 70
glyphs: [
"\U0000e81a", # wb_sunny (sol)
"\U0000e818", # cloud (nube)
"\U0000f176", # umbrella (lluvia)
"\U0000e810", # water_drop (gotas)
"\U0000e80b", # ac_unit (nieve)
"\U0000efd8", # air (viento)
"\U0000ea0b", # thunderstorm (tormenta)
"\U0000f159", # nights_stay (noche)
]
- file: "gfonts://Kanit"
id: font_info_text
size: 35
glyphs: ${allowed_characters}
- file: "gfonts://Material+Symbols+Outlined"
id: font_device_icons
size: 120
glyphs: [
"\U0000f02a", # ceiling-light
"\U0000f168", # fan
"\U0000e286", # blinds-shade
"\U0000ec1f", # blinds-shade-close
"\U0000ec12", # roller-shade
"\U0000ec11", # roller-shade-close
"\U0000ed38", # 3d
"\U0000ef55", # fire
"\U0000efc5", # vacuum
"\U0000f7ed", # led-strip
"\U0000e97e", # dehumidifier
"\U0000e1c4", # play
"\U0000e1a2", # pause
"\U0000eaaa", # base
"\U0000eee1", # locate
"\U0000f418", # power
"\U0000ef71", # stop
"\U0000ebfe", # spotlight
" ",
]
- file: "gfonts://Material+Symbols+Outlined"
id: font_device_icons_little
size: 60
glyphs: [
"\U0000e879", # exit
"\U0000e548", # more
"\U0000e834", # check
" ",
]
- file: "gfonts://Material+Symbols+Outlined"
id: font_details_icons
size: 60
glyphs: [
"\U0000e286", # blinds-shade
"\U0000ec1f", # blinds-shade-close
" ",
]
- file: "gfonts://Kanit"
id: font_value
size: 60
glyphs: ${allowed_characters}
- file: "gfonts://Kanit"
id: font_device_status
size: 30
glyphs: ${allowed_characters}
- file: "gfonts://Kanit"
id: font_device_name
size: 35
glyphs: ${allowed_characters}
- file: "gfonts://Kanit"
id: font_values
size: 30
glyphs: ${allowed_characters}
globals:
## Notifications
## Notificaciones
- id: notification
type: bool
restore_value: no
initial_value: 'false'
- id: notification_last_changed
type: time_t
restore_value: yes
initial_value: '0'
- id: notification_last_text
type: std::string
restore_value: yes
max_restore_data_length: 254
initial_value: '""'
i2c:
- id: bsp_bus
sda: GPIO31
scl: GPIO32
frequency: 400kHz
i2s_audio:
- id: mic_bus
i2s_lrclk_pin: GPIO29
i2s_bclk_pin: GPIO27
i2s_mclk_pin: GPIO30
image:
## Customization
## Personalización
- file: ${animation_active}
id: img_animation_active
resize: 400x400
type: RGB565
transparency: alpha_channel
- file: ${animation_iddle}
id: img_animation_iddle
resize: 400x400
type: RGB565
transparency: alpha_channel
- file: ${animation_alert}
id: img_animation_alert
resize: 400x400
type: RGB565
transparency: alpha_channel
## Icons
## Iconos
- file: ${icon_ha}
id: img_icon_ha
resize: 100x100
type: RGB565
transparency: alpha_channel
- file: mdi:calendar
id: icon_calendar_mini
resize: 60x60
type: BINARY
transparency: chroma_key
- file: mdi:check-bold
id: icon_check
resize: 60x60
type: BINARY
transparency: chroma_key
- file: mdi:alert-decagram-outline
id: icon_notification
resize: 400x400
type: BINARY
transparency: chroma_key
- file: mdi:microphone
id: icon_assist_active
resize: 400x400
type: BINARY
transparency: chroma_key
- file: mdi:timer-sand
id: icon_assist_thinking
resize: 400x400
type: BINARY
transparency: chroma_key
- file: mdi:check-bold
id: icon_assist_success
resize: 400x400
type: BINARY
transparency: chroma_key
- file: mdi:music
id: icon_music_mini
resize: 60x60
type: BINARY
transparency: chroma_key
- file: mdi:play-pause
id: icon_music_toggle
resize: 60x60
type: BINARY
transparency: chroma_key
- file: mdi:skip-previous
id: icon_music_previous
resize: 60x60
type: BINARY
transparency: chroma_key
- file: mdi:skip-next
id: icon_music_next
resize: 60x60
type: BINARY
transparency: chroma_key
- file: mdi:youtube
id: icon_youtube_mini
resize: 60x60
type: BINARY
transparency: chroma_key
- file: mdi:robot-vacuum
id: icon_vacuum
resize: 110x110
type: BINARY
transparency: chroma_key
- file: mdi:robot-vacuum
id: icon_vacuum_mini
resize: 60x60
type: BINARY
transparency: chroma_key
- file: mdi:water
id: icon_vacuum_water
resize: 40x40
type: BINARY
transparency: chroma_key
- file: mdi:robot-vacuum-alert
id: icon_vacuum_error
resize: 40x40
type: BINARY
transparency: chroma_key
- file: mdi:printer-3d-nozzle
id: icon_3dprinter
resize: 100x100
type: BINARY
transparency: chroma_key
- file: mdi:printer-3d-nozzle
id: icon_3dprinter_mini
resize: 60x60
type: BINARY
transparency: chroma_key
- file: mdi:printer-3d-nozzle
id: icon_3dprinter_hotend
resize: 40x40
type: BINARY
transparency: chroma_key
- file: mdi:square
id: icon_3dprinter_bed
resize: 40x40
type: BINARY
transparency: chroma_key
## Devices
## Dispositivos
- file: ${image_3dprinter}
id: img_3dprinter
resize: 500x500
type: RGB565
transparency: alpha_channel
- file: ${image_vacuum}
id: img_vacuum
resize: 430x430
type: RGB565
transparency: alpha_channel
interval:
- interval: 60s
then:
- lvgl.label.update:
id: lbl_clock
text: !lambda 'return id(esptime).now().strftime("%H:%M");'
- interval: 10s
then:
- if:
condition:
lambda: 'return !id(notification);'
then:
- lvgl.image.update:
id: animation_widget
src: img_animation_iddle
- delay: 1s
- lvgl.image.update:
id: animation_widget
src: img_animation_active
## Calendar
## Calendario
- interval: 5min
then:
- script.execute: refresh_calendar_widget
- interval: 60s
then:
- lvgl.bar.update:
id: lbl_home_calendar_progress_bar
value: !lambda |-
if (id(calendar_state).state != "on")
return 0;
if (!id(calendar_event_start).has_state() || !id(calendar_event_end).has_state())
return 0;
std::string start = id(calendar_event_start).state;
std::string end_s = id(calendar_event_end).state;
if (start.empty() || end_s.empty())
return 0;
int sy, sm, sd, sh, smin, ss, ey, em, ed, eh, emin, es;
sscanf(start.c_str(), "%d-%d-%d %d:%d:%d", &sy, &sm, &sd, &sh, &smin, &ss);
sscanf(end_s.c_str(), "%d-%d-%d %d:%d:%d", &ey, &em, &ed, &eh, &emin, &es);
auto now = id(esptime).now();
if (!now.is_valid()) return 0;
int now_mins = now.hour * 60 + now.minute;
int start_mins = sh * 60 + smin;
int end_mins = eh * 60 + emin;
if (now_mins < start_mins) return 0;
if (now_mins >= end_mins) return 100;
return (int)(((float)(now_mins - start_mins) / (end_mins - start_mins)) * 100.0f);
light:
- platform: monochromatic
output: backlight_pwm
name: "Pantalla"
id: backlight
icon: mdi:tablet
restore_mode: ALWAYS_ON
media_player:
- platform: speaker
name: "Habbit Desk PRO"
id: speaker_player
announcement_pipeline:
speaker: tab5_speaker
format: FLAC
sample_rate: 48000
num_channels: 1
on_announcement:
# Stop the wake word (mWW or VA) if the mic is capturing
- if:
condition:
- microphone.is_capturing:
then:
- micro_wake_word.stop:
on_idle:
# Since VA isn't running, this is the end of user-intiated media playback. Restart the wake word.
- if:
condition:
not:
voice_assistant.is_running:
then:
- micro_wake_word.start:
microphone:
- platform: i2s_audio
id: tab5_microphone
i2s_din_pin: GPIO28
sample_rate: 16000
bits_per_sample: 16bit
adc_type: external
micro_wake_word:
id: mww
models:
- okay_nabu
# - hey_mycroft
# - hey_jarvis
on_wake_word_detected:
- voice_assistant.start:
wake_word: !lambda return wake_word;
- lvgl.page.show: page_assistant
- light.turn_on: backlight
- lvgl.resume:
- lvgl.widget.redraw:
output:
- platform: ledc
pin: GPIO22
id: backlight_pwm
frequency: 1000Hz
pi4ioe5v6408:
- id: pi4ioe1
address: 0x43
# 0: O - wifi_antenna_int_ext
# 1: O - speaker_enable
# 2: O - external_5v_power
# 3: NC
# 4: O - lcd reset
# 5: O - touch panel reset
# 6: O - camera reset
# 7: I - headphone detect
- id: pi4ioe2
address: 0x44
# 0: O - wifi_power
# 1: NC
# 2: NC
# 3: O - usb_5v_power
# 4: O - poweroff pulse
# 5: O - quick charge enable (inverted)
# 6: I - charging status
# 7: O - charge enable
script:
- id: refresh_calendar_widget
then:
- lvgl.image.update:
id: icon_calendar_mini_id
image_recolor: !lambda |-
if (!id(calendar_event_start).has_state()) return lv_color_hex(0xFFFFFF);
std::string start = id(calendar_event_start).state;
if (start.empty()) return lv_color_hex(0xFFFFFF);
int sy, sm, sd, sh, smin, ss;
if (sscanf(start.c_str(), "%d-%d-%d %d:%d:%d", &sy, &sm, &sd, &sh, &smin, &ss) != 6) {
return lv_color_hex(0xFFFFFF);
}
auto now = id(esptime).now();
if (!now.is_valid()) return lv_color_hex(0xFFFFFF);
bool is_today = (now.year == sy && now.month == sm && now.day_of_month == sd);
bool calendar_off = (id(calendar_state).state == "off");
if (is_today && calendar_off) return lv_color_hex(0x1EBBD7);
return lv_color_hex(0xFFFFFF);
- lvgl.label.update:
id: lbl_home_calendar_event_name
text: !lambda |-
if (!id(calendar_event_name).has_state()) return std::string("Sin eventos");
std::string s = id(calendar_event_name).state;
if (s.length() > 40) return (s.substr(0, 37) + "...").c_str();
return s.c_str();
text_color: !lambda |-
if (!id(calendar_event_start).has_state()) return lv_color_hex(0xFFFFFF);
std::string start = id(calendar_event_start).state;
if (start.empty()) return lv_color_hex(0xFFFFFF);
int sy, sm, sd, sh, smin, ss;
if (sscanf(start.c_str(), "%d-%d-%d %d:%d:%d", &sy, &sm, &sd, &sh, &smin, &ss) != 6) {
return lv_color_hex(0xFFFFFF);
}
auto now = id(esptime).now();
if (!now.is_valid()) return lv_color_hex(0xFFFFFF);
bool is_today = (now.year == sy && now.month == sm && now.day_of_month == sd);
bool calendar_off = (id(calendar_state).state == "off");
if (is_today && calendar_off) return lv_color_hex(0x1EBBD7);
return lv_color_hex(0xFFFFFF);
- lvgl.label.update:
id: lbl_home_calendar_event_details
text: !lambda |-
if (!id(calendar_event_start).has_state() || !id(calendar_event_end).has_state())
return std::string("Sin eventos");
std::string start = id(calendar_event_start).state;
std::string end_s = id(calendar_event_end).state;
if (start.empty() || end_s.empty()) return std::string("Sin eventos");
int sy, sm, sd, sh, smin, ss, ey, em, ed, eh, emin, es;
sscanf(start.c_str(), "%d-%d-%d %d:%d:%d", &sy, &sm, &sd, &sh, &smin, &ss);
sscanf(end_s.c_str(), "%d-%d-%d %d:%d:%d", &ey, &em, &ed, &eh, &emin, &es);
static const int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
int yr = sy; if (sm < 3) yr--;
int dow = (yr + yr/4 - yr/100 + yr/400 + t[sm-1] + sd) % 7;
const char* dias[] = {"Dom", "Lun", "Mar", "Mie", "Jue", "Vie", "Sab"};
char buf[35];
sprintf(buf, "%s %02d/%02d/%02d, %02d:%02d-%02d:%02d",
dias[dow], sd, sm, sy % 100, sh, smin, eh, emin);
return std::string(buf);
text_color: !lambda |-
if (!id(calendar_event_start).has_state()) return lv_color_hex(0xFFFFFF);
std::string start = id(calendar_event_start).state;
if (start.empty()) return lv_color_hex(0xFFFFFF);
int sy, sm, sd, sh, smin, ss;
if (sscanf(start.c_str(), "%d-%d-%d %d:%d:%d", &sy, &sm, &sd, &sh, &smin, &ss) != 6) {
return lv_color_hex(0xFFFFFF);
}
auto now = id(esptime).now();
if (!now.is_valid()) return lv_color_hex(0xFFFFFF);
bool is_today = (now.year == sy && now.month == sm && now.day_of_month == sd);
bool calendar_off = (id(calendar_state).state == "off");
if (is_today && calendar_off) return lv_color_hex(0x1EBBD7);
return lv_color_hex(0xFFFFFF);
select:
- platform: template
id: wifi_antenna_select
name: "WiFi Antenna"
internal: True
options:
- "Internal"
- "External"
optimistic: true
on_value:
- if:
condition:
lambda: return i == 0;
then:
- switch.turn_off: wifi_antenna_int_ext
else:
- switch.turn_on: wifi_antenna_int_ext
## The DAC Output select needs to be manually (or with an automation) changed to `LINE1` for the onboard speaker
- platform: es8388
es8388_id: es8388_dac
dac_output:
name: DAC Output
id: dac_output_select
adc_input_mic:
name: ADC Input Mic
sensor:
# Built-in sensors
# Sensores internos
- platform: wifi_signal
name: "Intensidad WiFi"
update_interval: 300s
on_value:
then:
- lvgl.label.update:
id: wifi_icon
text: !lambda |-
if (std::isnan(x)) return "\U0000e648"; // wifi off - sin conexión
return "\U0000e63e"; // wifi on
text_color: !lambda |-
if (std::isnan(x)) return lv_color_hex(0x767676); // wifi off - sin conexión
return lv_color_hex(0xffffff); // wifi on
- platform: ina226
id: ina226_sensor
address: 0x41
adc_averaging: 16
max_current: 8.192A
shunt_resistance: 0.005ohm
bus_voltage:
name: Battery Voltage
id: battery_voltage
internal: true
current:
name: Battery Current
internal: true
- platform: template
name: "Batería"
id: battery_percentage
unit_of_measurement: "%"
accuracy_decimals: 0
device_class: battery
state_class: measurement
lambda: |-
// Define los voltajes mínimo y máximo de tu batería
float voltage_max = 8.23; // Voltaje máximo (batería llena)
float voltage_min = 6.0; // Voltaje mínimo (batería vacía)
float voltage = id(battery_voltage).state;
// Calcula el porcentaje
float percentage = (voltage - voltage_min) / (voltage_max - voltage_min) * 100.0;
// Limita el porcentaje entre 0 y 100
if (percentage > 100.0) percentage = 100.0;
if (percentage < 0.0) percentage = 0.0;
return percentage;
update_interval: 600s
on_value:
then:
- lvgl.label.update:
id: lbl_battery_percentage
text:
format: "%.0f%%"
args:
- id(battery_percentage).state
- lvgl.label.update:
id: battery_icon
text: !lambda |-
if (id(charging).state) return "\U0000f250";
float pct = x;
if (pct >= 70.0) return "\U0000f24f";
if (pct >= 30.0) return "\U0000f255";
return "\U0000f257";
text_color: !lambda |-
float pct = id(battery_percentage).state;
if (std::isnan(pct)) return lv_color_hex(0x767676);
if (id(charging).state) return lv_color_hex(0xe6b854);
if (pct >= 70.0) return lv_color_hex(0xc9e654);
if (pct >= 30.0) return lv_color_hex(0xe65476);
return lv_color_hex(0x767676);
## Climate
## Climatización
- platform: homeassistant
id: room_temperature_value
entity_id: ${room_temperature}
internal: true
on_value:
then:
- lvgl.label.update:
id: lbl_room_temperature
text:
format: "%.0f°C"
args:
- id(room_temperature_value).state
text_color: !lambda |-
float t = id(room_temperature_value).state;
if (t < 18.0) return lv_color_hex(0x1e9cd7);
if (t > 25.0) return lv_color_hex(0xe65476);
return lv_color_hex(0x626262);
- lvgl.label.update:
id: thermometer_icon
text_color: !lambda |-
float t = id(room_temperature_value).state;
if (t < 18.0) return lv_color_hex(0x1e9cd7);
if (t > 25.0) return lv_color_hex(0xe65476);
return lv_color_hex(0x626262);
- if:
condition:
lambda: 'return id(room_temperature_value).state < 23.0;'
then:
- lvgl.widget.show: btn_climate
- lvgl.widget.hide: btn_fan
else:
- lvgl.widget.hide: btn_climate
- lvgl.widget.show: btn_fan
- platform: homeassistant
id: room_humidity_value
entity_id: ${room_humidity}
internal: true
on_value:
then:
- lvgl.label.update:
id: lbl_room_humidity
text:
format: "%.0f%%"
args:
- id(room_humidity_value).state
text_color: !lambda |-
float t = id(room_humidity_value).state;
if (t < 40.0) return lv_color_hex(0xe0a020);
if (t > 60.0) return lv_color_hex(0x1e9cd7);
return lv_color_hex(0x626262);
- lvgl.label.update:
id: humidity_icon
text_color: !lambda |-
float t = id(room_humidity_value).state;
if (t < 40.0) return lv_color_hex(0xe0a020);
if (t > 60.0) return lv_color_hex(0x1e9cd7);
return lv_color_hex(0x626262);
## Media
## Media
- platform: homeassistant
id: media_duration
entity_id: ${media}
attribute: media_duration
internal: true
- platform: homeassistant
id: media_position
entity_id: ${media}
attribute: media_position
internal: true
on_value:
then:
- lvgl.bar.update:
id: lbl_home_media_progress_bar
value: !lambda |-
float dur = id(media_duration).state;
float pos = id(media_position).state;
if (dur <= 0) return 0;
return (int)((pos / dur) * 100.0f);
# Devices
# Dispositivos
# YOUTUBE
- platform: homeassistant
id: goal_current_value
entity_id: ${goal_current}
internal: true
filters:
- lambda: |-
if (isnan(x)) return 0;
return x;
on_value:
then:
- lvgl.bar.update:
id: lbl_home_goal_progress_bar
value: !lambda return (int)x;
- lvgl.label.update:
id: lbl_home_goal_current
text: !lambda |-
char buf[30];
snprintf(buf, sizeof(buf), "%.0f Suscriptores", x);
return std::string(buf);
- lvgl.label.update:
id: lbl_home_goal_progress_value
text: !lambda |-
int pct = (int)(x / 3000.0f * 100.0f);
char buf[10];
snprintf(buf, sizeof(buf), "%d%%", pct);
return std::string(buf);
# COVER
- platform: homeassistant
id: cover_1_position_value
entity_id: ${cover1}
attribute: current_position
internal: true
filters:
- lambda: |-
...
This file has been truncated, please download it to see its full contents.
Comments