substitutions: name: "energymonitor" friendly_name: "Energy Monitor" esphome: name: ${name} friendly_name: ${friendly_name} name_add_mac_suffix: false project: name: monitor.energymonitor version: "1.0" on_boot: then: - light.turn_on: display_backlight esp32: board: m5stack-core-esp32 framework: type: esp-idf network: enable_ipv6: true wifi: networks: - ssid: "Voltage-legacy" password: !secret voltage_legacy_psk priority: 10 - ssid: "Moppelkotze" password: !secret moppelkotze_psk priority: 5 on_connect: - lambda: id(wifi_connected) = true; on_disconnect: - lambda: id(wifi_connected) = false; power_save_mode: high min_auth_mode: WPA2 ap: ssid: "Energymonitor Fallback Hotspot" password: !secret fallback_psk captive_portal: time: - platform: sntp id: sntp_time timezone: Europe/Berlin servers: - de.pool.ntp.org logger: api: encryption: key: !secret apikey ota: platform: esphome password: !secret ota spi: clk_pin: GPIO18 mosi_pin: GPIO23 output: - platform: gpio pin: GPIO32 id: display_backlight_output light: - platform: binary id: display_backlight name: "Display Backlight" output: display_backlight_output restore_mode: ALWAYS_ON font: - file: "fonts/Roboto-Regular.ttf" id: font_small size: 18 glyphsets: - GF_Latin_Kernel glyphs: ["äöüÄÖÜß"] - file: "fonts/Roboto-Bold.ttf" id: font_title size: 28 glyphsets: - GF_Latin_Kernel glyphs: ["äöüÄÖÜß"] - file: "fonts/Roboto-Bold.ttf" id: font_value size: 52 glyphsets: - GF_Latin_Kernel glyphs: ["äöüÄÖÜß"] # M5CORE is the mipi_spi preset for the M5Stack Core's integrated display. display: - platform: mipi_spi id: tft model: M5CORE cs_pin: GPIO14 dc_pin: GPIO27 reset_pin: GPIO33 invert_colors: true update_interval: 1s lambda: |- it.fill(Color::BLACK); if (id(sntp_time).now().is_valid()) { it.strftime(284, 10, id(font_small), Color::WHITE, TextAlign::TOP_RIGHT, "%H:%M", id(sntp_time).now()); } else { it.printf(284, 10, id(font_small), Color::WHITE, TextAlign::TOP_RIGHT, "--:--"); } // Four bars show RSSI quality; a crossed outline means Wi-Fi is disconnected. if (id(wifi_connected)) { int bars = 1; if (id(wifi_rssi).has_state()) { const float rssi = id(wifi_rssi).state; bars = rssi >= -55 ? 4 : rssi >= -67 ? 3 : rssi >= -75 ? 2 : 1; } for (int index = 0; index < 4; index++) { const int height = 5 + index * 5; const Color color = index < bars ? Color(64, 255, 64) : Color(48, 48, 48); it.filled_rectangle(290 + index * 5, 30 - height, 3, height, color); } } else { const Color disconnected_color = Color(255, 80, 80); it.rectangle(290, 10, 19, 19, disconnected_color); it.line(290, 10, 308, 28, disconnected_color); it.line(308, 10, 290, 28, disconnected_color); } if (id(page_index) == 0) { it.printf(12, 12, id(font_small), Color::WHITE, "Netzleistung"); if (id(grid_power).has_state()) { it.printf(308, 32, id(font_value), Color::WHITE, TextAlign::TOP_RIGHT, "%+.0f W", id(grid_power).state); } else { it.printf(308, 42, id(font_value), Color::WHITE, TextAlign::TOP_RIGHT, "-- W"); } it.printf(12, 99, id(font_small), Color::WHITE, "Balkonkraftwerk"); if (id(balcony_solar_power).has_state()) { it.printf(308, 119, id(font_value), Color(255, 215, 0), TextAlign::TOP_RIGHT, "%.0f W", id(balcony_solar_power).state); } else { it.printf(308, 129, id(font_value), Color(255, 215, 0), TextAlign::TOP_RIGHT, "-- W"); } } else { it.printf(160, 45, id(font_title), Color::WHITE, TextAlign::TOP_CENTER, "Weitere Seite"); it.printf(160, 95, id(font_small), Color::WHITE, TextAlign::TOP_CENTER, "Für zusätzliche Werte vorbereitet"); } // Labels correspond to the left (A) and right (C) hardware buttons. it.printf(8, 239, id(font_small), Color::WHITE, TextAlign::BOTTOM_LEFT, "< 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); globals: - id: page_index type: int restore_value: true initial_value: '0' - id: wifi_connected type: bool restore_value: false initial_value: 'false' sensor: - platform: wifi_signal id: wifi_rssi internal: true update_interval: 10s - platform: homeassistant id: grid_power entity_id: sensor.netzleistung internal: true - platform: homeassistant id: balcony_solar_power entity_id: sensor.balkonkraftwerk_power internal: true binary_sensor: # M5Stack Core button A (left). GPIO39 is input-only and has an external pull-up. - platform: gpio pin: number: GPIO39 mode: INPUT inverted: true id: button_left on_press: then: - 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. - platform: gpio pin: number: GPIO37 mode: INPUT inverted: true id: button_right on_press: then: - lambda: |- id(page_index) = (id(page_index) + 1) % 2; - component.update: tft