esphome:
  name: epaper-v2
  friendly_name: ePaper-v2
  includes:
    - MAX17043_component.h
  libraries:
  - "Wire"

  on_boot:
      priority: -100.0
      then:
        - wait_until:
            condition:
              lambda: 'return id(data_updated) == true;'
        # Wait a bit longer so all the items are received
        - delay: 5s
        - logger.log: "Initial sensor data received: Refreshing display..."
        - lambda: 'id(initial_data_received) = true;'

        # refresh screen only if needed
        - if:
            condition:
              ##and:
              binary_sensor.is_on: screen_refresh_wanted
              #- lambda: 'return id(data_updated) == true;'
            then:  
              - script.execute: update_screen
            else:
              - if:
                  condition:
                    binary_sensor.is_on: auto_deep_sleep_activated
                  then:
                    - logger.log: "Screen update skipped since refresh is not wanted. Starting deep sleep..."
                    - script.execute: start_deep_sleep

esp32:
  board: seeed_xiao_esp32c3
  framework:
    type: arduino

i2c:
  sda: GPIO06
  scl: GPIO07
  scan: true
  id: i2c_main

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "ExUuNuSUoaxRok/hgZzctECziPedq7IIN09KTqdvydw="
    
ota:
  platform: esphome
  password: "b031623c7b286d12c44aa839335fa1cd"

wifi:
  ssid: "MondfischBox"
  password: "368093827689566"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Epaper Fallback Hotspot"
    password: "8wAOMyyDmJ2V"

captive_portal:

sun:
  latitude: 50.935173°
  longitude: 6.953101°

interval:
  - interval: 3min
    startup_delay: 3min
    then:
      if:
        condition:
          not:
            wifi.connected:
        then:
        #draw no wifi found message
          - logger.log: "No WiFi found. :/ Updating screen and entering deep sleep..."
          - script.execute: update_screen
          - script.execute: start_deep_sleep


  - interval: 4min
    startup_delay: 4min
    then:
      # enter deep sleep if activated
      if:
        condition:
          binary_sensor.is_on: auto_deep_sleep_activated            
        then:
          - script.execute: start_deep_sleep
        else:
          - logger.log: "Auto deep sleep not active. Will stay awake..."

  - interval: 30min
    startup_delay: 3min
    then:
      # refresh screen only if needed
      if:
        condition:
            ###and:
              binary_sensor.is_on: screen_refresh_wanted
              #- lambda: 'return id(data_updated) == true;'            
        then:  
          - script.execute: update_screen
        else:
          - logger.log: "Screen update skipped since refresh is not wanted."


deep_sleep:
  id: deep_sleep_1
  wakeup_pin:
    number: GPIO2
    inverted: false
    allow_other_uses: true
    mode: 
      input: true
      pullup: true
  wakeup_pin_mode: KEEP_AWAKE


web_server:
  port: 80
  auth:
    username: "tonwelle"
    password: "homepagett47ab"



time:
  - platform: homeassistant
    id: homeassistant_time
    timezone: "Europe/Berlin"

text_sensor: 
  - platform: version
    name: "ESPHome Version"

  - platform: wifi_info
    ip_address:
      name: IP Address
    ssid:
      name: Connected SSID
    bssid:
      name: Connected BSSID
    mac_address:
      name: Mac Wifi Address
    scan_results:
      name: Latest Scan Results

  - platform: homeassistant
    entity_id: sensor.wochentag
    id: wochentag
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.morgen
    id: morgen
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.uebermorgen
    id: uebermorgen
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  
  - platform: homeassistant
    entity_id: sensor.ueberuebermorgen
    id: ueberuebermorgen
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.ueberueberuebermorgen
    id: ueberueberuebermorgen
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.wochentag_datum
    id: wochentag_datum
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.termineheute
    id: termine_heute
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'  


  - platform: homeassistant
    entity_id: sensor.terminemorgen
    id: termine_morgen
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'  

  - platform: homeassistant
    entity_id: sensor.termineuebermorgen
    id: termine_uebermorgen
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'  

  - platform: homeassistant
    entity_id: sensor.termineueberuebermorgen
    id: termine_ueberuebermorgen
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'  
  
  - platform: homeassistant
    entity_id: sensor.termineueberueberuebermorgen
    id: termine_ueberueberuebermorgen
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'  

  - platform: homeassistant
    entity_id: weather.home
    id: weather_state
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_now
    id: weather_condition_now
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_0
    id: weather_condition_0
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_timestamp_0
    id: weather_timestamp_0
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_1
    id: weather_condition_1
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_timestamp_1
    id: weather_timestamp_1
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_2
    id: weather_condition_2
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_timestamp_2
    id: weather_timestamp_2
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_3
    id: weather_condition_3
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_timestamp_3
    id: weather_timestamp_3
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_4
    id: weather_condition_4
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_timestamp_4
    id: weather_timestamp_4
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: binary_sensor.ribba_frame_display_refresh_wanted
    id: display_refresh_wanted_external_sensor
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: sun
    id: weather_sunrise
    type: sunrise

  - platform: sun
    id: weather_sunset
    type: sunset

