LilyGo T457 working ESPHome still some issues to solve

Hi,
I have a Lilygo T547 V2.4 with S3 ESP, got it do compile with ESPHome and connected to HomeAssistant but still have som issue I want to fix. The case is, that this ePaper should mostly “sleep”, but if people want to get new informations, they should press a button on the display, the display updates thru HomeAssistant API (connect works), display newest things, and than people are able to press a touch button on the touch display. My problem now is that the “wakeup” takes quite some time, where the user does not see “anything” on the display. So my idea was to show “ASAP” a “Booting…” on the ePaper display, probable with a hint, how long the boot usually takes. As the blue LED goes on immediately, I was hoping to be “as fast” with writing on the ePaper, but I could not manage to do it. It takes about 10 seconds till the user sees something which are somehow “ages”.
(For wakign up from book I am using the RESET switch), as I had no luck with GPIO15 or GPIO16, which I ratherwould like to use. I could see both GPIO beeing triggered if the ESP is running, but I could not get it to make the ESP wake up.
My configuration is mainly form this setup.

I am using

on the board is printed V 2.4

Here is my ESPHome Yaml:
with this variable set:
rmgr_device_name: “${rmgr_device_name}”
and called via an include

So if anyone has an idea for any of those question, it would help me:
1.) Printing “Booting…” imemdiately on the Screen if the ESP gets power/awakes from deep_sleep
2.) Check on the board directly if the battery is charging (At the moment I assume charging if the volatage is increasing, which is computed on the HA)
3.) Awaking from deep_sleep thru an GPIO and not the used RESET

Many thanks
Juergen


# substitution fort ESPHome and recalculate in lambda for drawing
# rectangle (top_x, top_y, x_width, y_width) in the drawing


substitutions:
# Button Bottom Right
  button_br_x1: "680"
  button_br_y1: "425"
  button_br_x2: "890"
  button_br_y2: "500"
# Button Bottom Left
  button_bl_x1: "420" # 680 - length - padding = 680 - (button_br_x2 + button_br_x1) - 50 
  button_bl_y1: "${button_br_y1}" # same height as br but used for clarity below
  button_bl_x2: "630" # button_bl_x1 - (button_br_x2 + button_br_x1)
  button_bl_y2: "${button_br_y2}" # same height as br
# Button Bottom sleep
  button_bs_x1: "60" # 
  button_bs_y1: "${button_br_y1}" # same height as br but used for clarity below
  button_bs_x2: "270" # 
  button_bs_y2: "${button_br_y2}" # same height as br
# MDI fonts
# https://materialdesignicons.com/
# WIFI
  mdi_wifi: "\U000F05A9" # mdi-wifi
  mdi_wifi_strength_4: "\U000F0928" # mdi-wifi-strength-4
  mdi_wifi_strength_3: "\U000F0925" # mdi-wifi-strength-3 
  mdi_wifi_strength_2: "\U000F0922" # mdi-wifi-strength-2
  mdi_wifi_strength_1: "\U000F091F" # mdi-wifi-strength-1
  mdi_wifi_strength_alert_outline: "\U000F092B" # mdi-wifi-strength-alert-outline
  mdi_access_point: "\U000F0003" # mdi-access-point
# battery
  mdi_battery_80: "\U000F0081" # mdi-battery-80
  mdi_battery_60: "\U000F007F" # mdi-battery-60
  mdi_battery_40: "\U000F007D" # mdi-battery-40
  mdi_battery_20: "\U000F007B" # mdi-battery-20
  mdi_battery_10: "\U000F007A" # mdi-battery-10
  mdi_battery_charging_80: "\U000F008A" # mdi-battery-charging-80
  mdi_battery_charging_60: "\U000F0089" # mdi-battery-charging-60
  mdi_battery_charging_40: "\U000F0088" # mdi-battery-charging-40
  mdi_battery_charging_20: "\U000F0086" # mdi-battery-charging-20
  mdi_battery_charging_10: "\U000F089C" # mdi-battery-charging-10
  mdi_battery_unknown: "\U000F0091" # mdi-battery-unknown
# Misc
  mdi_book_outline: "\U000F0B64" # mdi-book-outline


