Add switchable clock display page
This commit is contained in:
+103
-7
@@ -149,6 +149,10 @@ globals:
|
|||||||
type: bool
|
type: bool
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 'false'
|
initial_value: 'false'
|
||||||
|
- id: clock_digital_view
|
||||||
|
type: bool
|
||||||
|
restore_value: true
|
||||||
|
initial_value: 'false'
|
||||||
- id: device_usage_view
|
- id: device_usage_view
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
@@ -259,20 +263,22 @@ sensor:
|
|||||||
script:
|
script:
|
||||||
- id: show_previous_page
|
- id: show_previous_page
|
||||||
then:
|
then:
|
||||||
- lambda: id(page_index) = (id(page_index) + 2 - 1) % 2;
|
- lambda: id(page_index) = (id(page_index) + 3 - 1) % 3;
|
||||||
- component.update: tft
|
- component.update: tft
|
||||||
- id: toggle_page_mode
|
- id: toggle_page_mode
|
||||||
then:
|
then:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
if (id(page_index) == 0) {
|
if (id(page_index) == 0) {
|
||||||
id(page_one_gauge_view) = !id(page_one_gauge_view);
|
id(page_one_gauge_view) = !id(page_one_gauge_view);
|
||||||
} else {
|
} else if (id(page_index) == 1) {
|
||||||
id(device_usage_view) = (id(device_usage_view) + 1) % 2;
|
id(device_usage_view) = (id(device_usage_view) + 1) % 2;
|
||||||
|
} else {
|
||||||
|
id(clock_digital_view) = !id(clock_digital_view);
|
||||||
}
|
}
|
||||||
- component.update: tft
|
- component.update: tft
|
||||||
- id: show_next_page
|
- id: show_next_page
|
||||||
then:
|
then:
|
||||||
- lambda: id(page_index) = (id(page_index) + 1) % 2;
|
- lambda: id(page_index) = (id(page_index) + 1) % 3;
|
||||||
- component.update: tft
|
- component.update: tft
|
||||||
|
|
||||||
button:
|
button:
|
||||||
@@ -299,7 +305,7 @@ binary_sensor:
|
|||||||
- platform: wireguard
|
- platform: wireguard
|
||||||
enabled:
|
enabled:
|
||||||
name: 'WireGuard Enabled'
|
name: 'WireGuard Enabled'
|
||||||
# M5Stack Core button B (middle) toggles the alternate gauge view on page one.
|
# M5Stack Core button B (middle) switches the current page's view.
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
number: GPIO38
|
number: GPIO38
|
||||||
@@ -462,7 +468,7 @@ display:
|
|||||||
} else {
|
} else {
|
||||||
it.printf(gauge_center_x, 169, id(font_title), solar_gauge_color, TextAlign::TOP_CENTER, "-- W");
|
it.printf(gauge_center_x, 169, id(font_title), solar_gauge_color, TextAlign::TOP_CENTER, "-- W");
|
||||||
}
|
}
|
||||||
} else {
|
} else if (id(page_index) == 1) {
|
||||||
// Page 2 lists nine consumers at once in two columns; button B changes group.
|
// Page 2 lists nine consumers at once in two columns; button B changes group.
|
||||||
const int device_count = 18;
|
const int device_count = 18;
|
||||||
const int usage_group = id(device_usage_view);
|
const int usage_group = id(device_usage_view);
|
||||||
@@ -538,6 +544,93 @@ display:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id(page_index) == 2) {
|
||||||
|
const auto now = id(sntp_time).now();
|
||||||
|
const Color accent(143, 190, 223);
|
||||||
|
const Color gold(255, 170, 40);
|
||||||
|
const Color muted(55, 65, 80);
|
||||||
|
it.print(12, 10, id(font_device), accent, "Uhr · Berlin");
|
||||||
|
if (!now.is_valid()) {
|
||||||
|
it.print(160, 100, id(font_title), accent, TextAlign::TOP_CENTER, "--:--:--");
|
||||||
|
it.print(160, 190, id(font_small), Color::WHITE, TextAlign::TOP_CENTER,
|
||||||
|
"Warte auf Zeitsynchronisation");
|
||||||
|
} else {
|
||||||
|
if (!id(clock_digital_view)) {
|
||||||
|
const int cx = 160, cy = 111, radius = 74;
|
||||||
|
const float tau = 6.28318530718f;
|
||||||
|
it.filled_circle(cx, cy, radius, Color(12, 18, 28));
|
||||||
|
it.circle(cx, cy, radius, accent);
|
||||||
|
it.circle(cx, cy, radius - 3, muted);
|
||||||
|
for (int tick = 0; tick < 60; tick++) {
|
||||||
|
const float angle = tick * tau / 60.0f;
|
||||||
|
const int inner = tick % 5 == 0 ? radius - 13 : radius - 8;
|
||||||
|
it.line(cx + lroundf(sinf(angle) * inner), cy - lroundf(cosf(angle) * inner),
|
||||||
|
cx + lroundf(sinf(angle) * (radius - 5)),
|
||||||
|
cy - lroundf(cosf(angle) * (radius - 5)),
|
||||||
|
tick % 5 == 0 ? accent : muted);
|
||||||
|
}
|
||||||
|
it.print(cx, cy - 49, id(font_device), Color::WHITE, TextAlign::CENTER, "12");
|
||||||
|
it.print(cx + 50, cy, id(font_device), Color::WHITE, TextAlign::CENTER, "3");
|
||||||
|
it.print(cx, cy + 49, id(font_device), Color::WHITE, TextAlign::CENTER, "6");
|
||||||
|
it.print(cx - 50, cy, id(font_device), Color::WHITE, TextAlign::CENTER, "9");
|
||||||
|
// Round-ended hands; minutes and hours advance with the seconds.
|
||||||
|
auto hand = [&](float turns, int length, int thickness, Color color) {
|
||||||
|
const float angle = turns * tau;
|
||||||
|
for (int r = 0; r <= length; r++) {
|
||||||
|
it.filled_circle(cx + lroundf(sinf(angle) * r),
|
||||||
|
cy - lroundf(cosf(angle) * r), thickness, color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
hand((now.hour % 12 + now.minute / 60.0f + now.second / 3600.0f) / 12.0f,
|
||||||
|
34, 3, Color::WHITE);
|
||||||
|
hand((now.minute + now.second / 60.0f) / 60.0f, 51, 2, accent);
|
||||||
|
const float second_angle = now.second * tau / 60.0f;
|
||||||
|
it.line(cx - lroundf(sinf(second_angle) * 12), cy + lroundf(cosf(second_angle) * 12),
|
||||||
|
cx + lroundf(sinf(second_angle) * 60), cy - lroundf(cosf(second_angle) * 60), gold);
|
||||||
|
it.filled_circle(cx, cy, 4, gold);
|
||||||
|
it.filled_circle(cx, cy, 1, Color::BLACK);
|
||||||
|
} else {
|
||||||
|
// Draw seven-segment digits directly, avoiding an extra font dependency.
|
||||||
|
const uint8_t masks[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66,
|
||||||
|
0x6D, 0x7D, 0x07, 0x7F, 0x6F};
|
||||||
|
const int digits[6] = {now.hour / 10, now.hour % 10, now.minute / 10,
|
||||||
|
now.minute % 10, now.second / 10, now.second % 10};
|
||||||
|
const int positions[6] = {17, 61, 121, 165, 225, 269};
|
||||||
|
const int y = 77;
|
||||||
|
for (int digit = 0; digit < 6; digit++) {
|
||||||
|
const int x = positions[digit];
|
||||||
|
const Color lit = digit < 4 ? accent : gold;
|
||||||
|
for (int segment = 0; segment < 7; segment++) {
|
||||||
|
const Color color = (masks[digits[digit]] & (1 << segment))
|
||||||
|
? lit : Color(20, 27, 36);
|
||||||
|
const bool horizontal = segment == 0 || segment == 3 || segment == 6;
|
||||||
|
const int sx = horizontal ? x + 6 : x + ((segment == 1 || segment == 2) ? 30 : 0);
|
||||||
|
const int sy = y + (segment == 0 ? 0 : segment == 3 ? 72 : segment == 6 ? 36
|
||||||
|
: (segment == 1 || segment == 5) ? 6 : 42);
|
||||||
|
// Taper each segment's ends for the classic LED clock shape.
|
||||||
|
for (int stripe = 0; stripe < 6; stripe++) {
|
||||||
|
const int inset = stripe < 3 ? 2 - stripe : stripe - 3;
|
||||||
|
if (horizontal)
|
||||||
|
it.line(sx + inset, sy + stripe, sx + 23 - inset, sy + stripe, color);
|
||||||
|
else
|
||||||
|
it.line(sx + stripe, sy + inset, sx + stripe, sy + 29 - inset, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int x : {109, 213}) {
|
||||||
|
it.filled_circle(x, y + 24, 3, accent);
|
||||||
|
it.filled_circle(x, y + 54, 3, accent);
|
||||||
|
}
|
||||||
|
it.line(40, 172, 280, 172, muted);
|
||||||
|
}
|
||||||
|
const char *weekdays[] = {"Sonntag", "Montag", "Dienstag", "Mittwoch",
|
||||||
|
"Donnerstag", "Freitag", "Samstag"};
|
||||||
|
it.printf(160, 190, id(font_small), Color::WHITE, TextAlign::TOP_CENTER,
|
||||||
|
"%s, %02d.%02d.%04d", weekdays[now.day_of_week - 1],
|
||||||
|
now.day_of_month, now.month, now.year);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Labels correspond to the left (A) and right (C) hardware buttons.
|
// Labels correspond to the left (A) and right (C) hardware buttons.
|
||||||
it.printf(8, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_LEFT,
|
it.printf(8, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_LEFT,
|
||||||
"< Zurück");
|
"< Zurück");
|
||||||
@@ -545,8 +638,11 @@ display:
|
|||||||
"Weiter >");
|
"Weiter >");
|
||||||
if (id(page_index) == 0) {
|
if (id(page_index) == 0) {
|
||||||
it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER,
|
it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER,
|
||||||
"Ansicht · 1 / 2");
|
"Ansicht · 1 / 3");
|
||||||
} else {
|
} else if (id(page_index) == 1) {
|
||||||
it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER,
|
it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER,
|
||||||
"Geräte %d / 2", id(device_usage_view) + 1);
|
"Geräte %d / 2", id(device_usage_view) + 1);
|
||||||
|
} else {
|
||||||
|
it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER,
|
||||||
|
"%s · 3 / 3", id(clock_digital_view) ? "Analog" : "Digital");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user