20260326
This commit is contained in:
3
esphome/widgets/home/home.yaml
Normal file
3
esphome/widgets/home/home.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
packages:
|
||||
home: !include home_widget.yaml
|
||||
info: !include info_page.yaml
|
||||
768
esphome/widgets/home/home_widget.yaml
Normal file
768
esphome/widgets/home/home_widget.yaml
Normal file
@@ -0,0 +1,768 @@
|
||||
substitutions:
|
||||
|
||||
weather_entity: "weather.forecast_home"
|
||||
temperature_entity: "sensor.outside_temperature"
|
||||
humidity_entity: "sensor.outside_humidity"
|
||||
co2_entity: "sensor.carbon_dioxide"
|
||||
|
||||
|
||||
lock_icon: "\U0000e92e"
|
||||
air_conditioner_icon: "\U0000e93b"
|
||||
heating_icon: "\U0000e936"
|
||||
info_icon: "\U0000e904"
|
||||
ha_icon: "\U0000e935" # home assistant
|
||||
wifi_25_icon: "\U0000e931" # wifi signal from 25% to 1%
|
||||
wifi_50_icon: "\U0000e932" # wifi signal from 50% to 25%
|
||||
wifi_75_icon: "\U0000e933" # wifi signal from 75% to 50%
|
||||
wifi_100_icon: "\U0000e934" # wifi signal from 100% to 75% or disable
|
||||
humidity_icon: "\U0000e938"
|
||||
co2_icon: "\U0000e937"
|
||||
tvoc: "\U0000e93a" # air quality
|
||||
temperature_icon: "\U0000e939"
|
||||
illumination: "\U0000e92f" # lux
|
||||
lightbulb_icon: "\U0000e908"
|
||||
|
||||
globals:
|
||||
- id: display_lock
|
||||
type: bool
|
||||
restore_value: true
|
||||
initial_value: "false"
|
||||
|
||||
|
||||
sensor:
|
||||
# WI-FI Signal
|
||||
- platform: wifi_signal
|
||||
id: wifi_signal_percent
|
||||
update_interval: 30s
|
||||
filters:
|
||||
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
|
||||
unit_of_measurement: "%"
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: wifi_status
|
||||
text_color: !lambda |-
|
||||
if (id(wifi_signal_percent).state > 0) {
|
||||
return lv_color_hex(0x5CA848);
|
||||
}
|
||||
return lv_color_hex(0x5CA848);
|
||||
text: !lambda |-
|
||||
if (id(wifi_signal_percent).state > 0 && id(wifi_signal_percent).state < 26) {
|
||||
return "${wifi_25_icon}";
|
||||
} else if (id(wifi_signal_percent).state > 25 && id(wifi_signal_percent).state < 51) {
|
||||
return "${wifi_50_icon}";
|
||||
} else if (id(wifi_signal_percent).state > 50 && id(wifi_signal_percent).state < 76) {
|
||||
return "${wifi_75_icon}";
|
||||
} else if (id(wifi_signal_percent).state > 75) {
|
||||
return "${wifi_100_icon}";
|
||||
}
|
||||
return "${wifi_100_icon}";
|
||||
|
||||
# Weather temperature sensor
|
||||
- platform: homeassistant
|
||||
id: weather_temp
|
||||
entity_id: "${weather_entity}"
|
||||
attribute: temperature
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: weather_temperature
|
||||
text:
|
||||
format: "%.0f°"
|
||||
args: [id(weather_temp).state]
|
||||
|
||||
# Temperature Home Sensor
|
||||
- platform: homeassistant
|
||||
id: temperature_sensor
|
||||
entity_id: "${temperature_entity}"
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: temperature_sensor_label
|
||||
text:
|
||||
format: "%.1f °C"
|
||||
args: [id(temperature_sensor).state]
|
||||
|
||||
# Humidity Home Sensor
|
||||
- platform: homeassistant
|
||||
id: humidity_sensor
|
||||
entity_id: "${humidity_entity}"
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: humidity_sensor_label
|
||||
text:
|
||||
format: "%.1f %%"
|
||||
args: [id(humidity_sensor).state]
|
||||
|
||||
|
||||
# CO2 Home Sensor
|
||||
- platform: homeassistant
|
||||
id: co2_sensor
|
||||
entity_id: "${co2_entity}"
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: co2_sensor_label
|
||||
text:
|
||||
format: "%.0f PPM"
|
||||
args: [id(co2_sensor).state]
|
||||
|
||||
|
||||
text_sensor:
|
||||
# Sun horizon sensor
|
||||
- platform: homeassistant
|
||||
id: sun_state_sensor
|
||||
entity_id: sun.sun
|
||||
|
||||
# Weather state sensor
|
||||
- platform: homeassistant
|
||||
id: weather_state_sensor
|
||||
entity_id: "${weather_entity}"
|
||||
on_value:
|
||||
then:
|
||||
- delay: 1s
|
||||
- script.execute:
|
||||
id: weather_get_and_set_translated_state
|
||||
state_str: !lambda 'return id(weather_state_sensor).state;'
|
||||
- script.execute: update_weather_image
|
||||
|
||||
lvgl:
|
||||
pages:
|
||||
- id: home_page
|
||||
bg_color: color_slate_blue_gray
|
||||
widgets:
|
||||
|
||||
# indicators
|
||||
- obj:
|
||||
id: home_bg_indicators
|
||||
y: 20
|
||||
width: 440
|
||||
height: 40
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
bg_color: color_steel_blue
|
||||
bg_opa: 20%
|
||||
border_opa: TRANSP
|
||||
border_width: 0
|
||||
shadow_opa: TRANSP
|
||||
radius: 10
|
||||
widgets:
|
||||
|
||||
# date
|
||||
- label:
|
||||
id: display_date
|
||||
x: 20
|
||||
align: LEFT_MID
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
text: "31.01"
|
||||
|
||||
# Wi-Fi status
|
||||
- label:
|
||||
id: wifi_status
|
||||
align: RIGHT_MID
|
||||
x: -20
|
||||
text: "${wifi_100_icon}"
|
||||
text_color: color_steel_blue
|
||||
text_font: icons_24
|
||||
|
||||
# Home Assistant status
|
||||
- label:
|
||||
id: ha_status
|
||||
align: RIGHT_MID
|
||||
x: -60
|
||||
text: "${ha_icon}"
|
||||
text_color: color_steel_blue
|
||||
text_font: icons_24
|
||||
|
||||
|
||||
# Heating status
|
||||
- label:
|
||||
id: heating_status
|
||||
align: RIGHT_MID
|
||||
x: -100
|
||||
text: "${heating_icon}"
|
||||
text_color: color_steel_blue
|
||||
text_font: icons_24
|
||||
|
||||
# AC status
|
||||
- label:
|
||||
id: ac_status
|
||||
align: RIGHT_MID
|
||||
x: -140
|
||||
y: 2
|
||||
text: "${air_conditioner_icon}"
|
||||
text_color: color_steel_blue
|
||||
text_font: icons_24
|
||||
|
||||
# Lock status
|
||||
- label:
|
||||
id: lock_status
|
||||
align: RIGHT_MID
|
||||
x: -180
|
||||
text: "${lock_icon}"
|
||||
text_color: color_steel_blue
|
||||
text_font: icons_24
|
||||
|
||||
# Alarm panel status
|
||||
# - label:
|
||||
# id: alarm_panel_status
|
||||
# align: RIGHT_MID
|
||||
# x: -220
|
||||
# text: "${shield_arming_icon}"
|
||||
# text_color: color_steel_blue
|
||||
# text_font: mdi_icons_24
|
||||
|
||||
# time
|
||||
- obj:
|
||||
id: home_bg_weather_time
|
||||
x: 20
|
||||
y: 80
|
||||
width: 440
|
||||
height: 220
|
||||
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: display_time
|
||||
align: CENTER
|
||||
text_font: nunito_84 #nunito_64
|
||||
text_color: color_misty_blue
|
||||
text: "23:59"
|
||||
|
||||
# weather
|
||||
- obj:
|
||||
id: home_bg_weather
|
||||
x: 20
|
||||
y: 340
|
||||
width: 440
|
||||
height: 300
|
||||
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:
|
||||
- image:
|
||||
id: weather_sunny_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: sunny_img
|
||||
- image:
|
||||
id: weather_clear_night_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: clear_night_img
|
||||
- image:
|
||||
id: weather_cloudy_image
|
||||
hidden: true
|
||||
y: 20
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: cloudy_img
|
||||
- image:
|
||||
id: weather_partlycloudy_sun_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: partlycloudy_sun_img
|
||||
- image:
|
||||
id: weather_partlycloudy_moon_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: partlycloudy_moon_img
|
||||
- image:
|
||||
id: weather_rainy_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: rainy_img
|
||||
- image:
|
||||
id: weather_pouring_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: pouring_img
|
||||
- image:
|
||||
id: weather_snowy_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: snowy_img
|
||||
- image:
|
||||
id: weather_snowy_rainy_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: snowy_rainy_img
|
||||
- image:
|
||||
id: weather_fog_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: fog_img
|
||||
- image:
|
||||
id: weather_hail_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: hail_img
|
||||
- image:
|
||||
id: weather_lightning_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: lightning_img
|
||||
- image:
|
||||
id: weather_lightning_rainy_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: lightning_rainy_img
|
||||
- image:
|
||||
id: weather_windy_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 25
|
||||
align: TOP_LEFT
|
||||
src: windy_img
|
||||
- image:
|
||||
id: weather_windy_variant_image
|
||||
hidden: true
|
||||
y: 10
|
||||
x: 10
|
||||
align: TOP_LEFT
|
||||
src: windy_variant_img
|
||||
|
||||
- label:
|
||||
x: -10
|
||||
y: 10
|
||||
align: TOP_RIGHT
|
||||
id: weather_temperature
|
||||
text_font: nunito_48
|
||||
text_color: color_misty_blue
|
||||
text: "-25°"
|
||||
|
||||
- label:
|
||||
id: weather_state_label
|
||||
y: -10
|
||||
width: 180
|
||||
height: 30
|
||||
align: BOTTOM_MID
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
long_mode: SCROLL_CIRCULAR
|
||||
text: " "
|
||||
|
||||
# sensors
|
||||
- obj:
|
||||
id: home_bg_sensors
|
||||
x: -20
|
||||
y: 80
|
||||
width: 200
|
||||
height: 200
|
||||
align: TOP_RIGHT
|
||||
pad_all: 0
|
||||
bg_color: color_steel_blue
|
||||
bg_opa: 20%
|
||||
border_opa: TRANSP
|
||||
border_width: 0
|
||||
shadow_opa: TRANSP
|
||||
radius: 10
|
||||
widgets:
|
||||
|
||||
# temperature
|
||||
- obj:
|
||||
y: 20
|
||||
width: 160
|
||||
height: 40
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
bg_opa: TRANSP
|
||||
border_opa: TRANSP
|
||||
border_width: 0
|
||||
shadow_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
id: temperature_sensor_icon
|
||||
align: LEFT_MID
|
||||
x: 20
|
||||
text: "${temperature_icon}"
|
||||
text_color: color_green
|
||||
text_font: icons_28
|
||||
- label:
|
||||
id: temperature_sensor_label
|
||||
align: LEFT_MID
|
||||
x: 55
|
||||
text: " "
|
||||
text_color: color_misty_blue
|
||||
text_font: nunito_16
|
||||
|
||||
# humidity
|
||||
- obj:
|
||||
y: 80
|
||||
width: 160
|
||||
height: 40
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
bg_opa: TRANSP
|
||||
border_opa: TRANSP
|
||||
border_width: 0
|
||||
shadow_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
id: humidity_sensor_icon
|
||||
align: LEFT_MID
|
||||
x: 20
|
||||
text: "${humidity_icon}"
|
||||
text_color: color_blue
|
||||
text_font: icons_28
|
||||
- label:
|
||||
id: humidity_sensor_label
|
||||
align: LEFT_MID
|
||||
x: 55
|
||||
text: " "
|
||||
text_color: color_misty_blue
|
||||
text_font: nunito_16
|
||||
|
||||
# co2
|
||||
- obj:
|
||||
y: 140
|
||||
width: 160
|
||||
height: 40
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
bg_opa: TRANSP
|
||||
border_opa: TRANSP
|
||||
border_width: 0
|
||||
shadow_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
id: co2_sensor_icon
|
||||
align: LEFT_MID
|
||||
x: 20
|
||||
text: "${co2_icon}"
|
||||
text_color: color_yellow
|
||||
text_font: icons_28
|
||||
- label:
|
||||
id: co2_sensor_label
|
||||
align: LEFT_MID
|
||||
x: 55
|
||||
text: " "
|
||||
text_color: color_misty_blue
|
||||
text_font: nunito_16
|
||||
|
||||
# display lock
|
||||
- obj:
|
||||
id: home_bg_display_lock
|
||||
x: 480
|
||||
y: 580
|
||||
width: 60
|
||||
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: display_lock_btn
|
||||
align: CENTER
|
||||
text_font: icons_36
|
||||
text_color: color_misty_blue
|
||||
text: "${lock_icon}"
|
||||
on_long_press:
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(display_lock) == false;'
|
||||
then:
|
||||
- switch.turn_on: display_lock_switch
|
||||
else:
|
||||
- switch.turn_off: display_lock_switch
|
||||
|
||||
# display backlight off
|
||||
- obj:
|
||||
id: home_bg_display_backlight_off
|
||||
x: 550
|
||||
y: 580
|
||||
width: 60
|
||||
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: display_backlight_off_btn
|
||||
align: CENTER
|
||||
text_font: icons_36
|
||||
text_color: color_misty_blue
|
||||
text: "${lightbulb_icon}"
|
||||
on_click:
|
||||
- delay: 1s
|
||||
- light.turn_off: display_backlight
|
||||
- lvgl.pause:
|
||||
|
||||
# display info
|
||||
- obj:
|
||||
id: home_bg_display_info
|
||||
x: 620
|
||||
y: 580
|
||||
width: 60
|
||||
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: display_info_btn
|
||||
align: CENTER
|
||||
text_font: icons_36
|
||||
text_color: color_misty_blue
|
||||
text: "${info_icon}"
|
||||
on_press:
|
||||
- lvgl.page.show:
|
||||
id: system_info_page
|
||||
animation: OUT_RIGHT
|
||||
time: 300ms
|
||||
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
id: sntp_time
|
||||
timezone: Europe/Moscow
|
||||
servers:
|
||||
- ntp0.ntp-servers.net
|
||||
- ntp1.ntp-servers.net
|
||||
- ntp2.ntp-servers.net
|
||||
on_time_sync:
|
||||
- script.execute: time_update
|
||||
on_time:
|
||||
- minutes: '*'
|
||||
seconds: 0
|
||||
then:
|
||||
- script.execute: time_update
|
||||
|
||||
script:
|
||||
|
||||
- id: time_update
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: display_time
|
||||
text: !lambda |-
|
||||
static char time_buf[16];
|
||||
auto now = id(sntp_time).now();
|
||||
snprintf(time_buf, sizeof(time_buf), "%02d:%02d", now.hour, now.minute);
|
||||
return time_buf;
|
||||
|
||||
- lvgl.label.update:
|
||||
id: display_date
|
||||
text: !lambda |-
|
||||
static char date_buf[16];
|
||||
auto now = id(sntp_time).now();
|
||||
snprintf(date_buf, sizeof(date_buf), "%02d.%02d", now.day_of_month, now.month);
|
||||
return date_buf;
|
||||
|
||||
- id: weather_get_and_set_translated_state
|
||||
parameters:
|
||||
state_str: string
|
||||
then:
|
||||
- lambda: |-
|
||||
std::string state = state_str;
|
||||
|
||||
auto it = id(weather_translations).find(state);
|
||||
std::string translated_state = (it != id(weather_translations).end()) ? it->second : state;
|
||||
|
||||
lv_label_set_text(id(weather_state_label), translated_state.c_str());
|
||||
|
||||
- id: update_weather_image
|
||||
then:
|
||||
- lambda: |-
|
||||
std::string weather = id(weather_state_sensor).state;
|
||||
bool is_night = (id(sun_state_sensor).state == "below_horizon");
|
||||
|
||||
if (weather == "cloudy") {
|
||||
lv_obj_clear_flag(id(weather_cloudy_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "partlycloudy") {
|
||||
if (is_night) {
|
||||
lv_obj_clear_flag(id(weather_partlycloudy_moon_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_clear_flag(id(weather_partlycloudy_sun_image), LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
} else if (weather == "sunny" || weather == "clear-night") {
|
||||
if (is_night) {
|
||||
lv_obj_clear_flag(id(weather_clear_night_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_clear_flag(id(weather_sunny_image), LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
} else if (weather == "rainy") {
|
||||
lv_obj_clear_flag(id(weather_rainy_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "lightning-rainy") {
|
||||
lv_obj_clear_flag(id(weather_lightning_rainy_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "lightning") {
|
||||
lv_obj_clear_flag(id(weather_lightning_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "pouring") {
|
||||
lv_obj_clear_flag(id(weather_pouring_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "snowy") {
|
||||
lv_obj_clear_flag(id(weather_snowy_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "snowy-rainy") {
|
||||
lv_obj_clear_flag(id(weather_snowy_rainy_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "fog") {
|
||||
lv_obj_clear_flag(id(weather_fog_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "hail") {
|
||||
lv_obj_clear_flag(id(weather_hail_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "windy") {
|
||||
lv_obj_clear_flag(id(weather_windy_image), LV_OBJ_FLAG_HIDDEN);
|
||||
} else if (weather == "windy-variant") {
|
||||
lv_obj_clear_flag(id(weather_windy_variant_image), LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
select:
|
||||
- platform: lvgl
|
||||
widget: language_dropdown
|
||||
id: weather_select_language
|
||||
on_value:
|
||||
then:
|
||||
- lambda: |-
|
||||
ESP_LOGI("LANGUAGE", "Language changed, updating weather translations");
|
||||
- delay: 300ms
|
||||
- script.execute:
|
||||
id: weather_get_and_set_translated_state
|
||||
state_str: !lambda 'return id(weather_state_sensor).state;'
|
||||
- lambda: |-
|
||||
ESP_LOGI("LANGUAGE", "Weather translations updated");
|
||||
|
||||
esphome:
|
||||
on_boot:
|
||||
priority: -100
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(weather_state_sensor).has_state();'
|
||||
then:
|
||||
- script.execute:
|
||||
id: weather_get_and_set_translated_state
|
||||
state_str: !lambda 'return id(weather_state_sensor).state;'
|
||||
|
||||
# - if:
|
||||
# condition:
|
||||
# lambda: 'return id(display_lock) == true;'
|
||||
# then:
|
||||
# - switch.turn_on: display_lock_switch
|
||||
# else:
|
||||
# - switch.turn_off: display_lock_switch
|
||||
|
||||
|
||||
api:
|
||||
on_client_connected:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return (0 == client_info.find("Home Assistant "));'
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: ha_status
|
||||
text_color: color_blue
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(weather_state_sensor).has_state();'
|
||||
then:
|
||||
- script.execute:
|
||||
id: weather_get_and_set_translated_state
|
||||
state_str: !lambda 'return id(weather_state_sensor).state;'
|
||||
|
||||
# - if:
|
||||
# condition:
|
||||
# lambda: 'return id(display_lock) == true;'
|
||||
# then:
|
||||
# - switch.turn_on: display_lock_switch
|
||||
# else:
|
||||
# - switch.turn_off: display_lock_switch
|
||||
|
||||
on_client_disconnected:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return (0 == client_info.find("Home Assistant "));'
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: ha_status
|
||||
text_color: color_steel_blue
|
||||
|
||||
switch:
|
||||
- platform: template
|
||||
name: "Touchscreen block"
|
||||
id: display_lock_switch
|
||||
lambda: |-
|
||||
return id(display_lock);
|
||||
turn_on_action:
|
||||
- lambda: 'id(display_lock) = true;'
|
||||
- lvgl.button.update:
|
||||
id: home_page_btn
|
||||
clickable: false
|
||||
- lvgl.button.update:
|
||||
id: lights_group_page_btn
|
||||
clickable: false
|
||||
- lvgl.button.update:
|
||||
id: devices_page_btn
|
||||
clickable: false
|
||||
- lvgl.button.update:
|
||||
id: settings_page_btn
|
||||
clickable: false
|
||||
- lvgl.label.update:
|
||||
id: lock_status
|
||||
text_color: color_green
|
||||
turn_off_action:
|
||||
- lambda: 'id(display_lock) = false;'
|
||||
- lvgl.button.update:
|
||||
id: home_page_btn
|
||||
clickable: true
|
||||
- lvgl.button.update:
|
||||
id: lights_group_page_btn
|
||||
clickable: true
|
||||
- lvgl.button.update:
|
||||
id: devices_page_btn
|
||||
clickable: true
|
||||
- lvgl.button.update:
|
||||
id: settings_page_btn
|
||||
clickable: true
|
||||
- lvgl.label.update:
|
||||
id: lock_status
|
||||
text_color: color_steel_blue
|
||||
380
esphome/widgets/home/info_page.yaml
Normal file
380
esphome/widgets/home/info_page.yaml
Normal file
@@ -0,0 +1,380 @@
|
||||
# System sensors
|
||||
sensor:
|
||||
# 1. Total SRAM memory usage
|
||||
- platform: template
|
||||
name: "SRAM Usage"
|
||||
id: sram_usage
|
||||
icon: mdi:memory
|
||||
unit_of_measurement: "KB"
|
||||
device_class: data_size
|
||||
state_class: measurement
|
||||
accuracy_decimals: 1
|
||||
update_interval: 10s
|
||||
lambda: |-
|
||||
// Total SRAM size for ESP32-S3 = 512KB
|
||||
const size_t total_sram = 512 * 1024;
|
||||
size_t free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
size_t used_sram = total_sram - free_sram;
|
||||
return used_sram / 1024.0; // Return used memory in KB
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.bar.update:
|
||||
id: sram_memory_bar
|
||||
value: !lambda |-
|
||||
const size_t total_sram = 512 * 1024; // 512KB for ESP32-S3
|
||||
size_t free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
size_t used_sram = total_sram - free_sram;
|
||||
return (int)(((double)used_sram / total_sram) * 100);
|
||||
- lvgl.label.update:
|
||||
id: sram_memory_label
|
||||
text: !lambda |-
|
||||
const size_t total_sram = 512 * 1024;
|
||||
size_t free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
size_t used_sram = total_sram - free_sram;
|
||||
static char sram_buf[32];
|
||||
snprintf(sram_buf, sizeof(sram_buf), "%.1f/%.0f KB",
|
||||
used_sram/1024.0, total_sram/1024.0);
|
||||
return sram_buf;
|
||||
|
||||
# 2. Total PSRAM memory usage
|
||||
- platform: template
|
||||
name: "PSRAM Usage"
|
||||
id: psram_usage
|
||||
icon: mdi:memory
|
||||
unit_of_measurement: "MB"
|
||||
device_class: data_size
|
||||
state_class: measurement
|
||||
accuracy_decimals: 1
|
||||
update_interval: 10s
|
||||
lambda: |-
|
||||
// Total PSRAM size = 8MB
|
||||
const size_t total_psram = 8 * 1024 * 1024;
|
||||
size_t free_psram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||
|
||||
// If PSRAM is not available, return 0
|
||||
if (heap_caps_get_total_size(MALLOC_CAP_SPIRAM) == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
size_t used_psram = total_psram - free_psram;
|
||||
return used_psram / (1024.0 * 1024.0); // Return used memory in MB
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.bar.update:
|
||||
id: psram_memory_bar
|
||||
value: !lambda |-
|
||||
const size_t total_psram = 8 * 1024 * 1024; // 8MB
|
||||
size_t free_psram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||
|
||||
if (heap_caps_get_total_size(MALLOC_CAP_SPIRAM) == 0) return 0;
|
||||
|
||||
size_t used_psram = total_psram - free_psram;
|
||||
return (int)(((double)used_psram / total_psram) * 100);
|
||||
- lvgl.label.update:
|
||||
id: psram_memory_label
|
||||
text: !lambda |-
|
||||
const size_t total_psram = 8 * 1024 * 1024;
|
||||
size_t free_psram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||
static char psram_buf[32];
|
||||
|
||||
if (heap_caps_get_total_size(MALLOC_CAP_SPIRAM) == 0) {
|
||||
snprintf(psram_buf, sizeof(psram_buf), "No PSRAM");
|
||||
} else {
|
||||
size_t used_psram = total_psram - free_psram;
|
||||
snprintf(psram_buf, sizeof(psram_buf), "%.1f/%.0f MB",
|
||||
used_psram/(1024.0*1024.0), total_psram/(1024.0*1024.0));
|
||||
}
|
||||
return psram_buf;
|
||||
|
||||
# 3. Chip temperature
|
||||
- platform: internal_temperature
|
||||
name: "ESP32 Internal Temperature"
|
||||
id: esp32_temperature
|
||||
update_interval: 30s
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: chip_temperature_label
|
||||
text:
|
||||
format: "%.1f°C"
|
||||
args: [id(esp32_temperature).state]
|
||||
|
||||
# 4. WiFi Signal Strength in dBm
|
||||
- platform: wifi_signal
|
||||
name: "WiFi Signal"
|
||||
id: wifi_signal_db
|
||||
update_interval: 30s
|
||||
unit_of_measurement: "dBm"
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: wifi_signal_label
|
||||
text:
|
||||
format: "%.0f dBm"
|
||||
args: [id(wifi_signal_db).state]
|
||||
|
||||
# Text sensors for WiFi information
|
||||
text_sensor:
|
||||
# 5. IP address
|
||||
- platform: wifi_info
|
||||
ip_address:
|
||||
name: "IP Address"
|
||||
id: wifi_ip_address
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: ip_address_label
|
||||
text: !lambda return id(wifi_ip_address).state.c_str();
|
||||
|
||||
# 6. MAC address
|
||||
- platform: wifi_info
|
||||
mac_address:
|
||||
name: "WiFi MAC"
|
||||
id: wifi_mac_address
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: wifi_mac_label
|
||||
text: !lambda return id(wifi_mac_address).state.c_str();
|
||||
|
||||
# 7. ESPHome version with compilation date
|
||||
- platform: template
|
||||
name: "ESPHome Version"
|
||||
id: esphome_version
|
||||
lambda: |-
|
||||
return {ESPHOME_VERSION};
|
||||
on_value:
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: esphome_version_label
|
||||
text: !lambda 'return id(esphome_version).state;'
|
||||
|
||||
# LVGL interface for displaying system information
|
||||
lvgl:
|
||||
pages:
|
||||
- id: system_info_page
|
||||
bg_color: color_slate_blue_gray
|
||||
widgets:
|
||||
- obj:
|
||||
id: system_info_container
|
||||
x: 20
|
||||
y: 20
|
||||
width: 440
|
||||
height: 340
|
||||
align: TOP_LEFT
|
||||
pad_all: 0
|
||||
bg_color: color_steel_blue
|
||||
bg_opa: 20%
|
||||
border_opa: TRANSP
|
||||
radius: 10
|
||||
widgets:
|
||||
# SRAM memory (show used from total)
|
||||
- obj:
|
||||
y: 10
|
||||
width: 400
|
||||
height: 50
|
||||
align: TOP_MID
|
||||
bg_opa: TRANSP
|
||||
pad_all: 0
|
||||
border_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
align: TOP_LEFT
|
||||
text: "SRAM Used:"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
- label:
|
||||
id: sram_memory_label
|
||||
align: TOP_RIGHT
|
||||
text: "0/512 KB"
|
||||
text_font: nunito_16
|
||||
text_color: color_green
|
||||
- bar:
|
||||
id: sram_memory_bar
|
||||
y: 30
|
||||
width: 390
|
||||
height: 12
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
min_value: 0
|
||||
max_value: 100
|
||||
value: 0
|
||||
bg_color: color_gray
|
||||
bg_opa: 50%
|
||||
indicator:
|
||||
bg_color: color_green
|
||||
|
||||
# PSRAM memory (show used from total)
|
||||
- obj:
|
||||
y: 70
|
||||
width: 400
|
||||
height: 50
|
||||
align: TOP_MID
|
||||
bg_opa: TRANSP
|
||||
pad_all: 0
|
||||
border_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
align: TOP_LEFT
|
||||
text: "PSRAM Used:"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
- label:
|
||||
id: psram_memory_label
|
||||
align: TOP_RIGHT
|
||||
text: "0/8 MB"
|
||||
text_font: nunito_16
|
||||
text_color: color_blue
|
||||
- bar:
|
||||
id: psram_memory_bar
|
||||
y: 30
|
||||
width: 390
|
||||
height: 12
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
min_value: 0
|
||||
max_value: 100
|
||||
value: 0
|
||||
bg_color: color_gray
|
||||
bg_opa: 50%
|
||||
indicator:
|
||||
bg_color: color_blue
|
||||
|
||||
# Chip temperature
|
||||
- obj:
|
||||
y: 130
|
||||
width: 400
|
||||
height: 30
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
bg_opa: TRANSP
|
||||
border_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
align: LEFT_MID
|
||||
text: "CPU Temperature:"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
- label:
|
||||
id: chip_temperature_label
|
||||
align: RIGHT_MID
|
||||
text: "0°C"
|
||||
text_font: nunito_16
|
||||
text_color: color_yellow
|
||||
|
||||
# WiFi signal
|
||||
- obj:
|
||||
y: 170
|
||||
width: 400
|
||||
height: 30
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
bg_opa: TRANSP
|
||||
border_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
align: LEFT_MID
|
||||
text: "WiFi Signal:"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
- label:
|
||||
id: wifi_signal_label
|
||||
align: RIGHT_MID
|
||||
text: "0 dBm"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
|
||||
# IP Address
|
||||
- obj:
|
||||
y: 210
|
||||
width: 400
|
||||
height: 30
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
bg_opa: TRANSP
|
||||
border_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
align: LEFT_MID
|
||||
text: "IP Address:"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
- label:
|
||||
id: ip_address_label
|
||||
align: RIGHT_MID
|
||||
text: "192.168.3.3"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
|
||||
# MAC Address
|
||||
- obj:
|
||||
y: 250
|
||||
width: 400
|
||||
height: 30
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
bg_opa: TRANSP
|
||||
border_color: color_white
|
||||
border_width: 1
|
||||
border_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
align: LEFT_MID
|
||||
text: "MAC Address:"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
- label:
|
||||
id: wifi_mac_label
|
||||
align: RIGHT_MID
|
||||
text: "11:22:A1:B2:C3:D4"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
|
||||
# ESPHome version
|
||||
- obj:
|
||||
y: 290
|
||||
width: 400
|
||||
height: 30
|
||||
align: TOP_MID
|
||||
pad_all: 0
|
||||
bg_opa: TRANSP
|
||||
border_opa: TRANSP
|
||||
widgets:
|
||||
- label:
|
||||
align: LEFT_MID
|
||||
text: "ESPHome Version:"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
- label:
|
||||
id: esphome_version_label
|
||||
align: RIGHT_MID
|
||||
text: "2020.0.0"
|
||||
text_font: nunito_16
|
||||
text_color: color_misty_blue
|
||||
|
||||
# Interval for periodic logging
|
||||
interval:
|
||||
- interval: 60s
|
||||
then:
|
||||
- lambda: |-
|
||||
// Log real memory usage
|
||||
const size_t total_sram = 512 * 1024;
|
||||
const size_t total_psram = 8 * 1024 * 1024;
|
||||
|
||||
size_t free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
size_t used_sram = total_sram - free_sram;
|
||||
|
||||
size_t free_psram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||
size_t used_psram = total_psram - free_psram;
|
||||
|
||||
ESP_LOGI("system_info", "SRAM: %u/%u KB used (%.1f%%)",
|
||||
used_sram/1024, total_sram/1024,
|
||||
(used_sram * 100.0) / total_sram);
|
||||
|
||||
if (heap_caps_get_total_size(MALLOC_CAP_SPIRAM) > 0) {
|
||||
ESP_LOGI("system_info", "PSRAM: %u/%u MB used (%.1f%%)",
|
||||
used_psram/(1024*1024), total_psram/(1024*1024),
|
||||
(used_psram * 100.0) / total_psram);
|
||||
} else {
|
||||
ESP_LOGI("system_info", "PSRAM: Not available");
|
||||
}
|
||||
Reference in New Issue
Block a user