# https://community.home-assistant.io/t/awesome-spotify-touch-control-via-ili9341-screen/406328

logger:

ota:

api:

captive_portal:

time:
    platform: homeassistant
    id: esptime

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

font:
  - file: 'fonts/verdana.ttf'
    id: font40
    size: 40
    glyphs: °.0123456789-%d
  - file: 'fonts/verdana.ttf'
    id: font_spot_time
    size: 12
    glyphs: :0123456789
  - file: 'fonts/verdana.ttf'
    id: font21
    size: 21
    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','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/', '\', '\xab', '\xc3', '\xaf', '''', 'ß' ]
  - file: 'fonts/verdana.ttf'
    id: font18
    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/verdana.ttf'
    id: font16
    size: 16
    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/materialdesignicons-webfont.ttf'
    id: font_icon_spotify
    size: 75
    glyphs:
      - "\U000F040C" # play-circle
      - "\U000F03E5" # pause-circle
      - "\U000F0661" # skip-next-circle
      - "\U000F0376" # minus-circle
      - "\U000F0417" # plus-circle
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_icon_spotify_big
    size: 80
    glyphs:
      - "\U000F04C7" # Spotify Icon
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_icon_spotify_infobar
    size: 30
    glyphs:
      - "\U000F04C7" # Spotify Icon 
      - "\U000F0595" # Wetter Icon 
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_icon_spotify_infobar_s
    size: 24
    glyphs:
      - "\U000F049D" # Shuffle on Icon 
      - "\U000F049E" # Shuffle off Icon 

color:
  - id: my_red
    red: 100%
    green: 0%
  - id: my_green
    red:   0%
    green: 100%
    blue:  30%
  - id: my_white
    red:   1.0000
    green: 1.0000
    blue:  1.0000
  - id: my_grey
    red:   0.6000
    green: 0.6000
    blue:  0.6000
  - id: my_black
    red:   0.0000
    green: 0.0000
    blue:  0.0000
output:
  # backlight
  - platform: ledc
    pin: 15
    id: gpio_15_backlight_pwm_touch
    inverted: false

light:
  - platform: monochromatic
    output: gpio_15_backlight_pwm_touch
    name: "ILI9341 Display Backlight Touch"
    id: back_light_touch
    restore_mode: RESTORE_DEFAULT_ON

text_sensor:
  - platform: homeassistant
    id: current_title
    entity_id: sensor.esp32_media_player_current_title
  - platform: homeassistant
    id: current_artist
    entity_id: sensor.esp32_media_player_current_artist
  - platform: homeassistant
    id: current_playlist
    entity_id: sensor.esp32_media_player_current_playlist
  - platform: homeassistant
    id: spotify
    entity_id: sensor.esp32_media_player_status
  - platform: homeassistant
    id: spotpostime
    entity_id: sensor.esp32_spotify_position_time
  - platform: homeassistant
    id: spotdur
    entity_id: sensor.esp32_spotify_duration
sensor:
  - platform: homeassistant
    id: spotvol
    entity_id: sensor.esp32_spotify_volume
    filters:
    - multiply: 10
  - platform: homeassistant
    id: spotpos
    entity_id: sensor.esp32_spotify_position
  - platform: homeassistant
    id: spotpos2
    entity_id: sensor.esp32_spotify_position
    filters:
    - offset: 78
binary_sensor:
  - platform: homeassistant
    entity_id: input_boolean.esp32_wetter_screen
    id: display_wetter
  - platform: homeassistant
    entity_id: input_boolean.esp32_spotify_volume
    id: display_volume
  - platform: homeassistant
    entity_id: binary_sensor.esp32_spotify_shuffle
    id: spotify_shuffle
  - platform: homeassistant
    entity_id: input_boolean.esp32_spotify_playlist_menu
    id: playlist
  - platform: xpt2046
    xpt2046_id: touchscreen                                             # Start Play/Pause
    id: touch_play
    x_min: 35
    x_max: 110
    y_min: 2
    y_max: 77
    on_press:
      if: 
        condition:
          or:
            - and: 
              - lambda: 'return id(spotify).state == "playing";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
            - and:
              - lambda: 'return id(spotify).state == "paused";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
        then:
        - homeassistant.service:
            service: script.esp32_spotify_play_pause
  - platform: xpt2046
    xpt2046_id: touchscreen                                             # Next Track
    id: touch_next
    x_min: 35
    x_max: 110
    y_min: 78
    y_max: 154
    on_press:
      if: 
        condition:
          or:
            - and: 
              - lambda: 'return id(spotify).state == "playing";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
            - and:
              - lambda: 'return id(spotify).state == "paused";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
        then:
        - homeassistant.service:
            service: media_player.media_next_track
            data:
              entity_id: media_player.spotify_xxx
  - platform: xpt2046
    xpt2046_id: touchscreen                                             # Volume - 
    id: touch_minus
    x_min: 35
    x_max: 110
    y_min: 155
    y_max: 230
    on_press:
      if: 
        condition:
          or:
            - and: 
              - lambda: 'return id(spotify).state == "playing";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
            - and:
              - lambda: 'return id(spotify).state == "paused";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
        then:
        - homeassistant.service:
            service: script.esp32_spotify_volume_down
  - platform: xpt2046
    xpt2046_id: touchscreen                                             # Volume +
    id: touch_plus
    x_min: 35
    x_max: 110
    y_min: 232
    y_max: 295
    on_press:
      if: 
        condition:
          or:
            - and: 
              - lambda: 'return id(spotify).state == "playing";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
            - and:
              - lambda: 'return id(spotify).state == "paused";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
        then:
        - homeassistant.service:
            service: script.esp32_spotify_volume_up
  - platform: xpt2046
    xpt2046_id: touchscreen                                             # Start Spotify
    id: touch_info_spot
    x_min: 195
    x_max: 239
    y_min: 275
    y_max: 319
    on_press:
      if: 
        condition:
          or:
            - and: 
              - lambda: 'return id(spotify).state != "playing";'
              - lambda: 'return id(spotify).state != "paused";'
            - and:
              - lambda: 'return id(display_wetter).state;'
        then:
        - homeassistant.service:
            service: script.esp32_open_spotify
  - platform: xpt2046
    xpt2046_id: touchscreen                                             # Turn on Display Wetter 
    id: touch_info_wetter
    x_min: 195
    x_max: 239
    y_min: 275
    y_max: 319
    on_press:
      if: 
        condition:
          or:
            - and: 
              - lambda: 'return id(spotify).state == "playing";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
            - and:
              - lambda: 'return id(spotify).state == "paused";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
        then:
        - homeassistant.service:
            service: script.esp32_open_display_wetter
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_info_spot_shuffle_off                                      # Touch Shuffle off
    x_min: 205
    x_max: 239
    y_min: 75
    y_max: 120
    on_press:
      if: 
        condition:
          or:
            - and: 
              - lambda: 'return id(spotify).state == "playing";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
              - lambda: 'return id(spotify_shuffle).state == false;'
            - and:
              - lambda: 'return id(spotify).state == "paused";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
              - lambda: 'return id(spotify_shuffle).state == false;'
        then:
        - homeassistant.service:
            service: media_player.shuffle_set
            data:
              shuffle: 'true'
              entity_id: media_player.spotify_xxx            
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_info_spot_shuffle_on                                      # Touch Shuffle on
    x_min: 205
    x_max: 239
    y_min: 75
    y_max: 120
    on_press:
      if: 
        condition:
          or:
            - and: 
              - lambda: 'return id(spotify).state == "playing";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
              - lambda: 'return id(spotify_shuffle).state;'
            - and:
              - lambda: 'return id(spotify).state == "paused";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
              - lambda: 'return id(spotify_shuffle).state;'
        then:
        - homeassistant.service:
            service: media_player.shuffle_set
            data:
              shuffle: 'false'
              entity_id: media_player.spotify_xxx
#START SPOTIFY PLAYLIST TOUCH
  - platform: xpt2046
    xpt2046_id: touchscreen                                             # Spotify Icon Playlist
    id: touch_playlist
    x_max: 180
    y_min: 3
    x_min: 105
    y_max: 75
    on_press:
      if: 
        condition:
          or:
            - and: 
              - lambda: 'return id(spotify).state == "playing";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
            - and:
              - lambda: 'return id(spotify).state == "paused";'
              - lambda: 'return id(playlist).state;'
              - lambda: 'return id(display_wetter).state == false;'
        then:
        - homeassistant.service:
            service: input_boolean.toggle
            data: 
              entity_id: input_boolean.esp32_spotify_playlist_menu
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_B1
    x_max: 239
    y_min: 200
    x_min: 201
    y_max: 319
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_b1
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_A1
    x_max: 239
    y_min: 75
    x_min: 201
    y_max: 199
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_a1
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_B2
    x_max: 200
    y_min: 200
    x_min: 161
    y_max: 319
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_b2
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_A2
    x_max: 200
    y_min: 75
    x_min: 161
    y_max: 199
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_a2
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_B3
    x_max: 160
    y_min: 200
    x_min: 121
    y_max: 319
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_b3
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_A3
    x_max: 160
    y_min: 75
    x_min: 121
    y_max: 199
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_a3
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_B4
    x_max: 120
    y_min: 200
    x_min: 81
    y_max: 319
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_b4
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_A4
    x_max: 120
    y_min: 75
    x_min: 81
    y_max: 199
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_a4
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_B5
    x_max: 80
    y_min: 200
    x_min: 41
    y_max: 319
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_b5
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_A5
    x_max: 80
    y_min: 75
    x_min: 41
    y_max: 199
    on_press:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_a5
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_B6
    x_max: 40
    y_min: 200
    x_min: 2
    y_max: 319
    on_state:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_b6
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_A6
    x_max: 40
    y_min: 75
    x_min: 2
    y_max: 199
    on_state:
      if: 
        condition:
          binary_sensor.is_off: playlist
        then:
        - homeassistant.service:
            service: script.esp32_spotify_playlist_a6
xpt2046:
  id: touchscreen
  cs_pin: 14
  irq_pin: 27
  update_interval: 50ms
  report_interval: 1s
  threshold: 400
  dimension_x: 240
  dimension_y: 320
  calibration_x_min: 3860
  calibration_x_max: 280
  calibration_y_min: 340
  calibration_y_max: 3860
  swap_x_y: false

display:
  - platform: ili9341
    model: TFT 2.4
    id: touch_display
    cs_pin: GPIO5
    dc_pin: GPIO4
    reset_pin: GPIO22
    rotation: 270
    lambda: |-
      auto black = Color(0, 0, 0);
      it.fill(black);
      // WENN SPOTIFY SPIELT BUTTONS
      if ((id(spotify).state == "playing" or id(spotify).state == "paused") and id(display_wetter).state == false) {
          if (id(spotify).state == "playing") 
          { it.print(0, 155, id(font_icon_spotify), id(my_green), TextAlign::TOP_LEFT, "\U000F03E5"); }            // Pause Icon
          else 
          { it.print(0, 155, id(font_icon_spotify), id(my_white), TextAlign::TOP_LEFT, "\U000F040C"); }            // Play Icon
      it.print(-5, 43, id(font_icon_spotify_big), id(my_green), TextAlign::TOP_LEFT, "\U000F04C7");                // Spotify Icon gross       
      // WENN SPOTIFY SPIELT UND PLAYLIST GESCHLOSSEN
         if (id(playlist).state) {
             if (id(spotify_shuffle).state) { 
                it.print(98, 3, id(font_icon_spotify_infobar_s), id(my_green), TextAlign::TOP_RIGHT, "\U000F049D");  // Shuffle on
             } 
             else {
                it.print(98, 3, id(font_icon_spotify_infobar_s), id(my_white), TextAlign::TOP_RIGHT, "\U000F049E");  // Shuffle off
             }  
      it.strftime(4, 0, id(font21), id(my_white), TextAlign::TOP_LEFT, "%H:%M", id(esptime).now());
      it.filled_circle(319, 0, 40, id(my_white));
      it.print(319, 1, id(font_icon_spotify_infobar), id(my_black), TextAlign::TOP_RIGHT, "\U000F0595");            // Wetter Display
      it.print(78, 66, id(font21), id(my_white), TextAlign::TOP_LEFT, id(current_title).state.c_str());             // Track Infos
      it.print(78, 91, id(font21), id(my_white), TextAlign::TOP_LEFT, id(current_artist).state.c_str());
      it.print(78, 46, id(font18), id(my_green), TextAlign::TOP_LEFT, id(current_playlist).state.c_str());
      // it.printf(78, 35, id(font18), id(my_green), TextAlign::TOP_LEFT, "%.0f", id(spotpos).state);
      
      it.filled_rectangle(78, 130, 222, 2, id(my_grey));                                                             // Progress Back
      it.filled_rectangle(78, 130, id(spotpos).state, 2, id(my_green));                                              // Progress Bar
      it.filled_circle(id(spotpos2).state, 130, 4, id(my_green));                                                    // Progress Circle
      it.print(78, 133, id(font_spot_time), id(my_green), TextAlign::TOP_LEFT, id(spotpostime).state.c_str());       // Position Song 
      it.print(300, 133, id(font_spot_time), id(my_green), TextAlign::TOP_RIGHT, id(spotdur).state.c_str());         // Duration Song
      
      it.print(78, 155, id(font_icon_spotify), id(my_white), TextAlign::TOP_LEFT, "\U000F0661");                    // Next Track   
      it.print(155, 155, id(font_icon_spotify), id(my_white), TextAlign::TOP_LEFT, "\U000F0376");                   // Volume-
      it.print(232, 155, id(font_icon_spotify), id(my_white), TextAlign::TOP_LEFT, "\U000F0417");                   // Volume+
          if (id(display_volume).state) {                                                                           // Volume State
          it.filled_circle(230, 122, 35, id(my_green));
          it.printf(230, 145, id(font40), id(my_black), TextAlign::BOTTOM_CENTER, "%.0f", id(spotvol).state);
          }
       } 
      // WENN SPOTIFY SPIELT UND PLAYLIST OFFEN
      else if ((id(spotify).state == "playing" or id(spotify).state == "paused") and id(playlist).state == false) {
      it.line(76, 0, 76, 240);
      it.line(200, 0, 200, 240);
      it.line(319, 0, 319, 240);
      it.line(76, 0, 319, 0);
      it.line(76, 40, 319, 40);
      it.line(76, 80, 319, 80);
      it.line(76, 120, 319, 120);
      it.line(76, 160, 319, 160);
      it.line(76, 200, 319, 200);
      it.line(76, 239, 319, 239);
      it.print(85, 20, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Mix d.Woche");
      it.print(85, 60, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Playlist W");
      it.print(85, 100, id(font18), id(my_white), TextAlign::CENTER_LEFT, "me right no");
      it.print(85, 140, id(font18), id(my_white), TextAlign::CENTER_LEFT, "House Party");
      it.print(85, 180, id(font18), id(my_white), TextAlign::CENTER_LEFT, "News");
      it.print(85, 220, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Playlist Z");
      it.print(209, 20, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Playlist X");
      it.print(209, 60, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Playlist Y");
      it.print(209, 100, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Pool Electro");
      it.print(209, 140, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Hot Hits");
      it.print(209, 180, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Kaffeehaus");
      it.print(209, 220, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Chilled Dan");
      }} 
      else {
      // STATUSLEISTE ZEIT ODER WETTERWARNUNG
      it.strftime(4, 3, id(font21), id(my_white), TextAlign::TOP_LEFT, "%H:%M", id(esptime).now());
      it.filled_circle(319, 0, 40, id(my_white));
      it.print(319, 1, id(font_icon_spotify_infobar), id(my_black), TextAlign::TOP_RIGHT, "\U000F04C7");            // Spotify Icon Infobar 
      }