esphome:
  name: "${rmgr_device_name}"
  friendly_name: "${rmgr_device_name}"
  platformio_options:
    board_build.f_flash: 80000000L
    board_build.flash_mode: qio
    board_build.psram_type: opi
    board_build.partitions: default_16MB.csv
    board_build.arduino.memory_type: qio_opi
    build_flags:  # the first three defines are required for the screen library to function.
      - "-DBOARD_HAS_PSRAM" #OK
      - "-DARDUINO_USB_MODE=1" #OK
      - "-DARDUINO_USB_CDC_ON_BOOT=1" #OK
  libraries:
    - SPI
  on_boot:
    - priority: -100
      then:
        - component.update: wifisignal
        - component.update: battery_voltage
    - priority: -800  # run as early as possible (must be <1000)
      then:
        - component.update: t5_display  # show "Booting..." immediately


esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: arduino
  variant: esp32s3
  flash_size: 16MB

i2c:
  - id: bus_a
    sda: GPIO18
    scl: GPIO17
    frequency: 100khz
    # There is some problems with i2c scan so turn scan off if problem appear on your board
    scan: False


touchscreen:
    platform: gt911
    id: lilygo_touchscreen
    interrupt_pin: GPIO47
    address: 0x5D
    i2c_id: bus_a
    setup_priority: -100
    transform:
    # because we use the display widescreen, buttons on top we have to transfer the touch
      mirror_x: false
      mirror_y: true
      swap_xy: true
    on_update:
        - lambda: |-
              for (auto touch: touches)  {
                  if (touch.state <= 2) {
                    ESP_LOGI("Touch points:", "id=%d x=%d, y=%d", touch.id, touch.x, touch.y);
                  }
              }


# Have Buttons in HomeAssistant for actions
# defined above and substitutions used also in lambda for drawing the rectangle on screen !!!

binary_sensor:
  - platform: touchscreen
    name: "bottom left touch"
    id: bl_touch
    x_min: ${button_bl_x1}
    y_min: ${button_bl_y1}
    x_max: ${button_bl_x2}
    y_max: ${button_bl_y2}
  - platform: touchscreen
    name: "bottom right touch"
    id: br_touch
    x_min: ${button_br_x1}
    y_min: ${button_br_y1}
    x_max: ${button_br_x2}
    y_max: ${button_br_y2}
  - platform: touchscreen
    name: "bottom sleep touch"
    id: bs_touch
    x_min: ${button_bs_x1}
    y_min: ${button_bs_y1}
    x_max: ${button_bs_x2}
    y_max: ${button_bs_y2}
  - platform: gpio
    pin: 
      number: GPIO21 # SENS OP_VN
      inverted: true
    name: "Button 1"
    on_press:
      - logger.log: "GPIO21 pressed"

text_sensor:
  - platform: homeassistant
    name: "Charging Status"
    id: ha_charging_status # internal here in ESPHome YAML
    entity_id: sensor.${rmgr_device_name}_battery_charging_status # ID in HA

globals:
  - id: sleep_duration
    type: int
    restore_value: no
    initial_value: '10'  # default sleep duration in seconds
  - id: overlay_text
    type: std::string
    restore_value: no
    initial_value: ""
  - id: is_booting
    type: bool
    restore_value: no
    initial_value: 'true'

# Enable logging
logger:

# we need time :-)
time:
  - platform: homeassistant
    id: ha_time

# Enable Home Assistant API
api:
  encryption:
    key: !secret api_encryption_key
  services:
    - service: set_sleep_duration
      variables:
        duration: int
      then:
        - lambda: |-
            id(sleep_duration) = duration;
            ESP_LOGI("Sleep", "Sleep duration set to %d seconds", duration);
  on_client_connected:
    then:
      - logger.log: "Connected to HomeAssistant. -> booted"
      - homeassistant.event:
          event: esphome.${rmgr_device_name}.booted
      - lambda: 'id(is_booting) = false;' # to not print "Booting..." a second time
      - lambda: 'id(overlay_text) = "";' # to prevent the screen updated twice after wakeup from deep_sleep; having an extra boolean might be the better idea
      - component.update: t5_display

#      - logger.log: "simulate refresh to refresh the screen on first connect"
#      - homeassistant.event:
#          event: esphome.${rmgr_device_name}

switch:
  - platform: template
    name: "Trigger Sleep"
    restore_mode: ALWAYS_OFF
    turn_on_action:
      - script.execute: go_to_sleep

# scripts for putting ESP into sleep and informing the User on ePaper

