Edit esp-reterminal-e1001.yaml
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-reterminal-e1001.yaml
|
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-reterminal-e1001.yaml
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# VERSIONS:
|
# 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
|
# 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
|
# selection, rounded tiles, full date header, Home Assistant job and
|
||||||
# appliance data, inverse alert tiles, and change-only display refreshes.
|
# appliance data, inverse alert tiles, and change-only display refreshes.
|
||||||
@@ -39,7 +41,8 @@
|
|||||||
# the visible page content has actually changed.
|
# the visible page content has actually changed.
|
||||||
# - Page changes and manual refreshes intentionally force one physical display refresh.
|
# - Page changes and manual refreshes intentionally force one physical display refresh.
|
||||||
# - Job countdown wording changes only when its displayed hour/day value changes.
|
# - 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.
|
# - Appliance tiles show OPERATING while active.
|
||||||
# - A completed appliance shows inverse FINISHED for one hour after cycle completion.
|
# - 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.
|
# - After one hour, the appliance tile shows Completed at HH:MM with a normal background.
|
||||||
@@ -57,12 +60,12 @@ substitutions:
|
|||||||
# Device Naming
|
# Device Naming
|
||||||
device_name: "esp-reterminal-e1001"
|
device_name: "esp-reterminal-e1001"
|
||||||
friendly_name: "reTerminal E1001 Dashboard"
|
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"
|
device_area: "Lounge"
|
||||||
|
|
||||||
# Project Naming
|
# Project Naming
|
||||||
project_name: "SeeedStudio.reTerminal-E1001"
|
project_name: "SeeedStudio.reTerminal-E1001"
|
||||||
project_version: "v0.3"
|
project_version: "v0.4"
|
||||||
|
|
||||||
# Passwords and Secrets
|
# Passwords and Secrets
|
||||||
api_key: !secret esp-api_key
|
api_key: !secret esp-api_key
|
||||||
@@ -240,14 +243,14 @@ font:
|
|||||||
family: Inter
|
family: Inter
|
||||||
weight: 700
|
weight: 700
|
||||||
id: font_job_title
|
id: font_job_title
|
||||||
size: 22
|
size: 25
|
||||||
|
|
||||||
- file:
|
- file:
|
||||||
type: gfonts
|
type: gfonts
|
||||||
family: Inter
|
family: Inter
|
||||||
weight: 700
|
weight: 700
|
||||||
id: font_job_status
|
id: font_job_status
|
||||||
size: 20
|
size: 23
|
||||||
|
|
||||||
- file:
|
- file:
|
||||||
type: gfonts
|
type: gfonts
|
||||||
@@ -263,6 +266,83 @@ font:
|
|||||||
id: font_appliance_status
|
id: font_appliance_status
|
||||||
size: 17
|
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:
|
# DISPLAY:
|
||||||
# Two pages with rounded status tiles.
|
# Two pages with rounded status tiles.
|
||||||
@@ -364,7 +444,36 @@ display:
|
|||||||
return std::string(buffer);
|
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 &state, float due_ts,
|
||||||
const std::string &completed_time) {
|
const std::string &completed_time) {
|
||||||
const int w = 256;
|
const int w = 256;
|
||||||
@@ -385,16 +494,16 @@ display:
|
|||||||
const int64_t remaining = static_cast<int64_t>(due_ts) - now_ts;
|
const int64_t remaining = static_cast<int64_t>(due_ts) - now_ts;
|
||||||
const int hours = static_cast<int>((remaining + 3599) / 3600);
|
const int hours = static_cast<int>((remaining + 3599) / 3600);
|
||||||
if (hours <= hour_limit) {
|
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 {
|
} else {
|
||||||
const int days = static_cast<int>((remaining + 86399) / 86400);
|
const int days = static_cast<int>((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 {
|
} else {
|
||||||
status = "Not Due";
|
status = "Not Due";
|
||||||
}
|
}
|
||||||
} else if (state == "Due") {
|
} else if (state == "Due") {
|
||||||
status = "DUE";
|
status = "DUE NOW";
|
||||||
border = emphasis_border;
|
border = emphasis_border;
|
||||||
} else if (state == "Overdue") {
|
} else if (state == "Overdue") {
|
||||||
status = "OVERDUE";
|
status = "OVERDUE";
|
||||||
@@ -407,23 +516,41 @@ display:
|
|||||||
}
|
}
|
||||||
|
|
||||||
rounded_tile(x, y, w, h, inverse, border);
|
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(
|
it.printf(
|
||||||
x + (w / 2),
|
x + (w / 2),
|
||||||
y + 67,
|
y + 83,
|
||||||
id(font_job_title),
|
id(font_job_title),
|
||||||
text_colour,
|
foreground,
|
||||||
TextAlign::CENTER,
|
TextAlign::CENTER,
|
||||||
"%s",
|
"%s",
|
||||||
name
|
title_line_1
|
||||||
);
|
);
|
||||||
|
|
||||||
it.printf(
|
it.printf(
|
||||||
x + (w / 2),
|
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),
|
id(font_job_status),
|
||||||
text_colour,
|
foreground,
|
||||||
TextAlign::CENTER,
|
TextAlign::CENTER,
|
||||||
"%s",
|
"%s",
|
||||||
status.c_str()
|
status.c_str()
|
||||||
@@ -445,40 +572,40 @@ display:
|
|||||||
|
|
||||||
// Three tiles on the top row and two centred on the lower row.
|
// Three tiles on the top row and two centred on the lower row.
|
||||||
draw_job(
|
draw_job(
|
||||||
8, 70,
|
8, 70, 0,
|
||||||
"Dog Feeding Morning",
|
"Dog Feeding", "Morning",
|
||||||
id(job_dog_feeding_morning_state).state,
|
id(job_dog_feeding_morning_state).state,
|
||||||
id(job_dog_feeding_morning_due_ts).state,
|
id(job_dog_feeding_morning_due_ts).state,
|
||||||
id(job_dog_feeding_morning_completed_time).state
|
id(job_dog_feeding_morning_completed_time).state
|
||||||
);
|
);
|
||||||
|
|
||||||
draw_job(
|
draw_job(
|
||||||
272, 70,
|
272, 70, 0,
|
||||||
"Dog Feeding Evening",
|
"Dog Feeding", "Evening",
|
||||||
id(job_dog_feeding_evening_state).state,
|
id(job_dog_feeding_evening_state).state,
|
||||||
id(job_dog_feeding_evening_due_ts).state,
|
id(job_dog_feeding_evening_due_ts).state,
|
||||||
id(job_dog_feeding_evening_completed_time).state
|
id(job_dog_feeding_evening_completed_time).state
|
||||||
);
|
);
|
||||||
|
|
||||||
draw_job(
|
draw_job(
|
||||||
536, 70,
|
536, 70, 1,
|
||||||
"Dog De-pooping",
|
"Dog", "De-pooping",
|
||||||
id(job_dog_depooping_state).state,
|
id(job_dog_depooping_state).state,
|
||||||
id(job_dog_depooping_due_ts).state,
|
id(job_dog_depooping_due_ts).state,
|
||||||
id(job_dog_depooping_completed_time).state
|
id(job_dog_depooping_completed_time).state
|
||||||
);
|
);
|
||||||
|
|
||||||
draw_job(
|
draw_job(
|
||||||
140, 275,
|
140, 275, 2,
|
||||||
"Dishwasher Unpacked",
|
"Dishwasher", "Unpacked",
|
||||||
id(job_dishwasher_unpacked_state).state,
|
id(job_dishwasher_unpacked_state).state,
|
||||||
id(job_dishwasher_unpacked_due_ts).state,
|
id(job_dishwasher_unpacked_due_ts).state,
|
||||||
id(job_dishwasher_unpacked_completed_time).state
|
id(job_dishwasher_unpacked_completed_time).state
|
||||||
);
|
);
|
||||||
|
|
||||||
draw_job(
|
draw_job(
|
||||||
404, 275,
|
404, 275, 3,
|
||||||
"Rubbish Removed",
|
"Rubbish", "Removed",
|
||||||
id(job_rubbish_removed_state).state,
|
id(job_rubbish_removed_state).state,
|
||||||
id(job_rubbish_removed_due_ts).state,
|
id(job_rubbish_removed_due_ts).state,
|
||||||
id(job_rubbish_removed_completed_time).state
|
id(job_rubbish_removed_completed_time).state
|
||||||
|
|||||||
Reference in New Issue
Block a user