Files
Smartwave/ecran_externe/epaper_thread_node.yaml
T
2026-08-15 15:00:22 +02:00

209 lines
6.4 KiB
YAML

substitutions:
device_id: !include device_id.txt
esphome:
name: "smartwave-epaper-${device_id}"
friendly_name: "SmartWave ePaper ExternalScreen ${device_id}"
includes:
- display_api.h
on_boot:
priority: -100.0
then:
- lambda: |-
setup_display_api([]() {
// Force immediate e-Paper refresh!
id(my_display).update();
});
web_server:
port: 5000
mdns:
disabled: false
services:
- service: "_displaytcp"
protocol: "_tcp"
port: 5000
txt:
version: "1.0"
type: "epaper_2.13"
esp32:
board: epaper-node-display
variant: esp32h2
framework:
type: esp-idf
log_level: INFO
advanced:
loop_task_stack_size: 32768
sdkconfig_options:
CONFIG_ESP_MAIN_TASK_STACK_SIZE: "16384"
CONFIG_OPENTHREAD_TASK_STACK_SIZE: "8192"
CONFIG_ESP_WIFI_ENABLED: "n"
CONFIG_OPENTHREAD_ENABLED: "y"
CONFIG_MBEDTLS_DYNAMIC_BUFFER: "y"
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA: "y"
logger:
level: VERBOSE
hardware_uart: UART0
logs:
openthread: INFO
network:
enable_ipv6: true
openthread:
force_dataset: true
tlv: 00030000184a0300000b35060004001fffe00208f7754c0c4a4dea9a0708fd1adbbe7435e95405103f543281275a135e38982974aa71e987030f4f70656e5468726561642d3766343101027f410410a500c86abfe7ef17888c2232feac2dc60c0402a0f7f80e080000000000010000
# -------------------------------------------------------------------
# MQTT Connection over Thread IPv6
# -------------------------------------------------------------------
# mqtt:
# broker: "mqtt.thread.smartwave.matthiasg.dev"
# # broker: "mqtt://[fd36:5102:8d0:1:f1cd:3499:e546:dbec]"
# # port: 1883
# topic_prefix: "microwave/display"
# keepalive: 60s
# on_connect:
# - mqtt.publish:
# topic: smartwave/hello
# payload: !lambda |-
# return std::string("{\"id_microwave\":\"") + "${device_id}" + "\",\"type\":\"externalDisplay\"}";
# on_message:
# - topic: microwave/display/status
# then:
# - text_sensor.template.publish:
# id: status_message
# state: !lambda 'return x;'
# - component.update: my_display
# -------------------------------------------------------------------
# Template Text Sensor
# -------------------------------------------------------------------
text_sensor:
- platform: openthread_info
role:
name: "Thread Role"
id: thread_role
channel:
name: "Thread Channel"
id: thread_channel
# -------------------------------------------------------------------
# Hardware SPI Pin Mapping (ESP32-H2)
# -------------------------------------------------------------------
spi:
clk_pin: GPIO10
mosi_pin: GPIO11
# -------------------------------------------------------------------
# Fonts
# -------------------------------------------------------------------
font:
- file:
type: gfonts
family: Open+Sans
weight: 700
size: 20
id: font_header
- file:
type: gfonts
family: Overpass
weight: 600
id: font_body
size: 14
- file:
type: gfonts
family: Overpass
weight: 500
id: font_small
size: 12
# -------------------------------------------------------------------
# Waveshare 2.13-inch e-Paper Display (250x122 standard resolution)
# -------------------------------------------------------------------
display:
- platform: waveshare_epaper
cs_pin: GPIO4
dc_pin: GPIO1
reset_pin: GPIO2
busy_pin: GPIO3
model: 2.13inv3
rotation: 90°
update_interval: 30min
id: my_display
lambda: |-
// --- STARTUP SCREEN ---
if (!g_received_update) {
int center_x = it.get_width() / 2;
int center_y = it.get_height() / 2;
it.printf(center_x, center_y - 10, id(font_header), TextAlign::CENTER, "SmartWave");
it.printf(center_x, center_y + 15, id(font_body), TextAlign::CENTER, "Waiting for updates...");
return;
}
// --- MICROWAVE LAYOUT ---
int y_offset = 0;
for (const auto& mw : g_microwaves) {
// Name
it.print(0, y_offset, id(font_header), mw.name.c_str());
// Decode State Text
std::string state_str;
switch(mw.state) {
case 0: state_str = mw.paused ? "PAUSED" : "COOKING"; break;
case 1: state_str = "STIRRING REQ."; break;
case 2: state_str = "DONE"; break;
case 3: state_str = "ALERT"; break;
case 4: state_str = "IDLE"; break;
default: state_str = "UNKNOWN"; break;
}
// Print Status (Top Right Align)
it.printf(it.get_width(), y_offset + 5, id(font_body), TextAlign::TOP_RIGHT, "%s", state_str.c_str());
// Process active/cooking visualisations
if (mw.state == 0) {
int bar_y = y_offset + 28;
int bar_w = 175;
int bar_h = 16;
// Draw progress bar outline & fill
it.rectangle(0, bar_y, bar_w, bar_h);
if (mw.progress > 0) {
int fill_w = (mw.progress * bar_w) / 100;
it.filled_rectangle(0, bar_y, fill_w, bar_h);
}
// Draw time remaining (or paused state)
if (mw.paused) {
it.printf(185, bar_y + 1, id(font_body), "PAUSED");
} else {
int mins = mw.remaining_time / 60;
int secs = mw.remaining_time % 60;
it.printf(185, bar_y + 1, id(font_body), "%02d:%02d", mins, secs);
}
}
else if (mw.state == 1) { // Stirring Required
it.filled_rectangle(0, y_offset + 28, 250, 20);
it.printf(125, y_offset + 28, id(font_body), COLOR_OFF, TextAlign::TOP_CENTER, "ACTION REQUIRED: STIR");
}
// Move cursor down (if we have more than 1 microwave on future larger screens)
y_offset += 60;
}
// --- SYSTEM FOOTER ---
// Line separator right above footer
it.line(0, 102, it.get_width(), 102);
// Bottom Left: Cloud Reachability & Last Update Time
std::string cloud_status = g_cloud_alert ? "Cloud: OK" : "Cloud: ERR";
it.printf(0, 105, id(font_small), "%s | %s", cloud_status.c_str(), g_update_time.c_str());
// Bottom Right: OpenThread Diagnostics
std::string role = id(thread_role).state;
it.printf(it.get_width(), 105, id(font_small), TextAlign::TOP_RIGHT,
"Th: %s (Ch %s)", role.c_str(), id(thread_channel).state.c_str());