From bb1f514fee95cb7f1852665f286e403f9b369dd9 Mon Sep 17 00:00:00 2001 From: Commander1024 Date: Sun, 16 Aug 2026 15:49:58 +0200 Subject: [PATCH] Add alternate gauge view for energy monitor Allow button B to toggle a persisted page-one gauge view with configurable grid and solar power limits. --- esphome/energymonitor.yaml | 71 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/esphome/energymonitor.yaml b/esphome/energymonitor.yaml index 89cc2e7..864a3df 100644 --- a/esphome/energymonitor.yaml +++ b/esphome/energymonitor.yaml @@ -1,6 +1,8 @@ substitutions: name: "energymonitor" friendly_name: "Energy Monitor" + grid_power_gauge_max_w: "5000.0" + balcony_solar_gauge_max_w: "800.0" esphome: name: ${name} @@ -137,6 +139,10 @@ globals: type: bool restore_value: false initial_value: 'false' + - id: page_one_gauge_view + type: bool + restore_value: true + initial_value: 'false' sensor: # WiFi signal strength @@ -175,6 +181,18 @@ binary_sensor: - platform: wireguard enabled: name: 'WireGuard Enabled' + # M5Stack Core button B (middle) toggles the alternate gauge view on page one. + - platform: gpio + pin: + number: GPIO38 + mode: INPUT + inverted: true + id: button_middle + on_press: + then: + - lambda: id(page_one_gauge_view) = !id(page_one_gauge_view); + - component.update: tft + # M5Stack Core button A (left). GPIO39 is input-only and has an external pull-up. - platform: gpio pin: @@ -250,7 +268,7 @@ display: } it.printf(312, 8, id(font_icon), wifi_color, TextAlign::TOP_RIGHT, "%s", wifi_icon); - if (id(page_index) == 0) { + if (id(page_index) == 0 && !id(page_one_gauge_view)) { it.printf(12, 12, id(font_small), Color::WHITE, "Netzleistung"); if (id(grid_power).has_state()) { const Color grid_power_color = id(grid_power).state >= 0 @@ -292,6 +310,48 @@ display: it.printf(308, 168, id(font_value), Color(255, 170, 40), TextAlign::TOP_RIGHT, "-- W"); } + } else if (id(page_index) == 0) { + // One shared gauge with two parallel curved bars: grid on the outside, solar inside. + const Color gauge_background = Color(42, 42, 42); + const int gauge_center_x = 160; + const int gauge_center_y = 188; + + // The outer band represents the absolute grid-power value with its signed color. + float grid_power_value = id(grid_power).has_state() ? id(grid_power).state : 0.0f; + float grid_power_magnitude = grid_power_value < 0.0f ? -grid_power_value : grid_power_value; + int grid_gauge_percent = static_cast(grid_power_magnitude * 100.0f / ${grid_power_gauge_max_w}); + if (grid_gauge_percent > 100) grid_gauge_percent = 100; + const Color grid_gauge_color = grid_power_value >= 0.0f + ? Color(143, 190, 223) // #8FBEDF + : Color(150, 110, 217); // #966ED9 + it.filled_gauge(gauge_center_x, gauge_center_y, 140, 122, 100, gauge_background); + it.filled_gauge(gauge_center_x, gauge_center_y, 140, 122, grid_gauge_percent, grid_gauge_color); + + // The inner band is solar power, normalized against the 800 W inverter maximum. + float solar_power_value = id(balcony_solar_power).has_state() ? id(balcony_solar_power).state : 0.0f; + int solar_gauge_percent = static_cast(solar_power_value * 100.0f / ${balcony_solar_gauge_max_w}); + if (solar_gauge_percent < 0) solar_gauge_percent = 0; + if (solar_gauge_percent > 100) solar_gauge_percent = 100; + const Color solar_gauge_color = Color(255, 170, 40); // #FFAA28 + it.filled_gauge(gauge_center_x, gauge_center_y, 116, 98, 100, gauge_background); + it.filled_gauge(gauge_center_x, gauge_center_y, 116, 98, solar_gauge_percent, solar_gauge_color); + + it.printf(gauge_center_x, 102, id(font_small), Color::WHITE, TextAlign::TOP_CENTER, + "Netzleistung"); + if (id(grid_power).has_state()) { + it.printf(gauge_center_x, 120, id(font_title), grid_gauge_color, TextAlign::TOP_CENTER, + "%+.0f W", grid_power_value); + } else { + it.printf(gauge_center_x, 120, id(font_title), Color::WHITE, TextAlign::TOP_CENTER, "-- W"); + } + it.printf(gauge_center_x, 151, id(font_small), Color::WHITE, TextAlign::TOP_CENTER, + "Balkonkraftwerk"); + if (id(balcony_solar_power).has_state()) { + it.printf(gauge_center_x, 169, id(font_title), solar_gauge_color, TextAlign::TOP_CENTER, + "%.0f W", solar_power_value); + } else { + it.printf(gauge_center_x, 169, id(font_title), solar_gauge_color, TextAlign::TOP_CENTER, "-- W"); + } } else { it.printf(160, 45, id(font_title), Color::WHITE, TextAlign::TOP_CENTER, "Weitere Seite"); @@ -304,5 +364,10 @@ display: "< Zurück"); it.printf(312, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_RIGHT, "Weiter >"); - it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER, - "%d / 2", id(page_index) + 1); + if (id(page_index) == 0) { + it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER, + "Ansicht · 1 / 2"); + } else { + it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER, + "2 / 2"); + }