sensor:
  # Create sensors for monitoring Weatherman remotely.
  
  - platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
    name: "WiFi Signal dB"
    id: wifi_signal_db
    update_interval: 60s
    entity_category: "diagnostic"
  
  - platform: copy # Reports the WiFi signal strength in %
    source_id: wifi_signal_db
    name: "WiFi Signal Percent"
    id: wifi_signal_percent
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "Signal %"
    entity_category: "diagnostic"

  - platform: uptime
    name: Uptime

  - platform: internal_temperature
    name: "Internal Temperature"

  - platform: template
    name: "Display Last Update"
    device_class: timestamp
    entity_category: "diagnostic"
    id: display_last_update
    
  - platform: template
    name: "Display Refresh Count"
    accuracy_decimals: 0
    unit_of_measurement: "Refreshes"
    state_class: "total_increasing"
    entity_category: "diagnostic"
    lambda: 'return id(recorded_display_refresh);'

  - platform: homeassistant
    entity_id: weather.hourly
    attribute: temperature
    id: weather_temperature
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.balkon_temperatur
    #attribute: weather_temperature_0
    id: weather_temperature_0
#    on_value:
#      then:
#        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_temperature_1
    id: weather_temperature_1
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_temperature_2
    id: weather_temperature_2
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_temperature_3
    id: weather_temperature_3
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_temperature_4
    id: weather_temperature_4
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
        
  # thanks to https://github.com/esphome/feature-requests/issues/1055
  - platform: custom
    lambda: |-
      auto max17043_sensor = new MAX17043Sensor();
      App.register_component(max17043_sensor);
      return {max17043_sensor->voltage_sensor, max17043_sensor->percentage_sensor};
    sensors:
      - name: "Battery voltage"
        id: "battery_voltage"
        unit_of_measurement: "mV"
        state_class: "measurement"
        device_class: "voltage"
        accuracy_decimals: 0
      - name: "Battery percentage"
        id: "battery_percentage"
        #icon: mdi:battery-outline
        unit_of_measurement: "%"
        state_class: "measurement"
        device_class: "battery"
        accuracy_decimals: 0

binary_sensor:
  - platform: homeassistant
    entity_id: binary_sensor.weatherman_motion_detected
    id: motion_detected

  - platform: gpio
    id: auto_sleep_activated_hw_switch
    name: "Auto Sleep On/Off HW Switch"
    pin:
      allow_other_uses: true
      number: GPIO02
      inverted: true
      mode:
        input: true
        pullup: true

  - platform: homeassistant
    entity_id: input_boolean.ribba_frame_auto_sleep_activated
    id: auto_sleep_activated_sw_switch

  - platform: template
    name: "Auto Sleep On/Off SW Switch"
    id: auto_sleep_activated_sw_switch_display_dummy
    lambda: |-
      return (id(auto_sleep_activated_sw_switch).state);

  - platform: template
    name: "Screen refresh wanted"
    id: "screen_refresh_wanted"
    lambda: |-
      return (id(display_refresh_wanted_external_sensor).state == "on");

  - platform: template
    name: "Auto deep sleep active"
    id: "auto_deep_sleep_activated"
    lambda: |-
      return (id(auto_sleep_activated_sw_switch).state and id(auto_sleep_activated_hw_switch).state);
    # If auto deep sleep changed update screen accordingly
    on_state:
      then:
        # refresh screen only if needed
        - if:
            condition:
              binary_sensor.is_on: auto_deep_sleep_activated
            then:
              - if:
                  condition:
                    #####and:
                     - binary_sensor.is_on: screen_refresh_wanted
                     #- lambda: 'return id(data_updated) == true;'

                  then:  
                    - script.execute: update_screen
              - script.execute: start_deep_sleep
            else:
              - if:
                  condition:
                    ####and:
                     - binary_sensor.is_on: screen_refresh_wanted
                     #- lambda: 'return id(data_updated) == true;'
                  then:  
                    - script.execute: update_screen

