From 027af09e40a58bd8de0539daabe93f3f0616dbab Mon Sep 17 00:00:00 2001 From: ESPHome Device Builder Date: Mon, 20 Jul 2026 16:27:51 +1200 Subject: [PATCH] Edit esp-reterminal-e1001.yaml --- esphome/esp-reterminal-e1001.yaml | 179 +++++++++++++++++++++++++----- 1 file changed, 153 insertions(+), 26 deletions(-) diff --git a/esphome/esp-reterminal-e1001.yaml b/esphome/esp-reterminal-e1001.yaml index 6b2fdcd..893b964 100644 --- a/esphome/esp-reterminal-e1001.yaml +++ b/esphome/esp-reterminal-e1001.yaml @@ -6,6 +6,8 @@ # https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-reterminal-e1001.yaml #:########################################################################################:# # VERSIONS: +# V0.4 2026-07-20 Improved Jobs page with large Material Design job icons, +# state icons, two-line centred job names and larger status text. # V0.3 2026-07-20 Added two-page Jobs and Appliances dashboard, white-button page # selection, rounded tiles, full date header, Home Assistant job and # appliance data, inverse alert tiles, and change-only display refreshes. @@ -39,7 +41,8 @@ # the visible page content has actually changed. # - Page changes and manual refreshes intentionally force one physical display refresh. # - Job countdown wording changes only when its displayed hour/day value changes. -# - OVERDUE and MISSED job tiles use a black background with white text. +# - Job tiles use large job icons, two-line names and clear state icons. +# - OVERDUE and MISSED job tiles use a black background with white text and icons. # - Appliance tiles show OPERATING while active. # - A completed appliance shows inverse FINISHED for one hour after cycle completion. # - After one hour, the appliance tile shows Completed at HH:MM with a normal background. @@ -57,12 +60,12 @@ substitutions: # Device Naming device_name: "esp-reterminal-e1001" friendly_name: "reTerminal E1001 Dashboard" - description_comment: "Seeed Studio reTerminal E1001 two-page Home Assistant jobs and appliance status dashboard. (Layout V1.1)" + description_comment: "Seeed Studio reTerminal E1001 two-page Home Assistant jobs and appliance status dashboard with icon-based job tiles. (Layout V1.1)" device_area: "Lounge" # Project Naming project_name: "SeeedStudio.reTerminal-E1001" - project_version: "v0.3" + project_version: "v0.4" # Passwords and Secrets api_key: !secret esp-api_key @@ -240,14 +243,14 @@ font: family: Inter weight: 700 id: font_job_title - size: 22 + size: 25 - file: type: gfonts family: Inter weight: 700 id: font_job_status - size: 20 + size: 23 - file: type: gfonts @@ -263,6 +266,83 @@ font: id: font_appliance_status size: 17 +#:########################################################################################:# +# JOB AND STATUS ICONS: +# Material Design Icons are downloaded and embedded at compile time. +# https://esphome.io/components/image/file.html +#:########################################################################################:# +image: + #:######################################################################################:# + # Job icons # + #:######################################################################################:# + + - platform: file + file: mdi:dog-side + id: icon_job_dog + type: BINARY + transparency: chroma_key + resize: 50x50 + + - platform: file + file: mdi:emoticon-poop + id: icon_job_poop + type: BINARY + transparency: chroma_key + resize: 50x50 + + - platform: file + file: mdi:dishwasher + id: icon_job_dishwasher + type: BINARY + transparency: chroma_key + resize: 50x50 + + - platform: file + file: mdi:trash-can + id: icon_job_rubbish + type: BINARY + transparency: chroma_key + resize: 50x50 + + #:######################################################################################:# + # State icons # + #:######################################################################################:# + + - platform: file + file: mdi:check-circle + id: icon_status_complete + type: BINARY + transparency: chroma_key + resize: 30x30 + + - platform: file + file: mdi:clock-outline + id: icon_status_due + type: BINARY + transparency: chroma_key + resize: 30x30 + + - platform: file + file: mdi:alert-octagon + id: icon_status_overdue + type: BINARY + transparency: chroma_key + resize: 30x30 + + - platform: file + file: mdi:close-circle + id: icon_status_missed + type: BINARY + transparency: chroma_key + resize: 30x30 + + - platform: file + file: mdi:help-circle-outline + id: icon_status_unknown + type: BINARY + transparency: chroma_key + resize: 30x30 + #:########################################################################################:# # DISPLAY: # Two pages with rounded status tiles. @@ -364,7 +444,36 @@ display: return std::string(buffer); }; - auto draw_job = [&](int x, int y, const char *name, + auto draw_job_icon = [&](int icon_type, int x, int y, Color foreground, Color background) { + if (icon_type == 0) { + it.image(x, y, id(icon_job_dog), foreground, background); + } else if (icon_type == 1) { + it.image(x, y, id(icon_job_poop), foreground, background); + } else if (icon_type == 2) { + it.image(x, y, id(icon_job_dishwasher), foreground, background); + } else { + it.image(x, y, id(icon_job_rubbish), foreground, background); + } + }; + + auto draw_state_icon = [&](const std::string &state, int x, int y, + Color foreground, Color background) { + if (state == "Complete") { + it.image(x, y, id(icon_status_complete), foreground, background); + } else if (state == "Overdue") { + it.image(x, y, id(icon_status_overdue), foreground, background); + } else if (state == "Missed") { + it.image(x, y, id(icon_status_missed), foreground, background); + } else if (state == "Due" || state == "Not Due") { + it.image(x, y, id(icon_status_due), foreground, background); + } else { + it.image(x, y, id(icon_status_unknown), foreground, background); + } + }; + + auto draw_job = [&](int x, int y, int icon_type, + const char *title_line_1, + const char *title_line_2, const std::string &state, float due_ts, const std::string &completed_time) { const int w = 256; @@ -385,16 +494,16 @@ display: const int64_t remaining = static_cast(due_ts) - now_ts; const int hours = static_cast((remaining + 3599) / 3600); if (hours <= hour_limit) { - status = "Due in " + std::to_string(hours) + (hours == 1 ? " hour" : " hours"); + status = "Due: " + std::to_string(hours) + (hours == 1 ? " Hour" : " Hours"); } else { const int days = static_cast((remaining + 86399) / 86400); - status = "Due in " + std::to_string(days) + (days == 1 ? " day" : " days"); + status = "Due: " + std::to_string(days) + (days == 1 ? " Day" : " Days"); } } else { status = "Not Due"; } } else if (state == "Due") { - status = "DUE"; + status = "DUE NOW"; border = emphasis_border; } else if (state == "Overdue") { status = "OVERDUE"; @@ -407,23 +516,41 @@ display: } rounded_tile(x, y, w, h, inverse, border); - const Color text_colour = inverse ? COLOR_OFF : COLOR_ON; + const Color foreground = inverse ? COLOR_OFF : COLOR_ON; + const Color background = inverse ? COLOR_ON : COLOR_OFF; + // Main job icon, centred near the top of the tile. + draw_job_icon(icon_type, x + ((w - 50) / 2), y + 8, foreground, background); + + // Small state icon in the upper-right corner. + draw_state_icon(state, x + w - 42, y + 12, foreground, background); + + // Two-line job title and one large status line. it.printf( x + (w / 2), - y + 67, + y + 83, id(font_job_title), - text_colour, + foreground, TextAlign::CENTER, "%s", - name + title_line_1 ); it.printf( x + (w / 2), - y + 132, + y + 114, + id(font_job_title), + foreground, + TextAlign::CENTER, + "%s", + title_line_2 + ); + + it.printf( + x + (w / 2), + y + 160, id(font_job_status), - text_colour, + foreground, TextAlign::CENTER, "%s", status.c_str() @@ -445,40 +572,40 @@ display: // Three tiles on the top row and two centred on the lower row. draw_job( - 8, 70, - "Dog Feeding Morning", + 8, 70, 0, + "Dog Feeding", "Morning", id(job_dog_feeding_morning_state).state, id(job_dog_feeding_morning_due_ts).state, id(job_dog_feeding_morning_completed_time).state ); draw_job( - 272, 70, - "Dog Feeding Evening", + 272, 70, 0, + "Dog Feeding", "Evening", id(job_dog_feeding_evening_state).state, id(job_dog_feeding_evening_due_ts).state, id(job_dog_feeding_evening_completed_time).state ); draw_job( - 536, 70, - "Dog De-pooping", + 536, 70, 1, + "Dog", "De-pooping", id(job_dog_depooping_state).state, id(job_dog_depooping_due_ts).state, id(job_dog_depooping_completed_time).state ); draw_job( - 140, 275, - "Dishwasher Unpacked", + 140, 275, 2, + "Dishwasher", "Unpacked", id(job_dishwasher_unpacked_state).state, id(job_dishwasher_unpacked_due_ts).state, id(job_dishwasher_unpacked_completed_time).state ); draw_job( - 404, 275, - "Rubbish Removed", + 404, 275, 3, + "Rubbish", "Removed", id(job_rubbish_removed_state).state, id(job_rubbish_removed_due_ts).state, id(job_rubbish_removed_completed_time).state @@ -1447,4 +1574,4 @@ button: - display.page.show: page_appliances - script.execute: id: refresh_display_if_changed - force: true \ No newline at end of file + force: true