Add device power usage display page, enable device buttons in HA
This commit is contained in:
+196
-17
@@ -118,6 +118,12 @@ font:
|
|||||||
glyphsets:
|
glyphsets:
|
||||||
- GF_Latin_Kernel
|
- GF_Latin_Kernel
|
||||||
glyphs: ["äöüÄÖÜß"]
|
glyphs: ["äöüÄÖÜß"]
|
||||||
|
- file: "fonts/Roboto-Regular.ttf"
|
||||||
|
id: font_device
|
||||||
|
size: 13
|
||||||
|
glyphsets:
|
||||||
|
- GF_Latin_Kernel
|
||||||
|
glyphs: ["äöüÄÖÜß"]
|
||||||
- file: "fonts/materialdesignicons-webfont.ttf"
|
- file: "fonts/materialdesignicons-webfont.ttf"
|
||||||
id: font_icon
|
id: font_icon
|
||||||
size: 24
|
size: 24
|
||||||
@@ -143,6 +149,10 @@ globals:
|
|||||||
type: bool
|
type: bool
|
||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: 'false'
|
initial_value: 'false'
|
||||||
|
- id: device_usage_view
|
||||||
|
type: int
|
||||||
|
restore_value: true
|
||||||
|
initial_value: '0'
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
# WiFi signal strength
|
# WiFi signal strength
|
||||||
@@ -170,10 +180,118 @@ sensor:
|
|||||||
id: grid_export_energy_daily
|
id: grid_export_energy_daily
|
||||||
entity_id: sensor.energy_export_daily
|
entity_id: sensor.energy_export_daily
|
||||||
internal: true
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: hallway_fragrance_power
|
||||||
|
entity_id: sensor.flur_raumduft_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: cellar_power
|
||||||
|
entity_id: sensor.keller_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: sideboard_power
|
||||||
|
entity_id: sensor.kuche_anrichte_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: kitchen_music_power
|
||||||
|
entity_id: sensor.kuche_musik_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: bedroom_bed_power
|
||||||
|
entity_id: sensor.schlafzimmer_bett_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: bedroom_cinema_power
|
||||||
|
entity_id: sensor.schlafzimmer_heimkino_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: desk_decoration_power
|
||||||
|
entity_id: sensor.schreibtisch_deko_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: desk_power
|
||||||
|
entity_id: sensor.schreibtisch_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: server_room_power
|
||||||
|
entity_id: sensor.serverraum_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: living_room_cinema_power
|
||||||
|
entity_id: sensor.wohnzimmer_heimkino_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: games_cabinet_power
|
||||||
|
entity_id: sensor.wohnzimmer_spieleschrank_power
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: refrigerator_power
|
||||||
|
entity_id: sensor.tz3000_ww6drja5_ts011f_leistung
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: coffee_machine_power
|
||||||
|
entity_id: sensor.kaffeemaschine_leistung_2
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: dryer_power
|
||||||
|
entity_id: sensor.ikea_of_sweden_inspelning_smart_plug_leistung
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: washing_machine_power
|
||||||
|
entity_id: sensor.waschmaschine_leistung
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: arcade_power
|
||||||
|
entity_id: sensor.arcade_automat_leistung
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: dishwasher_power
|
||||||
|
entity_id: sensor.spulmaschine_leistung
|
||||||
|
internal: true
|
||||||
|
- platform: homeassistant
|
||||||
|
id: microwave_power
|
||||||
|
entity_id: sensor.waschetrockner_leistung
|
||||||
|
internal: true
|
||||||
- platform: wireguard
|
- platform: wireguard
|
||||||
latest_handshake:
|
latest_handshake:
|
||||||
name: 'WireGuard Latest Handshake'
|
name: 'WireGuard Latest Handshake'
|
||||||
|
|
||||||
|
script:
|
||||||
|
- id: show_previous_page
|
||||||
|
then:
|
||||||
|
- lambda: id(page_index) = (id(page_index) + 2 - 1) % 2;
|
||||||
|
- component.update: tft
|
||||||
|
- id: toggle_page_mode
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
if (id(page_index) == 0) {
|
||||||
|
id(page_one_gauge_view) = !id(page_one_gauge_view);
|
||||||
|
} else {
|
||||||
|
id(device_usage_view) = (id(device_usage_view) + 1) % 2;
|
||||||
|
}
|
||||||
|
- component.update: tft
|
||||||
|
- id: show_next_page
|
||||||
|
then:
|
||||||
|
- lambda: id(page_index) = (id(page_index) + 1) % 2;
|
||||||
|
- component.update: tft
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: template
|
||||||
|
name: "Zurück"
|
||||||
|
icon: mdi:arrow-left
|
||||||
|
on_press:
|
||||||
|
- script.execute: show_previous_page
|
||||||
|
- platform: template
|
||||||
|
name: "Modus"
|
||||||
|
icon: mdi:view-dashboard-outline
|
||||||
|
on_press:
|
||||||
|
- script.execute: toggle_page_mode
|
||||||
|
- platform: template
|
||||||
|
name: "Weiter"
|
||||||
|
icon: mdi:arrow-right
|
||||||
|
on_press:
|
||||||
|
- script.execute: show_next_page
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: wireguard
|
- platform: wireguard
|
||||||
status:
|
status:
|
||||||
@@ -189,9 +307,7 @@ binary_sensor:
|
|||||||
inverted: true
|
inverted: true
|
||||||
id: button_middle
|
id: button_middle
|
||||||
on_press:
|
on_press:
|
||||||
then:
|
- script.execute: toggle_page_mode
|
||||||
- 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.
|
# M5Stack Core button A (left). GPIO39 is input-only and has an external pull-up.
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
@@ -201,10 +317,7 @@ binary_sensor:
|
|||||||
inverted: true
|
inverted: true
|
||||||
id: button_left
|
id: button_left
|
||||||
on_press:
|
on_press:
|
||||||
then:
|
- script.execute: show_previous_page
|
||||||
- lambda: |-
|
|
||||||
id(page_index) = (id(page_index) + 2 - 1) % 2;
|
|
||||||
- component.update: tft
|
|
||||||
# M5Stack Core button C (right). GPIO37 is input-only and has an external pull-up.
|
# M5Stack Core button C (right). GPIO37 is input-only and has an external pull-up.
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
pin:
|
pin:
|
||||||
@@ -213,10 +326,7 @@ binary_sensor:
|
|||||||
inverted: true
|
inverted: true
|
||||||
id: button_right
|
id: button_right
|
||||||
on_press:
|
on_press:
|
||||||
then:
|
- script.execute: show_next_page
|
||||||
- lambda: |-
|
|
||||||
id(page_index) = (id(page_index) + 1) % 2;
|
|
||||||
- component.update: tft
|
|
||||||
|
|
||||||
text_sensor:
|
text_sensor:
|
||||||
- platform: wireguard
|
- platform: wireguard
|
||||||
@@ -353,10 +463,79 @@ display:
|
|||||||
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 {
|
||||||
it.printf(160, 45, id(font_title), Color::WHITE, TextAlign::TOP_CENTER,
|
// Page 2 lists nine consumers at once in two columns; button B changes group.
|
||||||
"Weitere Seite");
|
const int device_count = 18;
|
||||||
it.printf(160, 95, id(font_small), Color::WHITE, TextAlign::TOP_CENTER,
|
const int usage_group = id(device_usage_view);
|
||||||
"Für zusätzliche Werte vorbereitet");
|
const int page_start = usage_group * 9;
|
||||||
|
const char *device_names[device_count] = {
|
||||||
|
"Raumduft", "Keller", "Anrichte", "Musik", "Bett", "HK Schlafzimmer",
|
||||||
|
"Deko", "Schreibtisch", "Serverraum", "HK Wohnzimmer", "Spieleschrank",
|
||||||
|
"Kühlschrank", "Kaffeemaschine", "Wäschetrockner", "Waschmaschine", "Arcade",
|
||||||
|
"Spülmaschine", "Mikrowelle"};
|
||||||
|
float device_values[device_count] = {
|
||||||
|
id(hallway_fragrance_power).state, id(cellar_power).state, id(sideboard_power).state,
|
||||||
|
id(kitchen_music_power).state, id(bedroom_bed_power).state, id(bedroom_cinema_power).state,
|
||||||
|
id(desk_decoration_power).state, id(desk_power).state, id(server_room_power).state,
|
||||||
|
id(living_room_cinema_power).state, id(games_cabinet_power).state, id(refrigerator_power).state,
|
||||||
|
id(coffee_machine_power).state, id(dryer_power).state, id(washing_machine_power).state,
|
||||||
|
id(arcade_power).state, id(dishwasher_power).state, id(microwave_power).state};
|
||||||
|
bool device_has_state[device_count] = {
|
||||||
|
id(hallway_fragrance_power).has_state(), id(cellar_power).has_state(), id(sideboard_power).has_state(),
|
||||||
|
id(kitchen_music_power).has_state(), id(bedroom_bed_power).has_state(), id(bedroom_cinema_power).has_state(),
|
||||||
|
id(desk_decoration_power).has_state(), id(desk_power).has_state(), id(server_room_power).has_state(),
|
||||||
|
id(living_room_cinema_power).has_state(), id(games_cabinet_power).has_state(), id(refrigerator_power).has_state(),
|
||||||
|
id(coffee_machine_power).has_state(), id(dryer_power).has_state(), id(washing_machine_power).has_state(),
|
||||||
|
id(arcade_power).has_state(), id(dishwasher_power).has_state(), id(microwave_power).has_state()};
|
||||||
|
Color device_colors[device_count] = {
|
||||||
|
Color(255, 170, 40), Color(69, 189, 255), Color(170, 116, 217), Color(93, 207, 140),
|
||||||
|
Color(238, 112, 112), Color(107, 139, 255), Color(255, 130, 180), Color(122, 204, 174),
|
||||||
|
Color(240, 195, 90), Color(151, 120, 220), Color(91, 189, 193), Color(212, 132, 82),
|
||||||
|
Color(143, 190, 223), Color(233, 106, 142), Color(132, 205, 92), Color(255, 181, 80),
|
||||||
|
Color(111, 167, 229), Color(190, 137, 226)};
|
||||||
|
|
||||||
|
// The title uses the free area to the left of the status indicators.
|
||||||
|
it.printf(12, 10, id(font_device), Color::WHITE, "Geräteverbrauch");
|
||||||
|
for (int display_index = 0; display_index < 9; display_index++) {
|
||||||
|
const int index = page_start + display_index;
|
||||||
|
const int column = display_index % 2;
|
||||||
|
const int row = display_index / 2;
|
||||||
|
const int x = column == 0 ? 12 : 166;
|
||||||
|
const int y = 43 + row * 25;
|
||||||
|
if (device_has_state[index]) {
|
||||||
|
it.printf(x, y, id(font_device), device_colors[index], "%s: %.0f W",
|
||||||
|
device_names[index], device_values[index]);
|
||||||
|
} else {
|
||||||
|
it.printf(x, y, id(font_device), device_colors[index], "%s: -- W", device_names[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The stacked bar always represents all 18 consumer devices, not only this view's rows.
|
||||||
|
const int bar_x = 12;
|
||||||
|
const int bar_y = 180;
|
||||||
|
const int bar_width = 296;
|
||||||
|
const int bar_height = 18;
|
||||||
|
float usage_sum = 0.0f;
|
||||||
|
int last_active = -1;
|
||||||
|
for (int index = 0; index < device_count; index++) {
|
||||||
|
if (device_has_state[index] && device_values[index] > 0.0f) {
|
||||||
|
usage_sum += device_values[index];
|
||||||
|
last_active = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it.filled_rectangle(bar_x, bar_y, bar_width, bar_height, Color(42, 42, 42));
|
||||||
|
if (usage_sum > 0.0f) {
|
||||||
|
int cursor_x = bar_x;
|
||||||
|
for (int index = 0; index < device_count; index++) {
|
||||||
|
if (!device_has_state[index] || device_values[index] <= 0.0f) continue;
|
||||||
|
const int segment_width = index == last_active
|
||||||
|
? bar_x + bar_width - cursor_x
|
||||||
|
: static_cast<int>(device_values[index] * bar_width / usage_sum);
|
||||||
|
if (segment_width > 0) {
|
||||||
|
it.filled_rectangle(cursor_x, bar_y, segment_width, bar_height, device_colors[index]);
|
||||||
|
cursor_x += segment_width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Labels correspond to the left (A) and right (C) hardware buttons.
|
// Labels correspond to the left (A) and right (C) hardware buttons.
|
||||||
@@ -367,7 +546,7 @@ display:
|
|||||||
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 / 2");
|
||||||
} else {
|
} else {
|
||||||
it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER,
|
it.printf(160, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_CENTER,
|
||||||
"2 / 2");
|
"Geräte %d / 2", id(device_usage_view) + 1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user