209 lines
6.4 KiB
YAML
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()); |