switch:
  - platform: template
    name: "Show frame alignment aid"
    id: show_frame_alignment_aid_switch
    optimistic: True
    restore_mode: RESTORE_DEFAULT_OFF 
    on_turn_on:
      then:
        - if:
            condition:
              binary_sensor.is_on: screen_refresh_wanted
            then:  
              - script.execute: update_screen
    on_turn_off:
      then:
        - if:
            condition:
              binary_sensor.is_on: screen_refresh_wanted
            then:  
              - script.execute: update_screen


number:
  - platform: template
    name: Sleep time
    id: deep_sleep_duration_seconds
    max_value: 86400
    min_value: 30
    step: 1
    unit_of_measurement: "s"
    optimistic: true
    restore_value: true
    initial_value: 1800
    mode: box

# Pins for Waveshare ePaper ESP Board
spi:
  clk_pin: GPIO08
  mosi_pin: GPIO10

button:
  - platform: shutdown
    name: "Shutdown ESP"
  - platform: restart
    name: "Restart ESP"
  - platform: template
    name: "Refresh Screen"
    on_press:
      - script.execute: update_screen
  - platform: template
    name: "Start deep sleep"
    on_press:
      - script.execute: start_deep_sleep

script:
  - id: update_screen
    then:
      - logger.log: "Updating screen..."
      - component.update: eink_display
      - lambda: 'id(recorded_display_refresh) += 1;'
      - lambda: 'id(display_last_update).publish_state(id(homeassistant_time).now().timestamp);'
      - logger.log: "...screen update finished."

  - id: start_deep_sleep
    then:
      - logger.log: "Starting deep sleep in 20 seconds..."
      - delay: 20s
      - lambda: |-
          id(deep_sleep_1).set_sleep_duration(id(deep_sleep_duration_seconds).state*1000);
      - deep_sleep.enter:
          id: deep_sleep_1

globals:
  - id: data_updated
    type: bool
    restore_value: no
    initial_value: 'false'
  - id: initial_data_received
    type: bool
    restore_value: no
    initial_value: 'false'
  - id: recorded_display_refresh
    type: int
    restore_value: yes
    initial_value: '0'


