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([](const std::string &dev_id, bool alert, bool defrost) { // Update global state id(cloud_alert) = alert; id(defrost_mode) = defrost; // Set status message text std::string msg = "Microwave " + dev_id; id(status_message).publish_state(msg.c_str()); // Force immediate e-Paper refresh! id(my_display).update(); }); # ------------------------------------------------------------------- # State Globals # ------------------------------------------------------------------- globals: - id: cloud_alert type: bool initial_value: 'false' - id: defrost_mode type: bool initial_value: 'false' 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: template name: "Display Status Message" id: status_message - platform: openthread_info ip_address: name: "Thread IP" id: thread_ip role: name: "Thread Role" id: thread_role channel: name: "Thread Channel" id: thread_channel rloc16: name: "Thread RLOC16" id: thread_rloc16 # ------------------------------------------------------------------- # 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: 400 id: font_body size: 14 # ------------------------------------------------------------------- # Waveshare 2.13-inch e-Paper Display (V4 panel = 2.13inv3 in ESPHome) # ------------------------------------------------------------------- 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: |- if (id(status_message).has_state()) { // Header it.print(5, 3, id(font_header), id(status_message).state.c_str()); it.line(0, 26, it.get_width(), 26); // Mode Status if (id(defrost_mode)) { it.print(5, 32, id(font_header), "MODE: DEFROST"); } else { it.print(5, 32, id(font_header), "MODE: NORMAL"); } // Cloud Alert Status Box if (id(cloud_alert)) { it.filled_rectangle(5, 60, 240, 24, COLOR_OFF); // Inverse background if supported, or frame box it.print(10, 62, id(font_body), "CLOUD ALERT ACTIVE"); } else { it.print(10, 62, id(font_body), "System Normal"); } // Footer: Thread Info it.line(0, 95, it.get_width(), 95); it.printf(5, 100, id(font_body), "Role: %s | Ch: %s", id(thread_role).state.c_str(), id(thread_channel).state.c_str()); } else { 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 Pi updates..."); }