mirror of
https://github.com/randybb/esphome-configs.git
synced 2026-10-14 08:35:12 +02:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
148c51c4df | ||
|
|
cc2ab4c467 | ||
|
|
504aa06d10 | ||
|
|
4b6544adfa | ||
|
|
6a51099789 |
No files matched your search
@@ -0,0 +1,19 @@
|
||||
---
|
||||
# IPv6-only IoT network (SLAAC, no DHCPv4); add next to a common package:
|
||||
# packages:
|
||||
# common: !include common/common.yaml
|
||||
# ipv6_only: !include common/ipv6_only.yaml
|
||||
external_components:
|
||||
# wifi ipv6_only (esphome/esphome#19750), drop once merged
|
||||
- source: github://pr#19750
|
||||
components: [const, network, wifi]
|
||||
|
||||
wifi:
|
||||
ipv6_only: true
|
||||
networks:
|
||||
- id: !extend wifi_iot
|
||||
ssid: !secret wifi_ssid_ipv6
|
||||
password: !secret wifi_password_ipv6
|
||||
|
||||
network:
|
||||
min_ipv6_addr_count: 1
|
||||
+3
-1
@@ -2,7 +2,9 @@
|
||||
wifi:
|
||||
# reboot_timeout: 0s
|
||||
networks:
|
||||
- ssid: !secret wifi_ssid
|
||||
# id lets devices override the network with '!extend wifi_iot'
|
||||
- id: wifi_iot
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_password
|
||||
enable_btm: true
|
||||
enable_rrm: true
|
||||
|
||||
@@ -23,6 +23,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# GPIO21 UART TX
|
||||
# GPIO20 UART RX
|
||||
|
||||
@@ -19,6 +19,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# Mi Desk Lamp
|
||||
# Pin Function (Name)
|
||||
|
||||
@@ -34,6 +34,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# fan:
|
||||
# - platform: speed
|
||||
|
||||
@@ -27,6 +27,7 @@ external_components:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
|
||||
# PINOUTS: M5ATOM+Atom Hub Switch
|
||||
|
||||
@@ -19,6 +19,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# PINOUTS: M5ATOM
|
||||
# IR G12
|
||||
|
||||
@@ -37,6 +37,7 @@ external_components:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# PINOUTS: M5ATOM
|
||||
# IR G12
|
||||
|
||||
@@ -36,6 +36,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
api:
|
||||
reboot_timeout: 300s
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
---
|
||||
substitutions:
|
||||
device: lvgl-4848s040
|
||||
name: LVGL 4848S040
|
||||
area: DEV
|
||||
comment: "${area} | Guition ESP32-S3-4848S040"
|
||||
|
||||
esphome:
|
||||
name: mcu-${device}
|
||||
friendly_name: ${name}
|
||||
area: ${area}
|
||||
comment: ${comment}
|
||||
on_boot:
|
||||
- priority: -100
|
||||
then:
|
||||
- lvgl.page.show: status_page
|
||||
|
||||
esp32:
|
||||
variant: esp32s3
|
||||
flash_size: 16MB
|
||||
framework:
|
||||
type: esp-idf
|
||||
# PSRAM bandwidth for the RGB panel (not set by ESPHome); without it the
|
||||
# image shifts during flash/WiFi activity
|
||||
sdkconfig_options:
|
||||
CONFIG_ESP32S3_DATA_CACHE_64KB: y
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
|
||||
CONFIG_SPIRAM_RODATA: y
|
||||
|
||||
psram:
|
||||
mode: octal
|
||||
speed: 80MHz
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# PINOUTS: Guition ESP32-S3-4848S040, 4", 480x480, ST7701S, capacitive
|
||||
## Display (RGB, pins in the mipi_rgb model)
|
||||
# CS 39
|
||||
# SCK 48 ST7701S init (3-wire SPI)
|
||||
# SDA 47
|
||||
# DE 18
|
||||
# HSYNC 16
|
||||
# VSYNC 17
|
||||
# PCLK 21
|
||||
# BL 38
|
||||
## Capacitive Touch (GT911)
|
||||
# TP_SDA 19
|
||||
# TP_SCL 45
|
||||
## Relays (86 box variant)
|
||||
# RELAY1 40
|
||||
# RELAY2 2
|
||||
# RELAY3 1
|
||||
|
||||
api:
|
||||
# status page until Home Assistant connects (log viewers don't subscribe to states)
|
||||
on_client_connected:
|
||||
- delay: 2s
|
||||
- if:
|
||||
condition:
|
||||
api.connected:
|
||||
state_subscription_only: true
|
||||
then:
|
||||
- lvgl.page.show: main_page
|
||||
on_client_disconnected:
|
||||
- if:
|
||||
condition:
|
||||
not:
|
||||
api.connected:
|
||||
state_subscription_only: true
|
||||
then:
|
||||
- lvgl.page.show: status_page
|
||||
|
||||
i2c:
|
||||
- id: i2c_main
|
||||
sda: 19
|
||||
scl: 45
|
||||
scan: true
|
||||
|
||||
spi:
|
||||
- id: lcd_spi
|
||||
clk_pin: 48
|
||||
mosi_pin: 47
|
||||
|
||||
display:
|
||||
- platform: mipi_rgb
|
||||
model: GUITION-4848S040
|
||||
id: main_display
|
||||
spi_id: lcd_spi
|
||||
update_interval: never
|
||||
auto_clear_enabled: false
|
||||
|
||||
touchscreen:
|
||||
- platform: gt911
|
||||
id: main_touch
|
||||
display: main_display
|
||||
i2c_id: i2c_main
|
||||
# the mipi_rgb model mirrors the image on both axes, touch has to follow
|
||||
transform:
|
||||
mirror_x: true
|
||||
mirror_y: true
|
||||
|
||||
output:
|
||||
- platform: ledc
|
||||
id: gpio_backlight_pwm
|
||||
pin: 38
|
||||
frequency: 1220
|
||||
|
||||
light:
|
||||
- platform: monochromatic
|
||||
id: back_light
|
||||
name: Backlight
|
||||
output: gpio_backlight_pwm
|
||||
restore_mode: ALWAYS_ON
|
||||
|
||||
script:
|
||||
- id: update_status
|
||||
then:
|
||||
- lambda: |-
|
||||
// same colors as the other status screens: ok green, waiting orange, details gray
|
||||
static const uint32_t OK = 0x4DD966, WAIT = 0xFFB300;
|
||||
auto set = [](lv_obj_t *label, const std::string &text, uint32_t color) {
|
||||
lv_label_set_text(label, text.c_str());
|
||||
lv_obj_set_style_text_color(label, lv_color_hex(color), LV_PART_MAIN);
|
||||
};
|
||||
|
||||
const bool wifi_ok = wifi::global_wifi_component->is_connected();
|
||||
set(id(status_wifi),
|
||||
wifi_ok ? str_sprintf("WiFi: connected (%d dBm)", wifi::global_wifi_component->wifi_rssi())
|
||||
: std::string("WiFi: connecting..."),
|
||||
wifi_ok ? OK : WAIT);
|
||||
|
||||
// IPv6 first (skip link-local), then IPv4
|
||||
std::string ips;
|
||||
if (wifi_ok) {
|
||||
char buf[network::IP_ADDRESS_BUFFER_SIZE];
|
||||
for (bool v6 : {true, false}) {
|
||||
for (auto &ip : wifi::global_wifi_component->get_ip_addresses()) {
|
||||
if (!ip.is_set() || ip.is_ip6() != v6)
|
||||
continue;
|
||||
ip.str_to(buf);
|
||||
if (v6 && strncmp(buf, "fe80", 4) == 0)
|
||||
continue;
|
||||
if (!ips.empty())
|
||||
ips += "\n";
|
||||
ips += buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
lv_label_set_text(id(status_ips), ips.c_str());
|
||||
if (ips.empty())
|
||||
lv_obj_add_flag(id(status_ips), LV_OBJ_FLAG_HIDDEN);
|
||||
else
|
||||
lv_obj_remove_flag(id(status_ips), LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
const bool api_ok = api::global_api_server->is_connected();
|
||||
set(id(status_ha), api_ok ? "Home Assistant: connected" : "Home Assistant: waiting...",
|
||||
api_ok ? OK : WAIT);
|
||||
|
||||
const uint32_t up = millis() / 1000;
|
||||
lv_label_set_text(id(status_footer),
|
||||
str_sprintf("ESPHome %s · up %ud %02u:%02u:%02u", ESPHOME_VERSION, up / 86400,
|
||||
(up / 3600) % 24, (up / 60) % 60, up % 60).c_str());
|
||||
|
||||
interval:
|
||||
- interval: 1s
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: clock_label
|
||||
text: !lambda |-
|
||||
auto now = id(ha_time).now();
|
||||
if (!now.is_valid())
|
||||
return std::string("--:--");
|
||||
return now.strftime("%H:%M");
|
||||
- if:
|
||||
condition:
|
||||
lvgl.page.is_showing: status_page
|
||||
then:
|
||||
- script.execute: update_status
|
||||
|
||||
image:
|
||||
- platform: file
|
||||
file: assets/images/made-for-esphome-white-on-black.svg
|
||||
id: esphome_logo
|
||||
resize: 320x95
|
||||
type: RGB565
|
||||
transparency: alpha_channel
|
||||
|
||||
font:
|
||||
- file: "gfonts://Roboto@500"
|
||||
id: font_clock
|
||||
size: 150
|
||||
glyphs: "0123456789:-"
|
||||
- file: "gfonts://Roboto"
|
||||
id: font_title
|
||||
size: 32
|
||||
- file: "gfonts://Roboto"
|
||||
id: font_status
|
||||
size: 20
|
||||
glyphs: "·"
|
||||
glyphsets: [GF_Latin_Kernel]
|
||||
|
||||
lvgl:
|
||||
log_level: WARN
|
||||
color_depth: 16
|
||||
bg_color: 0x000000
|
||||
text_color: 0xFFFFFF
|
||||
theme:
|
||||
buttonmatrix:
|
||||
bg_opa: TRANSP
|
||||
border_width: 0
|
||||
items:
|
||||
bg_color: 0x2B2F36
|
||||
text_color: 0xFFFFFF
|
||||
radius: 12
|
||||
checked:
|
||||
bg_color: 0xE08A00
|
||||
top_layer:
|
||||
widgets:
|
||||
# same navigation bar as on mcu-lvgl-trainer
|
||||
- buttonmatrix:
|
||||
id: nav_bar
|
||||
align: bottom_mid
|
||||
width: 100%
|
||||
height: 60
|
||||
pad_all: 4
|
||||
pad_column: 6
|
||||
items:
|
||||
text_font: montserrat_28
|
||||
rows:
|
||||
- buttons:
|
||||
- id: page_prev
|
||||
text: ""
|
||||
on_press:
|
||||
then:
|
||||
lvgl.page.previous:
|
||||
- id: page_home
|
||||
text: ""
|
||||
on_press:
|
||||
then:
|
||||
lvgl.page.show: main_page
|
||||
- id: page_next
|
||||
text: ""
|
||||
on_press:
|
||||
then:
|
||||
lvgl.page.next:
|
||||
pages:
|
||||
# 1: clock
|
||||
- id: main_page
|
||||
widgets:
|
||||
- label:
|
||||
id: clock_label
|
||||
align: CENTER
|
||||
y: -30
|
||||
text_font: font_clock
|
||||
text: "--:--"
|
||||
|
||||
# 2: status (shown until Home Assistant connects)
|
||||
- id: status_page
|
||||
on_load:
|
||||
- script.execute: update_status
|
||||
widgets:
|
||||
- image:
|
||||
src: esphome_logo
|
||||
align: TOP_MID
|
||||
y: 16
|
||||
- label:
|
||||
align: TOP_MID
|
||||
y: 120
|
||||
text_font: font_title
|
||||
text: "${name}"
|
||||
- obj:
|
||||
id: status_lines
|
||||
x: 24
|
||||
y: 170
|
||||
width: 440
|
||||
height: SIZE_CONTENT
|
||||
bg_opa: TRANSP
|
||||
border_width: 0
|
||||
pad_all: 0
|
||||
scrollbar_mode: "OFF"
|
||||
layout:
|
||||
type: flex
|
||||
flex_flow: column
|
||||
pad_row: 6
|
||||
widgets:
|
||||
- label:
|
||||
id: status_wifi
|
||||
text_font: font_status
|
||||
text: ""
|
||||
- label:
|
||||
id: status_ips
|
||||
text_font: font_status
|
||||
text_color: 0x8C8C8C
|
||||
pad_left: 20
|
||||
text: ""
|
||||
- label:
|
||||
id: status_ha
|
||||
text_font: font_status
|
||||
text: ""
|
||||
- label:
|
||||
id: status_footer
|
||||
text_font: font_status
|
||||
text_color: 0x8C8C8C
|
||||
text: ""
|
||||
+80
-35
@@ -26,6 +26,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
i2c:
|
||||
- id: touchscreen_bus
|
||||
@@ -240,8 +241,8 @@ script:
|
||||
- lvgl.label.update:
|
||||
id: stopwatch_label
|
||||
text: !lambda |-
|
||||
const uint32_t ms = id(sw_accum) + (id(sw_running) ? millis() - id(sw_start) : 0);
|
||||
const uint32_t s = ms / 1000;
|
||||
const unsigned ms = id(sw_accum) + (id(sw_running) ? millis() - id(sw_start) : 0);
|
||||
const unsigned s = ms / 1000;
|
||||
if (s >= 3600)
|
||||
return str_sprintf("%u:%02u:%02u", s / 3600, (s / 60) % 60, s % 60);
|
||||
return str_sprintf("%02u:%02u.%u", s / 60, s % 60, (ms / 100) % 10);
|
||||
@@ -252,35 +253,51 @@ script:
|
||||
|
||||
- id: update_status
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: status_label
|
||||
text: !lambda |-
|
||||
std::string out;
|
||||
if (wifi::global_wifi_component->is_connected()) {
|
||||
out = str_sprintf("WiFi: connected (%d dBm)", wifi::global_wifi_component->wifi_rssi());
|
||||
// IPv6 first (skip link-local), then IPv4
|
||||
char buf[network::IP_ADDRESS_BUFFER_SIZE];
|
||||
for (bool v6 : {true, false}) {
|
||||
for (auto &ip : wifi::global_wifi_component->get_ip_addresses()) {
|
||||
if (!ip.is_set() || ip.is_ip6() != v6)
|
||||
continue;
|
||||
ip.str_to(buf);
|
||||
if (v6 && strncmp(buf, "fe80", 4) == 0)
|
||||
continue;
|
||||
out += "\n ";
|
||||
out += buf;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out = "WiFi: connecting...";
|
||||
}
|
||||
out += api::global_api_server->is_connected_with_state_subscription() ? "\nHome Assistant: connected"
|
||||
: "\nHome Assistant: waiting...";
|
||||
const uint32_t up = millis() / 1000;
|
||||
out += str_sprintf("\nESPHome %s · up %ud %02u:%02u", ESPHOME_VERSION, up / 86400, (up / 3600) % 24,
|
||||
(up / 60) % 60);
|
||||
return out;
|
||||
- lambda: |-
|
||||
// same colors as the other status screens: ok green, waiting orange, details gray
|
||||
static const uint32_t OK = 0x4DD966, WAIT = 0xFFB300;
|
||||
auto set = [](lv_obj_t *label, const std::string &text, uint32_t color) {
|
||||
lv_label_set_text(label, text.c_str());
|
||||
lv_obj_set_style_text_color(label, lv_color_hex(color), LV_PART_MAIN);
|
||||
};
|
||||
|
||||
const bool wifi_ok = wifi::global_wifi_component->is_connected();
|
||||
set(id(status_wifi),
|
||||
wifi_ok ? str_sprintf("WiFi: connected (%d dBm)", wifi::global_wifi_component->wifi_rssi())
|
||||
: std::string("WiFi: connecting..."),
|
||||
wifi_ok ? OK : WAIT);
|
||||
|
||||
// IPv6 first (skip link-local), then IPv4
|
||||
std::string ips;
|
||||
if (wifi_ok) {
|
||||
char buf[network::IP_ADDRESS_BUFFER_SIZE];
|
||||
for (bool v6 : {true, false}) {
|
||||
for (auto &ip : wifi::global_wifi_component->get_ip_addresses()) {
|
||||
if (!ip.is_set() || ip.is_ip6() != v6)
|
||||
continue;
|
||||
ip.str_to(buf);
|
||||
if (v6 && strncmp(buf, "fe80", 4) == 0)
|
||||
continue;
|
||||
if (!ips.empty())
|
||||
ips += "\n";
|
||||
ips += buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
lv_label_set_text(id(status_ips), ips.c_str());
|
||||
if (ips.empty())
|
||||
lv_obj_add_flag(id(status_ips), LV_OBJ_FLAG_HIDDEN);
|
||||
else
|
||||
lv_obj_remove_flag(id(status_ips), LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
const bool api_ok = api::global_api_server->is_connected();
|
||||
set(id(status_ha), api_ok ? "Home Assistant: connected" : "Home Assistant: waiting...",
|
||||
api_ok ? OK : WAIT);
|
||||
|
||||
const uint32_t up = millis() / 1000;
|
||||
lv_label_set_text(id(status_footer),
|
||||
str_sprintf("ESPHome %s · up %ud %02u:%02u:%02u", ESPHOME_VERSION, up / 86400,
|
||||
(up / 3600) % 24, (up / 60) % 60, up % 60).c_str());
|
||||
interval:
|
||||
- interval: 1s
|
||||
then:
|
||||
@@ -697,9 +714,37 @@ lvgl:
|
||||
align: TOP_MID
|
||||
y: 96
|
||||
text: "${name}"
|
||||
- label:
|
||||
id: status_label
|
||||
- obj:
|
||||
id: status_lines
|
||||
x: 20
|
||||
y: 130
|
||||
text_font: font_small
|
||||
text: ""
|
||||
y: 126
|
||||
width: 440
|
||||
height: SIZE_CONTENT
|
||||
bg_opa: TRANSP
|
||||
border_width: 0
|
||||
pad_all: 0
|
||||
scrollbar_mode: "OFF"
|
||||
layout:
|
||||
type: flex
|
||||
flex_flow: column
|
||||
pad_row: 4
|
||||
widgets:
|
||||
- label:
|
||||
id: status_wifi
|
||||
text_font: font_small
|
||||
text: ""
|
||||
- label:
|
||||
id: status_ips
|
||||
text_font: font_small
|
||||
text_color: 0x8C8C8C
|
||||
pad_left: 16
|
||||
text: ""
|
||||
- label:
|
||||
id: status_ha
|
||||
text_font: font_small
|
||||
text: ""
|
||||
- label:
|
||||
id: status_footer
|
||||
text_font: font_small
|
||||
text_color: 0x8C8C8C
|
||||
text: ""
|
||||
+218
-541
@@ -10,8 +10,10 @@ esphome:
|
||||
friendly_name: ${name}
|
||||
area: ${area}
|
||||
comment: ${comment}
|
||||
platformio_options:
|
||||
board_build.flash_mode: dio
|
||||
on_boot:
|
||||
- priority: -100
|
||||
then:
|
||||
- lvgl.page.show: status_page
|
||||
|
||||
esp32:
|
||||
variant: esp32s3
|
||||
@@ -19,9 +21,9 @@ esp32:
|
||||
toolchain: esp-idf
|
||||
framework:
|
||||
type: esp-idf
|
||||
# Required to achieve sufficient PSRAM bandwidth
|
||||
# PSRAM bandwidth for the RGB panel (not set by ESPHome); without it the
|
||||
# image shifts during flash/WiFi activity
|
||||
sdkconfig_options:
|
||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: y
|
||||
CONFIG_ESP32S3_DATA_CACHE_64KB: y
|
||||
CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
|
||||
CONFIG_SPIRAM_RODATA: y
|
||||
@@ -32,6 +34,7 @@ psram:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# PINOUTS: ESP32 Cheap Yellow Display, 4.3", IPS, Capacitive
|
||||
## Display
|
||||
@@ -63,6 +66,7 @@ packages:
|
||||
# HSYNC 39
|
||||
# VSYNC 41
|
||||
# DE 40
|
||||
# BL 2
|
||||
## Capacitive Touch
|
||||
# TP_INT
|
||||
# TP_RST 38
|
||||
@@ -89,575 +93,248 @@ packages:
|
||||
# 3 19 TP_SDA
|
||||
# 4 20 TP_SCL
|
||||
|
||||
api:
|
||||
# status page until Home Assistant connects (log viewers don't subscribe to states)
|
||||
on_client_connected:
|
||||
- delay: 2s
|
||||
- if:
|
||||
condition:
|
||||
api.connected:
|
||||
state_subscription_only: true
|
||||
then:
|
||||
- lvgl.page.show: main_page
|
||||
on_client_disconnected:
|
||||
- if:
|
||||
condition:
|
||||
not:
|
||||
api.connected:
|
||||
state_subscription_only: true
|
||||
then:
|
||||
- lvgl.page.show: status_page
|
||||
|
||||
i2c:
|
||||
- id: i2c_main
|
||||
sda: 19
|
||||
scl: 20
|
||||
scan: true
|
||||
|
||||
# same pins and timing as the 5" Sunton board, pclk lowered for the 4.3" panel
|
||||
display:
|
||||
- platform: rpi_dpi_rgb
|
||||
- platform: mipi_rgb
|
||||
model: ESP32-8048S050
|
||||
id: main_display
|
||||
color_order: RGB
|
||||
invert_colors: true
|
||||
pclk_frequency: 12.5MHz
|
||||
update_interval: never
|
||||
auto_clear_enabled: false # takes 2.8 seconds to clear the display
|
||||
dimensions:
|
||||
width: 800
|
||||
height: 480
|
||||
de_pin: 40
|
||||
hsync_pin: 39
|
||||
vsync_pin: 41
|
||||
pclk_pin: 42
|
||||
pclk_frequency: 12.5MHz
|
||||
hsync_pulse_width: 4
|
||||
hsync_front_porch: 8
|
||||
hsync_back_porch: 8
|
||||
vsync_pulse_width: 4
|
||||
vsync_front_porch: 8
|
||||
vsync_back_porch: 8
|
||||
data_pins:
|
||||
red:
|
||||
- 45 # R1
|
||||
- 48 # R2
|
||||
- 47 # R3
|
||||
- 21 # R4
|
||||
- 14 # R5
|
||||
green:
|
||||
- 5 # G0
|
||||
- 6 # G1
|
||||
- 7 # G2
|
||||
- 15 # G3
|
||||
- 16 # G4
|
||||
- 4 # G5
|
||||
blue:
|
||||
- 8 # B1
|
||||
- 3 # B2
|
||||
- 46 # B3
|
||||
- 9 # B4
|
||||
- 1 # B5
|
||||
|
||||
touchscreen:
|
||||
- platform: gt911
|
||||
id: main_touch
|
||||
display: main_display
|
||||
i2c_id: i2c_main
|
||||
reset_pin: 38
|
||||
|
||||
# Define a PWM output on the ESP32
|
||||
output:
|
||||
- platform: ledc
|
||||
id: gpio_backlight_pwm
|
||||
pin: 2
|
||||
frequency: 1220
|
||||
id: gpio_backlight_pwm
|
||||
|
||||
light:
|
||||
- platform: monochromatic
|
||||
output: gpio_backlight_pwm
|
||||
id: back_light
|
||||
name: Backlight
|
||||
output: gpio_backlight_pwm
|
||||
restore_mode: ALWAYS_ON
|
||||
|
||||
text_sensor:
|
||||
- platform: template
|
||||
# name: Uptime Human Readable
|
||||
id: uptime_human
|
||||
icon: mdi:clock-start
|
||||
internal: True
|
||||
|
||||
number:
|
||||
- platform: template
|
||||
initial_value: 0
|
||||
id: counting_number
|
||||
internal: True
|
||||
min_value: -10
|
||||
max_value: 10
|
||||
step: 1
|
||||
optimistic: True
|
||||
|
||||
# debug:
|
||||
# update_interval: 5s
|
||||
|
||||
sensor:
|
||||
- platform: uptime
|
||||
id: uptime_counter
|
||||
update_interval: 1s
|
||||
accuracy_decimals: 0
|
||||
on_raw_value:
|
||||
then:
|
||||
- light.turn_on:
|
||||
id: back_light
|
||||
brightness: 90%
|
||||
- number.increment:
|
||||
id: counting_number
|
||||
cycle: True
|
||||
- script.execute: update_display
|
||||
# - platform: debug
|
||||
# free:
|
||||
# name: "${name} Heap Free"
|
||||
# block:
|
||||
# name: "${name} Heap Max Block"
|
||||
# loop_time:
|
||||
# name: "${name} Loop Time"
|
||||
# psram:
|
||||
# name: "${name} Free PSRAM"
|
||||
- platform: uptime
|
||||
# name: Uptime Sensor
|
||||
internal: True
|
||||
id: uptime_sensor
|
||||
update_interval: 1s
|
||||
on_raw_value:
|
||||
then:
|
||||
- text_sensor.template.publish:
|
||||
id: uptime_human
|
||||
state: !lambda |-
|
||||
int seconds = round(id(uptime_sensor).raw_state);
|
||||
int days = seconds / (24 * 3600);
|
||||
seconds = seconds % (24 * 3600);
|
||||
int hours = seconds / 3600;
|
||||
seconds = seconds % 3600;
|
||||
int minutes = seconds / 60;
|
||||
seconds = seconds % 60;
|
||||
return (
|
||||
("Uptime ") +
|
||||
(days ? to_string(days) + "d " : "") +
|
||||
(hours ? to_string(hours) + "h " : "") +
|
||||
(minutes ? to_string(minutes) + "m " : "") +
|
||||
(to_string(seconds) + "s")
|
||||
).c_str();
|
||||
|
||||
script:
|
||||
- id: update_display
|
||||
- id: update_status
|
||||
then:
|
||||
- lambda: |-
|
||||
// same colors as the other status screens: ok green, waiting orange, details gray
|
||||
static const uint32_t OK = 0x4DD966, WAIT = 0xFFB300;
|
||||
auto set = [](lv_obj_t *label, const std::string &text, uint32_t color) {
|
||||
lv_label_set_text(label, text.c_str());
|
||||
lv_obj_set_style_text_color(label, lv_color_hex(color), LV_PART_MAIN);
|
||||
};
|
||||
|
||||
const bool wifi_ok = wifi::global_wifi_component->is_connected();
|
||||
set(id(status_wifi),
|
||||
wifi_ok ? str_sprintf("WiFi: connected (%d dBm)", wifi::global_wifi_component->wifi_rssi())
|
||||
: std::string("WiFi: connecting..."),
|
||||
wifi_ok ? OK : WAIT);
|
||||
|
||||
// IPv6 first (skip link-local), then IPv4
|
||||
std::string ips;
|
||||
if (wifi_ok) {
|
||||
char buf[network::IP_ADDRESS_BUFFER_SIZE];
|
||||
for (bool v6 : {true, false}) {
|
||||
for (auto &ip : wifi::global_wifi_component->get_ip_addresses()) {
|
||||
if (!ip.is_set() || ip.is_ip6() != v6)
|
||||
continue;
|
||||
ip.str_to(buf);
|
||||
if (v6 && strncmp(buf, "fe80", 4) == 0)
|
||||
continue;
|
||||
if (!ips.empty())
|
||||
ips += "\n";
|
||||
ips += buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
lv_label_set_text(id(status_ips), ips.c_str());
|
||||
if (ips.empty())
|
||||
lv_obj_add_flag(id(status_ips), LV_OBJ_FLAG_HIDDEN);
|
||||
else
|
||||
lv_obj_remove_flag(id(status_ips), LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
const bool api_ok = api::global_api_server->is_connected();
|
||||
set(id(status_ha), api_ok ? "Home Assistant: connected" : "Home Assistant: waiting...",
|
||||
api_ok ? OK : WAIT);
|
||||
|
||||
const uint32_t up = millis() / 1000;
|
||||
lv_label_set_text(id(status_footer),
|
||||
str_sprintf("ESPHome %s · up %ud %02u:%02u:%02u", ESPHOME_VERSION, up / 86400,
|
||||
(up / 3600) % 24, (up / 60) % 60, up % 60).c_str());
|
||||
interval:
|
||||
- interval: 1s
|
||||
then:
|
||||
# - lvgl.indicator.line.update:
|
||||
# id: power_meter_input
|
||||
# value: !lambda return id(counting_number).state;
|
||||
- lvgl.label.update:
|
||||
id: battery_kw
|
||||
id: clock_label
|
||||
text: !lambda |-
|
||||
static char buf[8];
|
||||
snprintf(buf, sizeof(buf), "%.1fkW", id(counting_number).state);
|
||||
return buf;
|
||||
- lvgl.label.update:
|
||||
id: battery_status
|
||||
text_color: 0xFF0000
|
||||
#text: "charging"
|
||||
text: "discharging"
|
||||
- lvgl.label.update:
|
||||
id: battery_soc
|
||||
text: !lambda |-
|
||||
static char buf[8];
|
||||
snprintf(buf, sizeof(buf), "%.1f%%", id(counting_number).state);
|
||||
return buf;
|
||||
- lvgl.label.update:
|
||||
id: solar_kw
|
||||
text: !lambda |-
|
||||
static char buf[8];
|
||||
snprintf(buf, sizeof(buf), "%.1fkW", id(counting_number).state);
|
||||
return buf;
|
||||
# - lvgl.img.update:
|
||||
# id: img_solar_power
|
||||
# src: solar_power_icon
|
||||
# img_recolor: 0xFFF000 #mixes this color with the base image
|
||||
# #img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect
|
||||
# #bg_color: 0xFFFFFF
|
||||
# # - lvgl.indicator.line.update:
|
||||
# # id: power_meter_input2
|
||||
# # value: !lambda return id(counting_number).state;
|
||||
- lvgl.label.update:
|
||||
id: battery_kw2
|
||||
text: !lambda |-
|
||||
static char buf[8];
|
||||
snprintf(buf, sizeof(buf), "%.1fkW", id(counting_number).state);
|
||||
return buf;
|
||||
- lvgl.label.update:
|
||||
id: battery_status2
|
||||
text_color: 0xFF0000
|
||||
#text: "charging"
|
||||
text: "discharging"
|
||||
- lvgl.label.update:
|
||||
id: battery_soc2
|
||||
text: !lambda |-
|
||||
static char buf[8];
|
||||
snprintf(buf, sizeof(buf), "%.1f%%", id(counting_number).state);
|
||||
return buf;
|
||||
- lvgl.label.update:
|
||||
id: solar_kw2
|
||||
text: !lambda |-
|
||||
static char buf[8];
|
||||
snprintf(buf, sizeof(buf), "%.1fkW", id(counting_number).state);
|
||||
return buf;
|
||||
# - lvgl.img.update:
|
||||
# id: img_solar_power2
|
||||
# src: solar_power_icon
|
||||
# img_recolor: 0xFFF000 #mixes this color with the base image
|
||||
# #img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect
|
||||
# #bg_color: 0xFFFFFF
|
||||
auto now = id(ha_time).now();
|
||||
if (!now.is_valid())
|
||||
return std::string("--:--");
|
||||
return now.strftime("%H:%M");
|
||||
- if:
|
||||
condition:
|
||||
lvgl.page.is_showing: status_page
|
||||
then:
|
||||
- script.execute: update_status
|
||||
|
||||
image:
|
||||
- file: mdi:sun-wireless-outline
|
||||
#"solar-power-invert.png"
|
||||
# mdi:solar-power
|
||||
# mdi:battery-charging-outline
|
||||
# mdi:battery-arrow-up-outline
|
||||
# mdi:battery-arrow-down-outline
|
||||
id: solar_power_icon
|
||||
resize: 50x50
|
||||
type: BINARY
|
||||
- platform: file
|
||||
file: assets/images/made-for-esphome-white-on-black.svg
|
||||
id: esphome_logo
|
||||
resize: 400x118
|
||||
type: RGB565
|
||||
transparency: alpha_channel
|
||||
|
||||
- file: mdi:battery-arrow-down-outline
|
||||
id: home_battery_icon
|
||||
resize: 30x30
|
||||
type: BINARY
|
||||
font:
|
||||
- file: "gfonts://Roboto@500"
|
||||
id: font_clock
|
||||
size: 200
|
||||
glyphs: "0123456789:-"
|
||||
- file: "gfonts://Roboto"
|
||||
id: font_title
|
||||
size: 40
|
||||
- file: "gfonts://Roboto"
|
||||
id: font_status
|
||||
size: 26
|
||||
glyphs: "·"
|
||||
glyphsets: [GF_Latin_Kernel]
|
||||
|
||||
lvgl:
|
||||
log_level: INFO
|
||||
log_level: WARN
|
||||
color_depth: 16
|
||||
#buffer_size: 25%
|
||||
bg_color: 0
|
||||
border_width: 0
|
||||
outline_width: 0
|
||||
shadow_width: 0
|
||||
text_font: unscii_16
|
||||
align: center
|
||||
style_definitions:
|
||||
- id: meter_style
|
||||
text_font: unscii_8
|
||||
#state_default: null
|
||||
- id: font_style
|
||||
text_font: MONTSERRAT_24
|
||||
#text_font: unscii_16
|
||||
align: center
|
||||
text_color: 0xFFFFFF
|
||||
#bg_opa: cover
|
||||
bg_color: 0x000000
|
||||
text_color: 0xFFFFFF
|
||||
theme:
|
||||
buttonmatrix:
|
||||
bg_opa: TRANSP
|
||||
bg_color: 0
|
||||
radius: 4
|
||||
pad_all: 2
|
||||
- id: details_style
|
||||
text_font: MONTSERRAT_18
|
||||
align: center
|
||||
text_color: 0xFFFFFF
|
||||
#bg_opa: cover
|
||||
bg_opa: TRANSP
|
||||
bg_color: 0
|
||||
radius: 4
|
||||
pad_all: 2
|
||||
widgets:
|
||||
- obj: # Meter
|
||||
height: 240
|
||||
width: 240
|
||||
#bg_opa: TRANSP
|
||||
bg_color: 0
|
||||
border_width: 0
|
||||
outline_width: 0
|
||||
shadow_width: 0
|
||||
pad_all: 4
|
||||
align: TOP_LEFT
|
||||
#scrollbar_mode: "off"
|
||||
widgets:
|
||||
- meter: # Gradient color arc
|
||||
height: 100%
|
||||
width: 100%
|
||||
border_width: 0
|
||||
outline_width: 0
|
||||
align: center
|
||||
bg_color: 0
|
||||
styles: meter_style
|
||||
#bg_opa: TRANSP
|
||||
scales:
|
||||
angle_range: 180 # sets the total angle to 180 = starts mid left and ends mid right
|
||||
range_to: 10
|
||||
range_from: -10
|
||||
ticks:
|
||||
count: 0
|
||||
indicators:
|
||||
- line:
|
||||
id: power_meter_input
|
||||
width: 8
|
||||
color: 0xFFFFFF
|
||||
r_mod: 12 #sets line length by this much difference from the scale default radius
|
||||
value: 50
|
||||
# - image:
|
||||
# id: power_meter_input_img
|
||||
- arc:
|
||||
color: 0xFF3000
|
||||
r_mod: 10 #radius difference from the scale default radius
|
||||
width: 20
|
||||
start_value: -10
|
||||
end_value: 0
|
||||
- arc:
|
||||
color: 0x00FF00
|
||||
r_mod: 10 #radius difference from the scale default radius
|
||||
width: 20
|
||||
start_value: 0
|
||||
end_value: 10
|
||||
#- canvas:
|
||||
- arc: # black arc to erase middle part of meter indicator line
|
||||
height: 160
|
||||
width: 160
|
||||
align: center
|
||||
arc_color: 0x000000 # background color
|
||||
arc_width: 150
|
||||
start_angle: 0
|
||||
end_angle: 360
|
||||
indicator:
|
||||
arc_width: 150
|
||||
arc_color: 0x000000
|
||||
- label: # gauge lower and higher range indicators
|
||||
styles: font_style
|
||||
text_font: MONTSERRAT_18 # override font size
|
||||
y: 8 #negative = higher
|
||||
x: -99
|
||||
text: "-10"
|
||||
- label:
|
||||
styles: font_style
|
||||
text_font: MONTSERRAT_18 # override font size
|
||||
y: 8 #negative = higher
|
||||
x: 99
|
||||
text: "+10"
|
||||
- label:
|
||||
styles: font_style
|
||||
id: battery_status
|
||||
y: -35 #negative = higher
|
||||
- label:
|
||||
styles: font_style
|
||||
id: battery_kw
|
||||
y: -60
|
||||
- label:
|
||||
styles: font_style
|
||||
text_font: MONTSERRAT_40 # override font size
|
||||
id: battery_soc
|
||||
y: 0
|
||||
- label:
|
||||
styles: font_style
|
||||
id: solar_kw
|
||||
text_color: 0xFFFF00
|
||||
y: 90
|
||||
#- img:
|
||||
# src: home_battery_icon
|
||||
#id: img_solar_power
|
||||
#align: center
|
||||
#img_recolor: 0xFFFFFF
|
||||
#img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect
|
||||
#bg_color: 0xFFFFFF
|
||||
#y: -35
|
||||
#x: -60
|
||||
- image:
|
||||
src: solar_power_icon
|
||||
id: img_solar_power
|
||||
align: center
|
||||
image_recolor: 0xFFFF00
|
||||
image_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect
|
||||
#bg_color: 0xFFFFFF
|
||||
y: 50
|
||||
#x: -60
|
||||
- obj: # Meter
|
||||
height: 240
|
||||
width: 240
|
||||
#bg_opa: TRANSP
|
||||
bg_color: 0
|
||||
border_width: 0
|
||||
outline_width: 0
|
||||
shadow_width: 0
|
||||
pad_all: 4
|
||||
align: TOP_MID
|
||||
#scrollbar_mode: "off"
|
||||
widgets:
|
||||
- meter: # Gradient color arc
|
||||
height: 100%
|
||||
width: 100%
|
||||
border_width: 0
|
||||
outline_width: 0
|
||||
align: center
|
||||
bg_color: 0
|
||||
styles: meter_style
|
||||
#bg_opa: TRANSP
|
||||
scales:
|
||||
angle_range: 180 # sets the total angle to 180 = starts mid left and ends mid right
|
||||
range_to: 10
|
||||
range_from: -10
|
||||
ticks:
|
||||
count: 0
|
||||
indicators:
|
||||
- line:
|
||||
id: power_meter_input2
|
||||
width: 8
|
||||
color: 0xFFFFFF
|
||||
r_mod: 12 #sets line length by this much difference from the scale default radius
|
||||
value: 50
|
||||
# - image:
|
||||
# id: power_meter_input_img2
|
||||
- arc:
|
||||
color: 0xFF3000
|
||||
r_mod: 10 #radius difference from the scale default radius
|
||||
width: 20
|
||||
start_value: -10
|
||||
end_value: 0
|
||||
- arc:
|
||||
color: 0x00FF00
|
||||
r_mod: 10 #radius difference from the scale default radius
|
||||
width: 20
|
||||
start_value: 0
|
||||
end_value: 10
|
||||
#- canvas:
|
||||
- arc: # black arc to erase middle part of meter indicator line
|
||||
height: 160
|
||||
width: 160
|
||||
align: center
|
||||
arc_color: 0x000000 # background color
|
||||
arc_width: 150
|
||||
start_angle: 0
|
||||
end_angle: 360
|
||||
indicator:
|
||||
arc_width: 150
|
||||
arc_color: 0x000000
|
||||
- label: # gauge lower and higher range indicators
|
||||
styles: font_style
|
||||
text_font: MONTSERRAT_18 # override font size
|
||||
y: 8 #negative = higher
|
||||
x: -99
|
||||
text: "-10"
|
||||
- label:
|
||||
styles: font_style
|
||||
text_font: MONTSERRAT_18 # override font size
|
||||
y: 8 #negative = higher
|
||||
x: 99
|
||||
text: "+10"
|
||||
- label:
|
||||
styles: font_style
|
||||
id: battery_status2
|
||||
y: -35 #negative = higher
|
||||
- label:
|
||||
styles: font_style
|
||||
id: battery_kw2
|
||||
y: -60
|
||||
- label:
|
||||
styles: font_style
|
||||
text_font: MONTSERRAT_40 # override font size
|
||||
id: battery_soc2
|
||||
y: 0
|
||||
- label:
|
||||
styles: font_style
|
||||
id: solar_kw2
|
||||
text_color: 0xFFFF00
|
||||
y: 90
|
||||
#- img:
|
||||
# src: home_battery_icon
|
||||
#id: img_solar_power
|
||||
#align: center
|
||||
#img_recolor: 0xFFFFFF
|
||||
#img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect
|
||||
#bg_color: 0xFFFFFF
|
||||
#y: -35
|
||||
#x: -60
|
||||
- image:
|
||||
src: solar_power_icon
|
||||
id: img_solar_power2
|
||||
align: center
|
||||
image_recolor: 0xFFFF00
|
||||
image_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect
|
||||
#bg_color: 0xFFFFFF
|
||||
y: 50
|
||||
#x: -60
|
||||
- obj: # Meter
|
||||
height: 240
|
||||
width: 240
|
||||
#bg_opa: TRANSP
|
||||
bg_color: 0
|
||||
border_width: 0
|
||||
outline_width: 0
|
||||
shadow_width: 0
|
||||
pad_all: 4
|
||||
align: BOTTOM_LEFT
|
||||
#scrollbar_mode: "off"
|
||||
widgets:
|
||||
- meter: # Gradient color arc
|
||||
height: 100%
|
||||
width: 100%
|
||||
border_width: 0
|
||||
outline_width: 0
|
||||
align: center
|
||||
bg_color: 0
|
||||
styles: meter_style
|
||||
#bg_opa: TRANSP
|
||||
scales:
|
||||
angle_range: 180 # sets the total angle to 180 = starts mid left and ends mid right
|
||||
range_to: 10
|
||||
range_from: -10
|
||||
ticks:
|
||||
count: 0
|
||||
indicators:
|
||||
- line:
|
||||
id: power_meter_input3
|
||||
width: 8
|
||||
color: 0xFFFFFF
|
||||
r_mod: 12 #sets line length by this much difference from the scale default radius
|
||||
value: 50
|
||||
# - image:
|
||||
# id: power_meter_input_img3
|
||||
- arc:
|
||||
color: 0xFF3000
|
||||
r_mod: 10 #radius difference from the scale default radius
|
||||
width: 20
|
||||
start_value: -10
|
||||
end_value: 0
|
||||
- arc:
|
||||
color: 0x00FF00
|
||||
r_mod: 10 #radius difference from the scale default radius
|
||||
width: 20
|
||||
start_value: 0
|
||||
end_value: 10
|
||||
#- canvas:
|
||||
- arc: # black arc to erase middle part of meter indicator line
|
||||
height: 160
|
||||
width: 160
|
||||
align: center
|
||||
arc_color: 0x000000 # background color
|
||||
arc_width: 150
|
||||
start_angle: 0
|
||||
end_angle: 360
|
||||
indicator:
|
||||
arc_width: 150
|
||||
arc_color: 0x000000
|
||||
- label: # gauge lower and higher range indicators
|
||||
styles: font_style
|
||||
text_font: MONTSERRAT_18 # override font size
|
||||
y: 8 #negative = higher
|
||||
x: -99
|
||||
text: "-10"
|
||||
- label:
|
||||
styles: font_style
|
||||
text_font: MONTSERRAT_18 # override font size
|
||||
y: 8 #negative = higher
|
||||
x: 99
|
||||
text: "+10"
|
||||
- label:
|
||||
styles: font_style
|
||||
id: battery_status3
|
||||
y: -35 #negative = higher
|
||||
- label:
|
||||
styles: font_style
|
||||
id: battery_kw3
|
||||
y: -60
|
||||
- label:
|
||||
styles: font_style
|
||||
text_font: MONTSERRAT_40 # override font size
|
||||
id: battery_soc3
|
||||
y: 0
|
||||
- label:
|
||||
styles: font_style
|
||||
id: solar_kw3
|
||||
text_color: 0xFFFF00
|
||||
y: 90
|
||||
#- img:
|
||||
# src: home_battery_icon
|
||||
#id: img_solar_power
|
||||
#align: center
|
||||
#img_recolor: 0xFFFFFF
|
||||
#img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect
|
||||
#bg_color: 0xFFFFFF
|
||||
#y: -35
|
||||
#x: -60
|
||||
- image:
|
||||
src: solar_power_icon
|
||||
id: img_solar_power3
|
||||
align: center
|
||||
image_recolor: 0xFFFF00
|
||||
image_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect
|
||||
#bg_color: 0xFFFFFF
|
||||
y: 50
|
||||
#x: -60
|
||||
border_width: 0
|
||||
items:
|
||||
bg_color: 0x2B2F36
|
||||
text_color: 0xFFFFFF
|
||||
radius: 12
|
||||
checked:
|
||||
bg_color: 0xE08A00
|
||||
top_layer:
|
||||
widgets:
|
||||
# same navigation bar as on mcu-lvgl-trainer
|
||||
- buttonmatrix:
|
||||
id: nav_bar
|
||||
align: bottom_mid
|
||||
width: 100%
|
||||
height: 64
|
||||
pad_all: 4
|
||||
pad_column: 6
|
||||
items:
|
||||
text_font: montserrat_28
|
||||
rows:
|
||||
- buttons:
|
||||
- id: page_prev
|
||||
text: "\uF053"
|
||||
on_press:
|
||||
then:
|
||||
lvgl.page.previous:
|
||||
- id: page_home
|
||||
text: "\uF015"
|
||||
on_press:
|
||||
then:
|
||||
lvgl.page.show: main_page
|
||||
- id: page_next
|
||||
text: "\uF054"
|
||||
on_press:
|
||||
then:
|
||||
lvgl.page.next:
|
||||
pages:
|
||||
# 1: clock
|
||||
- id: main_page
|
||||
widgets:
|
||||
- label:
|
||||
id: clock_label
|
||||
align: CENTER
|
||||
y: -32
|
||||
text_font: font_clock
|
||||
text: "--:--"
|
||||
|
||||
# 2: status (shown until Home Assistant connects)
|
||||
- id: status_page
|
||||
on_load:
|
||||
- script.execute: update_status
|
||||
widgets:
|
||||
- image:
|
||||
src: esphome_logo
|
||||
align: TOP_MID
|
||||
y: 16
|
||||
- label:
|
||||
align: TOP_MID
|
||||
y: 140
|
||||
text_font: font_title
|
||||
text: "${name}"
|
||||
- obj:
|
||||
id: status_lines
|
||||
x: 60
|
||||
y: 196
|
||||
width: 700
|
||||
height: SIZE_CONTENT
|
||||
bg_opa: TRANSP
|
||||
border_width: 0
|
||||
pad_all: 0
|
||||
scrollbar_mode: "OFF"
|
||||
layout:
|
||||
type: flex
|
||||
flex_flow: column
|
||||
pad_row: 8
|
||||
widgets:
|
||||
- label:
|
||||
id: status_wifi
|
||||
text_font: font_status
|
||||
text: ""
|
||||
- label:
|
||||
id: status_ips
|
||||
text_font: font_status
|
||||
text_color: 0x8C8C8C
|
||||
pad_left: 30
|
||||
text: ""
|
||||
- label:
|
||||
id: status_ha
|
||||
text_font: font_status
|
||||
text: ""
|
||||
- label:
|
||||
id: status_footer
|
||||
text_font: font_status
|
||||
text_color: 0x8C8C8C
|
||||
text: ""
|
||||
@@ -26,6 +26,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# PINOUTS: M5ATOM
|
||||
# IR G12
|
||||
|
||||
@@ -59,6 +59,7 @@ external_components:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
# common: !include common/common_dev.yaml
|
||||
|
||||
# web_server:
|
||||
|
||||
@@ -37,6 +37,7 @@ external_components:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
script:
|
||||
- id: geiger_click
|
||||
|
||||
@@ -22,6 +22,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# GPIO21 UART TX
|
||||
# GPIO20 UART RX
|
||||
|
||||
@@ -37,6 +37,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
|
||||
# PINOUTS: M5ATOM+Atom Hub Switch
|
||||
|
||||
@@ -23,6 +23,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
uart:
|
||||
- id: cse7766_uart
|
||||
|
||||
@@ -19,6 +19,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
spi:
|
||||
clk_pin: 23
|
||||
|
||||
@@ -40,6 +40,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
# logger:
|
||||
# hardware_uart: UART0
|
||||
|
||||
@@ -21,6 +21,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
i2c:
|
||||
sda: 25
|
||||
|
||||
@@ -33,6 +33,7 @@ psram:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
external_components:
|
||||
- source: github://m5stack/esphome-yaml/components
|
||||
|
||||
@@ -21,6 +21,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
logger:
|
||||
logs:
|
||||
@@ -49,6 +50,20 @@ color:
|
||||
hex: ff0000
|
||||
- id: my_white
|
||||
hex: ffffff
|
||||
- id: status_ok
|
||||
hex: 4dd966
|
||||
- id: status_wait
|
||||
hex: ffb300
|
||||
- id: status_dim
|
||||
hex: 8c8c8c
|
||||
|
||||
image:
|
||||
- platform: file
|
||||
file: assets/images/made-for-esphome-white-on-black.svg
|
||||
id: esphome_logo
|
||||
resize: 220x65
|
||||
type: RGB565
|
||||
transparency: alpha_channel
|
||||
|
||||
font:
|
||||
- file: "gfonts://Roboto"
|
||||
@@ -107,6 +122,46 @@ display:
|
||||
invert_colors: false
|
||||
lambda: |-
|
||||
it.fill(Color::BLACK);
|
||||
|
||||
// status screen until Home Assistant connects (240x320)
|
||||
if (!api::global_api_server->is_connected_with_state_subscription()) {
|
||||
const int cx = it.get_width() / 2;
|
||||
it.image(cx, 48, id(esphome_logo), ImageAlign::CENTER);
|
||||
it.print(cx, 100, id(roboto_24), id(my_white), TextAlign::CENTER, "${name}");
|
||||
|
||||
int y = 130;
|
||||
if (wifi::global_wifi_component->is_connected()) {
|
||||
it.printf(8, y, id(roboto_16), id(status_ok), "WiFi: connected (%d dBm)",
|
||||
wifi::global_wifi_component->wifi_rssi());
|
||||
y += 22;
|
||||
// IPv6 first (skip link-local), then IPv4
|
||||
char buf[network::IP_ADDRESS_BUFFER_SIZE];
|
||||
for (bool v6 : {true, false}) {
|
||||
for (auto &ip : wifi::global_wifi_component->get_ip_addresses()) {
|
||||
if (!ip.is_set() || ip.is_ip6() != v6 || y > 200)
|
||||
continue;
|
||||
ip.str_to(buf);
|
||||
if (v6 && strncmp(buf, "fe80", 4) == 0)
|
||||
continue;
|
||||
it.print(8, y, id(roboto_12), id(status_dim), buf);
|
||||
y += 16;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
it.print(8, y, id(roboto_16), id(status_wait), "WiFi: connecting...");
|
||||
y += 22;
|
||||
}
|
||||
y += 8;
|
||||
it.print(8, y, id(roboto_16), api::global_api_server->is_connected() ? id(status_ok) : id(status_wait),
|
||||
api::global_api_server->is_connected() ? "Home Assistant: connected" : "Home Assistant: waiting...");
|
||||
|
||||
it.printf(8, it.get_height() - 8, id(roboto_12), id(status_dim), TextAlign::BOTTOM_LEFT, "ESPHome %s",
|
||||
ESPHOME_VERSION);
|
||||
it.printf(it.get_width() - 8, it.get_height() - 8, id(roboto_12), id(status_dim), TextAlign::BOTTOM_RIGHT,
|
||||
"up %us", (unsigned) (millis() / 1000));
|
||||
return;
|
||||
}
|
||||
|
||||
it.print(0, 0, id(b612_12), id(my_white), TextAlign::TOP_LEFT, "HELLO WORLD!");
|
||||
it.print(0, 14, id(b612_12), id(my_green), TextAlign::TOP_LEFT, "HELLO WORLD!");
|
||||
it.print(0, 28, id(b612_12), id(my_magenta), TextAlign::TOP_LEFT, "HELLO WORLD!");
|
||||
|
||||
@@ -34,6 +34,7 @@ esp32:
|
||||
|
||||
packages:
|
||||
common: !include common/common.yaml
|
||||
ipv6_only: !include common/ipv6_only.yaml
|
||||
|
||||
api:
|
||||
actions:
|
||||
|
||||
Reference in new issue
Block a user