#:########################################################################################:# # TITLE: ESP reTERMINAL E1001 DASHBOARD # # zorruno.com layout v1.1 2026 # #:########################################################################################:# # REPO: # https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-reterminal-e1001.yaml #:########################################################################################:# # VERSIONS: # V0.1 2026-07-20 Initial ESPHome bring-up, Home Assistant API connection, # E1001 e-paper display test matrix and physical button setup. #:########################################################################################:# # HARDWARE: # - Seeed Studio reTerminal E1001 # - ESP32-S3 # - 32MB flash # - 8MB octal PSRAM # - 7.5 inch monochrome e-paper display # - 800x480 resolution # - Green refresh button: GPIO3 # - Right white button: GPIO4 # - Left white button: GPIO5 # - Onboard green LED: GPIO6, inverted # - Display SPI clock: GPIO7 # - Display SPI MOSI: GPIO9 # - Display CS: GPIO10 # - Display DC: GPIO11 # - Display reset: GPIO12 # - Display busy: GPIO13, inverted #:########################################################################################:# # OPERATION NOTES: # - This first build uses DHCP through common/network_common_dhcp.yaml. # - Home Assistant connects through the encrypted ESPHome native API. # - MQTT is not required for importing Home Assistant entity states. # - The display currently shows a fixed 4x3 test matrix. # - The green physical button and the Home Assistant button both force a refresh. # - The left and right white buttons are exposed to Home Assistant for later page control. # - Deep sleep is intentionally disabled during initial development and OTA testing. #:########################################################################################:# #:########################################################################################:# # SUBSTITUTIONS: # Specific device variable substitutions # If NOT using a secrets file, replace the passwords etc with quoted values. #:########################################################################################:# substitutions: # Device Naming device_name: "esp-reterminal-e1001" friendly_name: "reTerminal E1001 Dashboard" description_comment: "Seeed Studio reTerminal E1001 7.5-inch e-paper Home Assistant status dashboard. Initial ESPHome display and connectivity test. (Layout V1.1)" device_area: "Lounge" # Project Naming project_name: "SeeedStudio.reTerminal-E1001" project_version: "v0.1" # Passwords and Secrets api_key: !secret esp-api_key ota_pass: !secret esp-ota_pass # Device Settings log_level: "INFO" update_interval: "60s" display_update_interval: "5min" #:########################################################################################:# # PACKAGES: # Included Common Packages # https://esphome.io/components/packages.html #:########################################################################################:# packages: #### WIFI, Network DHCP, Fallback AP, Safemode #### common_wifi: !include file: common/network_common_dhcp.yaml vars: local_device_name: "${device_name}" local_ota_pass: "${ota_pass}" #### HOME ASSISTANT API #### common_api: !include file: common/api_common.yaml #file: common/api_common_noencryption.yaml vars: local_api_key: "${api_key}" #### MQTT #### # MQTT is not needed for the E1001 to import Home Assistant entity states. #common_mqtt: !include # file: common/mqtt_common.yaml # vars: # local_device_name: "${device_name}" #### WEB PORTAL #### #common_webportal: !include common/webportal_common_nopass.yaml #### SNTP #### # Home Assistant time will be added when the dashboard requires a clock. #common_sntp: !include common/sntp_common.yaml #### DIAGNOSTICS SENSORS #### # Enable these after the first hardware build is confirmed stable. #diag_basic: !include common/include_basic_diag_sensors.yaml #diag_more: !include common/include_more_diag_sensors.yaml #diag_debug: !include common/include_debug_diag_sensors.yaml #diag_resetcount: !include common/include_resetcount_diag_sensors.yaml #:########################################################################################:# # ESPHOME: # https://esphome.io/components/esphome.html #:########################################################################################:# esphome: name: "${device_name}" friendly_name: "${friendly_name}" comment: "${description_comment}" area: "${device_area}" project: name: "${project_name}" version: "${project_version}" #:########################################################################################:# # ESP PLATFORM AND FRAMEWORK: # https://esphome.io/components/esp32.html #:########################################################################################:# esp32: board: esp32-s3-devkitc-1 flash_size: 32MB framework: type: arduino #:########################################################################################:# # PSRAM: # https://esphome.io/components/psram.html #:########################################################################################:# psram: mode: octal speed: 80MHz #:########################################################################################:# # LOGGER: # The E1001 uses its CH340K USB-to-UART bridge on UART0. # https://esphome.io/components/logger.html #:########################################################################################:# logger: level: "${log_level}" baud_rate: 115200 hardware_uart: UART0 #:########################################################################################:# # SPI: # E-paper display bus # https://esphome.io/components/spi.html #:########################################################################################:# spi: id: epaper_spi clk_pin: GPIO7 mosi_pin: GPIO9 #:########################################################################################:# # FONTS: # https://esphome.io/components/font.html #:########################################################################################:# font: - file: type: gfonts family: Inter weight: 700 id: font_title size: 34 - file: type: gfonts family: Inter weight: 600 id: font_tile size: 20 - file: type: gfonts family: Inter weight: 400 id: font_small size: 16 #:########################################################################################:# # DISPLAY: # Initial fixed 4x3 layout test # https://esphome.io/components/display/waveshare_epaper.html #:########################################################################################:# display: - platform: waveshare_epaper id: epaper_display spi_id: epaper_spi model: 7.50inv2 cs_pin: GPIO10 dc_pin: GPIO11 reset_pin: number: GPIO12 inverted: false busy_pin: number: GPIO13 inverted: true update_interval: "${display_update_interval}" lambda: |- // Screen and header geometry. const int screen_width = 800; const int screen_height = 480; const int header_height = 62; // Tile matrix geometry: 4 columns x 3 rows. const int columns = 4; const int margin_x = 10; const int gap_x = 8; const int gap_y = 8; const int grid_top = 72; const int tile_width = 189; const int tile_height = 126; const char *tile_line_1[12] = { "Dog Feeding", "Dog Feeding", "Dog", "Dishwasher", "Rubbish", "Washing", "Dryer", "Main Dishwasher", "Downstairs Dish", "EV Charger", "EV Charger", "3D Printer" }; const char *tile_line_2[12] = { "Morning", "Evening", "De-pooping", "Unpacked", "Removed", "Status", "Status", "Status", "Status", "32A", "16A", "Status" }; // Outer screen border and header. it.rectangle(0, 0, screen_width - 1, screen_height - 1); it.line(0, header_height, screen_width - 1, header_height); it.print( 16, 31, id(font_title), TextAlign::CENTER_LEFT, "Home Status" ); if (id(wifi_ip_address).has_state()) { it.printf( 784, 31, id(font_small), TextAlign::CENTER_RIGHT, "ESPHome | %s", id(wifi_ip_address).state.c_str() ); } else { it.print( 784, 31, id(font_small), TextAlign::CENTER_RIGHT, "ESPHome | Connecting..." ); } // Draw the twelve initial placeholder tiles. for (int tile = 0; tile < 12; tile++) { const int column = tile % columns; const int row = tile / columns; const int x = margin_x + column * (tile_width + gap_x); const int y = grid_top + row * (tile_height + gap_y); it.rectangle(x, y, tile_width, tile_height); it.printf( x + (tile_width / 2), y + 46, id(font_tile), TextAlign::CENTER, "%s", tile_line_1[tile] ); it.printf( x + (tile_width / 2), y + 82, id(font_small), TextAlign::CENTER, "%s", tile_line_2[tile] ); } #:########################################################################################:# # WIFI INFORMATION: # Triggers a display refresh after DHCP has supplied the IP address. # https://esphome.io/components/text_sensor/wifi_info.html #:########################################################################################:# text_sensor: - platform: wifi_info ip_address: id: wifi_ip_address name: "${friendly_name} IP Address" entity_category: diagnostic on_value: then: - delay: 2s - component.update: epaper_display #:########################################################################################:# # OUTPUTS: # Onboard green LED # https://esphome.io/components/output/gpio.html #:########################################################################################:# output: - platform: gpio id: onboard_led_output pin: GPIO6 inverted: true #:########################################################################################:# # LIGHTS: # https://esphome.io/components/light/binary.html #:########################################################################################:# light: - platform: binary id: onboard_led name: "${friendly_name} Onboard LED" output: onboard_led_output restore_mode: ALWAYS_OFF entity_category: diagnostic #:########################################################################################:# # PHYSICAL BUTTONS: # Green refresh button plus left/right page buttons # https://esphome.io/components/binary_sensor/gpio.html #:########################################################################################:# binary_sensor: - platform: gpio id: button_refresh name: "${friendly_name} Green Refresh Button" pin: number: GPIO3 mode: input: true pullup: true inverted: true filters: - delayed_on: 20ms - delayed_off: 20ms on_press: then: - light.turn_on: onboard_led - component.update: epaper_display - delay: 300ms - light.turn_off: onboard_led - platform: gpio id: button_right name: "${friendly_name} Right Button" pin: number: GPIO4 mode: input: true pullup: true inverted: true filters: - delayed_on: 20ms - delayed_off: 20ms - platform: gpio id: button_left name: "${friendly_name} Left Button" pin: number: GPIO5 mode: input: true pullup: true inverted: true filters: - delayed_on: 20ms - delayed_off: 20ms #:########################################################################################:# # HOME ASSISTANT CONTROLS: # Manual display refresh button # https://esphome.io/components/button/template.html #:########################################################################################:# button: - platform: template id: refresh_display_button name: "${friendly_name} Refresh Display" icon: "mdi:refresh" on_press: then: - component.update: epaper_display