font:
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_small_book
    size: 18
    glyphs:
      ['&', '@', '!', '?', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
       '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
       'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
       'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
       'u', 'v', 'w', 'x', 'y', 'z', 'å', 'ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', '/', '€', '’', 'ß'] 
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_large_bold
    size: 108
    glyphs: [' ', '-', '°', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C']
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_title
    size: 54
    glyphs:
      ['&', '@', '!', '?', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
       '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
       'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
       'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
       'u', 'v', 'w', 'x', 'y', 'z', 'å', 'ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', '/', '€', '’', 'ß'] 
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_medium_bold
    size: 30
    glyphs:
      ['&', '@', '!', '?', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
       '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
       'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
       'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
       'u', 'v', 'w', 'x', 'y', 'z', 'å', 'ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', '/', '€', '’', 'ß'] 
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_small_bold
    size: 25
    glyphs:
      ['&', '@', '!', '?', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
       '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
       'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
       'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
       'u', 'v', 'w', 'x', 'y', 'z', 'å', 'ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', '/', '€', '’', 'ß'] 

  # Include Material Design Icons font
  # Thanks to https://community.home-assistant.io/t/display-materialdesign-icons-on-esphome-attached-to-screen/199790/16
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_mdi_large
    size: 96
    glyphs: &mdi-weather-glyphs
      - "\U000F0590" # mdi-weather-cloudy
      - "\U000F0F2F" # mdi-weather-cloudy-alert
      - "\U000F0E6E" # mdi-weather-cloudy-arrow-right
      - "\U000F0591" # mdi-weather-fog
      - "\U000F0592" # mdi-weather-hail
      - "\U000F0F30" # mdi-weather-hazy
      - "\U000F0898" # mdi-weather-hurricane
      - "\U000F0593" # mdi-weather-lightning
      - "\U000F067E" # mdi-weather-lightning-rainy
      - "\U000F0594" # mdi-weather-night
      - "\U000F0F31" # mdi-weather-night-partly-cloudy
      - "\U000F0595" # mdi-weather-partly-cloudy
      - "\U000F0F32" # mdi-weather-partly-lightning
      - "\U000F0F33" # mdi-weather-partly-rainy
      - "\U000F0F34" # mdi-weather-partly-snowy
      - "\U000F0F35" # mdi-weather-partly-snowy-rainy
      - "\U000F0596" # mdi-weather-pouring
      - "\U000F0597" # mdi-weather-rainy
      - "\U000F0598" # mdi-weather-snowy
      - "\U000F0F36" # mdi-weather-snowy-heavy
      - "\U000F067F" # mdi-weather-snowy-rainy
      - "\U000F0599" # mdi-weather-sunny
      - "\U000F0F37" # mdi-weather-sunny-alert
      - "\U000F14E4" # mdi-weather-sunny-off
      - "\U000F059A" # mdi-weather-sunset
      - "\U000F059B" # mdi-weather-sunset-down
      - "\U000F059C" # mdi-weather-sunset-up
      - "\U000F0F38" # mdi-weather-tornado
      - "\U000F059D" # mdi-weather-windy
      - "\U000F059E" # mdi-weather-windy-variant
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_mdi_medium
    size: 36
    glyphs: *mdi-weather-glyphs

  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_wifi_bat
    size: 20
    glyphs: [

      # Wifi
      '󰤮', # F092E mdi-wifi-strength-off-outline
      '󰤯', # F092F mdi-wifi-strength-outline
      '󰤟', # F091F mdi-wifi-strength-1
      '󰤢', # F0922 mdi-wifi-strength-2
      '󰤥', # F0925 mdi-wifi-strength-3
      '󰤨', # F0928 mdi-wifi-strength-4
      
      # Battery
      '󰁺', # F007A mdi-battery-10
      '󰁻', # F007B mdi-battery-20
      '󰁼', # F007C mdi-battery-30
      '󰁽', # F007D mdi-battery-40
      '󰁾', # F007E mdi-battery-50
      '󰁿', # F007F mdi-battery-60
      '󰂀', # F0080 mdi-battery-70
      '󰂁', # F0081 mdi-battery-80
      '󰂂', # F0082 mdi-battery-90
      '󰁹', # F0079 mdi-battery 100
      ]

color:
  - id: color_bg
    red: 0%
    green: 0%
    blue: 50%
    white: 0%
  - id: color_text
    red: 0%
    green: 0%
    blue: 0%
    white: 0%
  - id: color_black
    red: 0%
    green: 0%
    blue: 50%
    white: 0%
  - id: color_white
    red: 0%
    green: 0%
    blue: 0%
    white: 0%


# Now render everything on the ePaper screen.
display:
  - platform: waveshare_epaper
    id: eink_display
    cs_pin: GPIO05
    dc_pin: GPIO04
    reset_pin: GPIO03
    reset_duration: 2ms
    model: 7.50in-bV3
    update_interval: never
    rotation: 270°
    lambda: |-

      // Map weather states to MDI characters.
      std::map<std::string, std::string> weather_icon_map
        {
          {"cloudy", "\U000F0590"},
          {"cloudy-alert", "\U000F0F2F"},
          {"cloudy-arrow-right", "\U000F0E6E"},
          {"fog", "\U000F0591"},
          {"hail", "\U000F0592"},
          {"hazy", "\U000F0F30"},
          {"hurricane", "\U000F0898"},
          {"lightning", "\U000F0593"},
          {"lightning-rainy", "\U000F067E"},
          {"clear-night", "\U000F0594"},
          {"night-partly-cloudy", "\U000F0F31"},
          {"partlycloudy", "\U000F0595"},
          {"partly-lightning", "\U000F0F32"},
          {"partly-rainy", "\U000F0F33"},
          {"partly-snowy", "\U000F0F34"},
          {"partly-snowy-rainy", "\U000F0F35"},
          {"pouring", "\U000F0596"},
          {"rainy", "\U000F0597"},
          {"snowy", "\U000F0598"},
          {"snowy-heavy", "\U000F0F36"},
          {"snowy-rainy", "\U000F067F"},
          {"sunny", "\U000F0599"},
          {"sunny-alert", "\U000F0F37"},
          {"sunny-off", "\U000F14E4"},
          {"sunset", "\U000F059A"},
          {"sunset-down", "\U000F059B"},
          {"sunset-up", "\U000F059C"},
          {"tornado", "\U000F0F38"},
          {"windy", "\U000F059D"},
          {"windy-variant", "\U000F059E"},
        };

      // Fill background.
      it.fill(color_bg);

      int wifi_icon_x = 440;
      int wifi_icon_y = 765;

      int battery_icon_x = 40;
      int battery_icon_y = 765;


      if (id(initial_data_received) == false) 
      {

        it.fill(color_white);

        if (id(show_frame_alignment_aid_switch).state)
        {
          it.rectangle(25, 60, 435, 675, color_text);          
        }

        it.printf(240, 390, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "WARTE AUF DATEN...");

        if (!id(auto_deep_sleep_activated).state)
        {
          it.printf(240, 750, id(font_small_book), color_black, TextAlign::TOP_CENTER, "Auto Sleep Mode deaktiviert.");
        }

        char str_time[17];
        char str_date[17];
        time_t currTime = id(homeassistant_time).now().timestamp;
        strftime(str_time, sizeof(str_time), "%H:%M", localtime(&currTime));
        strftime(str_date, sizeof(str_date), "%d.%m.%Y", localtime(&currTime));

        it.printf(240, 770, id(font_small_book), color_black, TextAlign::TOP_CENTER, "Status von %s Uhr am %s", str_time, str_date);

        if(id(wifi_signal_percent).has_state()) 
        {
          if (id(wifi_signal_percent).state >= -50) {
              //Excellent
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰤨");
              ESP_LOGI("WiFi", "Exellent");
          } else if (id(wifi_signal_percent).state  >= 90) {
              //Good
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰤥");
              ESP_LOGI("WiFi", "Good");
          } else if (id(wifi_signal_percent).state  >= 50) {
              //Fair
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰤢");
              ESP_LOGI("WiFi", "Fair");
          } else if (id(wifi_signal_percent).state  >= 30) {
              //Weak
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰤟");
              ESP_LOGI("WiFi", "Weak");
          } else {
              //Unlikely working signal
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰤯");
              ESP_LOGI("WiFi", "Unlikely");
          }
        } else
        {
          //no signal (yet)
          it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰤮");
          ESP_LOGI("WiFi", "No signal");          
        }

        if(id(battery_percentage).has_state()) 
        {
          if (id(battery_percentage).state >= 95) 
          {
              // 100 %
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰁹");
          } else if (id(battery_percentage).state  >= 90) {
              // 90 %
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰂂");
          } else if (id(battery_percentage).state  >= 80) {
              // 80%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰂁");
          } else if (id(battery_percentage).state  >= 70) {
              // 70%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰂀");
          } else if (id(battery_percentage).state  >= 60) {
              // 60%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰁿");
          } else if (id(battery_percentage).state  >= 50) {
              // 50%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰁾");
          } else if (id(battery_percentage).state  >= 40) {
              // 40%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰁽");
          } else if (id(battery_percentage).state  >= 30) {
              // 30%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰁼");
          } else if (id(battery_percentage).state  >= 20) {
              // 20%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰁻");
          } else {
              // 10%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_black, TextAlign::TOP_CENTER, "󰁺");
          }
        }

      } else {

        it.fill(color_black);
        
        if (id(show_frame_alignment_aid_switch).state)
        {
          it.rectangle(25, 60, 435, 675, color_text);        
        }

        // Weather Section
        // it.image(0, 88, id(title_weather)); 
        //it.printf(240, 84, id(font_title), color_text, TextAlign::TOP_CENTER, "WETTER");
        it.printf(100, 34, id(font_mdi_large), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
        it.printf(300, 34, id(font_large_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);
        
        it.filled_rectangle(70, 140, 350, 3,color_text);
        
        it.printf(85, 158, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
        it.printf(85, 182, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
        it.printf(85, 230, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);

        it.printf(165, 158, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
        it.printf(165, 182, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
        it.printf(165, 230, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);

        it.printf(245, 158, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
        it.printf(245, 182, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
        it.printf(245, 230, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);

        it.printf(325, 158, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
        it.printf(325, 182, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
        it.printf(325, 230, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);

        it.printf(405, 158, id(font_small_book), color_white, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_4).state.c_str());
        it.printf(405, 182, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_4).state.c_str()].c_str());
        it.printf(405, 230, id(font_small_bold), color_white, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_4).state);


        it.filled_rectangle(70, 265, 350, 3,color_text);


        it.printf(240, 285, id(font_medium_bold), color_text, TextAlign::TOP_CENTER, "%s", id(wochentag_datum).state.c_str());



        std::string heute = id(termine_heute).state; 
        // Display position and line height
        int xPos1 = 35, yPos1 = 360, lineHeight1 = 30;
        //it.printf(150, 524, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%s", id(termine_heute).state.c_str());
        it.printf(xPos1, 335, id(font_small_book), color_text, TextAlign::TOP_LEFT, "HEUTE");
        std::string delimiter1 = "%";
        std::size_t curPos1 = 0, commaPos1 = 0;
        while (commaPos1 != std::string::npos) {
          commaPos1 = heute.find(delimiter1, curPos1);
          it.printf(xPos1, yPos1, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "%s", heute.substr(curPos1, commaPos1 - curPos1).c_str()); //print it!
          yPos1 += lineHeight1;
          curPos1 = commaPos1 + delimiter1.size();
        }
                    
        yPos1=yPos1-15;
        it.printf(xPos1, yPos1, id(font_small_book), color_text, TextAlign::TOP_LEFT, "%s", id(morgen).state.c_str());
        yPos1=yPos1+25;

        std::string morgen = id(termine_morgen).state; 
        //std::string delimiter1 = "%";
        std::size_t curPos2 = 0, commaPos2 = 0;
        while (commaPos2 != std::string::npos) {
          commaPos2 = morgen.find(delimiter1, curPos2);
          it.printf(xPos1, yPos1, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "%s", morgen.substr(curPos2, commaPos2 - curPos2).c_str()); //print it!
          yPos1 += lineHeight1;
          curPos2 = commaPos2 + delimiter1.size();
        }


        yPos1=yPos1-15;
        it.printf(xPos1, yPos1, id(font_small_book), color_text, TextAlign::TOP_LEFT, "%s", id(uebermorgen).state.c_str());
        yPos1=yPos1+25;

        std::string uebermorgen = id(termine_uebermorgen).state; 
        //std::string delimiter1 = "%";
        std::size_t curPos3 = 0, commaPos3 = 0;
        while (commaPos3 != std::string::npos) {
          commaPos3 = uebermorgen.find(delimiter1, curPos3);
          it.printf(xPos1, yPos1, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "%s", uebermorgen.substr(curPos3, commaPos3 - curPos3).c_str()); //print it!
          yPos1 += lineHeight1;
          curPos3 = commaPos3 + delimiter1.size();
        }

        yPos1=yPos1-15;
        if (yPos1 <= 710) {
          it.printf(xPos1, yPos1, id(font_small_book), color_text, TextAlign::TOP_LEFT, "%s", id(ueberuebermorgen).state.c_str());
          yPos1=yPos1+25;

          std::string ueberuebermorgen = id(termine_ueberuebermorgen).state; 
          //std::string delimiter1 = "%";
          std::size_t curPos4 = 0, commaPos4 = 0;
          while (commaPos4 != std::string::npos) {
            commaPos4 = ueberuebermorgen.find(delimiter1, curPos4);
            //if (yPos1 < 715) {
              it.printf(xPos1, yPos1, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "%s", ueberuebermorgen.substr(curPos4, commaPos4 - curPos4).c_str()); //print it!
              yPos1 += lineHeight1;
              curPos4 = commaPos4 + delimiter1.size();
            //}
            //else {
            //  yPos1 += lineHeight1;
            //}
          }
        }

        yPos1=yPos1-15;
        if (yPos1 <= 710) {
            it.printf(xPos1, yPos1, id(font_small_book), color_white, TextAlign::TOP_LEFT, "%s", id(ueberueberuebermorgen).state.c_str());
            yPos1 += 25;

            std::string ueberueberuebermorgen = id(termine_ueberueberuebermorgen).state; 
            std::size_t curPos4 = 0, commaPos4 = 0;
            while (commaPos4 != std::string::npos && yPos1 <= 710) {  // Changed || to &&
                commaPos4 = ueberueberuebermorgen.find(delimiter1, curPos4);
                it.printf(xPos1, yPos1, id(font_small_bold), color_text, TextAlign::TOP_LEFT, 
                          "%s", ueberueberuebermorgen.substr(curPos4, commaPos4 - curPos4).c_str());
                yPos1 += lineHeight1;
                curPos4 = commaPos4 + delimiter1.size();
            }
        }
            
        }

        
        if (!id(auto_deep_sleep_activated).state)
        {
          it.printf(240, 750, id(font_small_book), color_white, TextAlign::TOP_CENTER, "Auto Sleep Mode deaktiviert.");
        }

        // Refresh Timestamp
        // Code by EnsconcE from https://community.home-assistant.io/t/esphome-show-time/348903
        char str_time[17];
        char str_date[17];
        time_t currTime = id(homeassistant_time).now().timestamp;
        strftime(str_time, sizeof(str_time), "%H:%M", localtime(&currTime));
        strftime(str_date, sizeof(str_date), "%d.%m.%Y", localtime(&currTime));
        it.printf(240, 770, id(font_small_book), color_white, TextAlign::TOP_CENTER, "Status von %s Uhr am %s", str_time, str_date);

        if(id(wifi_signal_percent).has_state()) 
        {
          if (id(wifi_signal_percent).state >= -50) {
              //Excellent
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰤨");
              ESP_LOGI("WiFi", "Exellent");
          } else if (id(wifi_signal_percent).state  >= 90) {
              //Good
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰤥");
              ESP_LOGI("WiFi", "Good");
          } else if (id(wifi_signal_percent).state  >= 50) {
              //Fair
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰤢");
              ESP_LOGI("WiFi", "Fair");
          } else if (id(wifi_signal_percent).state  >= 30) {
              //Weak
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰤟");
              ESP_LOGI("WiFi", "Weak");
          } else {
              //Unlikely working signal
              it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰤯");
              ESP_LOGI("WiFi", "Unlikely");
          }
        } else
        {
          //no signal (yet)
          it.print(wifi_icon_x, wifi_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰤮");
          ESP_LOGI("WiFi", "No signal");          
        }

        if(id(battery_percentage).has_state()) 
        {
          if (id(battery_percentage).state >= 95) 
          {
              // 100 %
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰁹");
          } else if (id(battery_percentage).state  >= 90) {
              // 90 %
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰂂");
          } else if (id(battery_percentage).state  >= 80) {
              // 80%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰂁");
          } else if (id(battery_percentage).state  >= 70) {
              // 70%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰂀");
          } else if (id(battery_percentage).state  >= 60) {
              // 60%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰁿");
          } else if (id(battery_percentage).state  >= 50) {
              // 50%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰁾");
          } else if (id(battery_percentage).state  >= 40) {
              // 40%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰁽");
          } else if (id(battery_percentage).state  >= 30) {
              // 30%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰁼");
          } else if (id(battery_percentage).state  >= 20) {
              // 20%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰁻");
          } else {
              // 10%
              it.print(battery_icon_x, battery_icon_y, id(font_wifi_bat), color_white, TextAlign::TOP_CENTER, "󰁺");
          }
        }
      }
The above code is an esphome yaml for an epaper display. it gets is variables from a home assistant instance and outputs the formatted content to an epaper display using the lambda function. can you check the code for consistency, refactor and comment if you find it neccecary? 
the home assistant entity names must not be changed.