script:
# to print on screen until when we sleep
  - id: go_to_sleep
    mode: restart
    then:
      - lambda: |-
          auto now = id(ha_time).now();
          auto timestamp = now.timestamp + id(sleep_duration) - 10; // seems to have 10 sec offset 
          auto future = esphome::ESPTime::from_epoch_local(timestamp);

          // Map day_of_week (0 = saturday) to 3-letter name
          const char* days[] = {"SAT", "SUN", "MON", "TUE", "WED", "THU", "FRI" };
          int dow = future.day_of_week % 7;  // ensure it's in 0..6
          const char* day_str = days[dow];

          char wake_time[50];
          snprintf(wake_time, sizeof(wake_time), "Sleeping until: [%02d:%s] %04d-%02d-%02d %02d:%02d:%02d",
              dow,day_str,
              future.year, future.month, future.day_of_month,
              future.hour, future.minute, future.second);

          id(overlay_text) = wake_time;
          ESP_LOGI("sleep", "Device will sleep until: %s", wake_time);
      - component.update: t5_display
#      - delay: 3s
      - script.execute: sleep_now

# to immediately put ESP into sleep
  - id: sleep_now
    then:
      - lambda: |-
          ESP.deepSleep(id(sleep_duration) * 1000000ULL);


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Not needed, as the API connect takes way longer than the WIFI connect 
#
#  fast_connect: true
#  manual_ip:
#    static_ip: 172.16.0.200
#    gateway: 172.16.0.1
#    subnet: 255.255.255.0


external_components:
  - source: github://nickolay/esphome-lilygo-t547plus
    components: ["t547"]
  - source: github://kaeltis/esphome-lilygo-t547plus
    components: ["lilygo_t5_47_battery"]

font:
  - file: 'fonts/GothamRnd-Book.ttf'
    id: font_medium_gotham
    size: 30

  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_mdi_medlarge
    size: 35
    glyphs:
      - "${mdi_wifi}"
      - "${mdi_wifi_strength_4}"
      - "${mdi_wifi_strength_3}"
      - "${mdi_wifi_strength_2}"
      - "${mdi_wifi_strength_1}"
      - "${mdi_wifi_strength_alert_outline}"
      - "${mdi_book_outline}"
      # battery
      - "${mdi_battery_80}"
      - "${mdi_battery_60}"
      - "${mdi_battery_40}"
      - "${mdi_battery_20}"
      - "${mdi_battery_10}"
      - "${mdi_battery_charging_80}"
      - "${mdi_battery_charging_60}"
      - "${mdi_battery_charging_40}"
      - "${mdi_battery_charging_20}"
      - "${mdi_battery_charging_10}"
      - "${mdi_battery_unknown}"
      

display:
  - platform: t547
    id: t5_display
    update_interval: never
    lambda: |-
      auto draw_rect_frame = [&](display::Display &it,
                            int x1, int y1, int x2, int y2,
                            int thickness,
                            std::string label = "",
                            esphome::font::Font* font = nullptr) {
        int width = x2 - x1;
        int height = y2 - y1;

        // Draw borders
        it.filled_rectangle(x1, y1, width, thickness);                     // top
        it.filled_rectangle(x1, y2 - thickness, width, thickness);         // bottom
        it.filled_rectangle(x1, y1, thickness, height);                    // left
        it.filled_rectangle(x2 - thickness, y1, thickness, height);        // right

        // Optional: draw label text centered inside
        if (!label.empty() && font != nullptr) {
          int cx = x1 + width / 2;
          int cy = y1 + height / 2 + 5;
          it.printf(cx, cy, font, TextAlign::CENTER, "%s", label.c_str());
        }
      };

      auto draw_for_test = [&](display::Display &it) {
        int x = it.get_width() / 2;
        int y = it.get_height() / 2;
        it.printf(x, y, id(font_medium_gotham), TextAlign::TOP_CENTER, "Waiting ...");
        it.filled_circle(20, 32, 15);
        it.circle(20, 42, 15);
        it.filled_gauge(75, 75, 30, 20, 80);
        it.filled_regular_polygon(170, 45, 20, EDGES_HEXAGON);
        it.regular_polygon(340, 90, 40, EDGES_OCTAGON, VARIATION_FLAT_TOP);

        it.printf(520,300, id(font_mdi_medlarge), "${mdi_book_outline}");
      };

      auto draw_wifi_icon = [&](display::Display &it) {
        std::string wifi_symbol = "${mdi_access_point}";  // default if no state!

        if (id(wifisignal).has_state()) {
          float rssi = id(wifisignal).state;
          if (rssi >= -50) {
            wifi_symbol = "${mdi_wifi_strength_4}";
          } else if (rssi >= -60) {
            wifi_symbol = "${mdi_wifi_strength_3}";
          } else if (rssi >= -67) {
            wifi_symbol = "${mdi_wifi_strength_2}";
          } else if (rssi >= -70) {
            wifi_symbol = "${mdi_wifi_strength_1}";
          } else {
            wifi_symbol = "${mdi_wifi_strength_alert_outline}";
          }
        }
      // soll neben die Buttons gedruckt werden über wifi
      it.printf(${button_br_x2} + 15, ${button_br_y1} + (${button_br_y2} - ${button_br_y1}) / 2 , id(font_mdi_medlarge), TextAlign::TOP_LEFT, wifi_symbol.c_str());
      };

      auto draw_battery_icon = [&](display::Display &it) {
        std::string batt_symbol = "${mdi_battery_unknown}";  // default if no state!

        if (id(battery_voltage_voltage).has_state()) {
          float batt = id(battery_voltage_voltage).state;
          bool charging = id(ha_charging_status).has_state() && id(ha_charging_status).state == "charging";
          if (charging) {
            if (batt >= 4.43) {
              batt_symbol = "${mdi_battery_charging_80}";
            } else if (batt >= 4) {
              batt_symbol = "${mdi_battery_charging_60}";
            } else if (batt >= 3.9) {
              batt_symbol = "${mdi_battery_charging_40}";
            } else if (batt >= 3.8) {
              batt_symbol = "${mdi_battery_charging_20}";
            } else {
              batt_symbol = "${mdi_battery_charging_10}";
            }
          } else {
              if (batt >= 4.43) {
                batt_symbol = "${mdi_battery_80}";
            } else if (batt >= 4) {
              batt_symbol = "${mdi_battery_60}";
            } else if (batt >= 3.9) {
              batt_symbol = "${mdi_battery_40}";
            } else if (batt >= 3.8) {
              batt_symbol = "${mdi_battery_20}";
            } else {
              batt_symbol = "${mdi_battery_10}";
            }
          }
        }
  
      // soll neben die Buttons gedruckt werden über wifi
      it.printf(${button_br_x2} + 15, ${button_br_y1} + (${button_br_y2} - ${button_br_y1}) / 2 - 40, id(font_mdi_medlarge), TextAlign::TOP_LEFT, batt_symbol.c_str());
      };

      auto draw_sleep_overlay = [&](display::Display &it) {
        it.printf(${button_br_x2}, ${button_br_y1} + (${button_br_y2} - ${button_br_y1}) / 2,
                  id(font_medium_gotham), TextAlign::CENTER_RIGHT,
                  id(overlay_text).c_str());
      };

      auto draw_buttons = [&](display::Display &it) {
        // below draw empty rectangle frame
        // draw_rect_frame(it, ${button_bl_x1}, ${button_bl_y1}, ${button_bl_x2}, ${button_bl_y2}, 8);
        // below draw rectanle with text centered
        draw_rect_frame(it, ${button_bl_x1}, ${button_bl_y1}, ${button_bl_x2}, ${button_bl_y2}, 12, "15 Min", id(font_medium_gotham));
        draw_rect_frame(it, ${button_br_x1}, ${button_br_y1}, ${button_br_x2}, ${button_br_y2}, 12, "30 Min", id(font_medium_gotham));
        draw_rect_frame(it, ${button_bs_x1}, ${button_bs_y1}, ${button_bs_x2}, ${button_bs_y2}, 12, "SLEEP", id(font_medium_gotham));

        //it.filled_rectangle(${button_bl_x1}, ${button_bl_y1},
        //                    ${button_bl_x2} - ${button_bl_x1}, ${button_bl_y2} - ${button_bl_y1});


      };




      // ##### below the drawing happens
      // befor the "if" the stuff is always on screen
      if (id(is_booting)) {
        it.printf(it.get_width() / 2, it.get_height() / 2, id(font_medium_gotham), TextAlign::CENTER, "Booting...");
        return;
      } else {
        draw_for_test(it);
        draw_battery_icon(it);
        if (id(overlay_text) != "") {
          // Here we go to Sleep Mode
          draw_sleep_overlay(it);
        } else {
          // Printe in NON Sleep Mode
          draw_buttons(it);
          draw_wifi_icon(it);
        }
      }

sensor:
  - platform: lilygo_t5_47_battery
    id: battery_voltage
    update_interval: 600s # we sleep a lot, and call it during wakeup
    voltage:
      name: "Battery Voltage"
      id: battery_voltage_voltage
  - platform: wifi_signal
    name: "WiFi Signal Strength"
    id: "wifisignal"
    unit_of_measurement: "dBm"
    entity_category: "diagnostic"
# update not really needed due to deep_sleep
    update_interval: never