Spotify Playlist Player

Hi folks,

This is a player that can play selected playlist on a specified source using the spotify component.

This is inspired by the @Bob_NL 's Chromecast Radio station and player selection. And is in large just a modified version of the code found here.
https://community.home-assistant.io/t/chromecast-radio-with-station-and-player-selection/12732

NOTE: Currently the spotify component can have some issues with source list remembering, so the source selection can be funky at times. Resulting in the playlist being played on the last used source - not the source you selected. It is unknown if this issue will be fixed in the future. However, you might have better luck than I had. In the near future Iā€™ll try to set up a dedicated spotify player like Mobidy and see if that works better, ill share my experience and code here.

So, letā€™s get to the code.

configuration.yaml

input_slider:
  spotify_volume:
    name: Lydstyrke
    icon: mdi:volume-high
    min: 0
    max: 1
    step: 0.05
input_select:
  spotify_playlist:
    name: 'Playlist:'
    options:
      - Morning Commute
      - Cinematic Chill-Out
      - FUTURESYNTH
      - From a Smokey Bar
      - Piano in the Background
    icon: mdi:spotify
  spotify_source:
    name: 'Source:'
    options:
      - Stue
      - KĆøkken
      - Lejligheden
      - iPad
    initial: Lejligheden
    icon: mdi:speaker-wireless

customizes.yaml

script.spotify_music:
  friendly_name: 'Afspil'
  icon: mdi:play

groups.yaml

music_spotify:
  name: Music 
  entities:
  - input_select.spotify_playlist
  - input_select.spotify_source
  - script.spotify_music
  - input_slider.spotify_volume

scripts.yaml

spotify_music:
alias: Play selected spotify playlist
sequence:
  - service: media_player.volume_set
    data:
      entity_id: media_player.spotify
      volume_level: '0.40'
  -  service: media_player.select_source
     data_template: 
       entity_id: media_player.spotify
       source: >
        {% if is_state("input_select.spotify_source", "Stue") %} Stue
        {% elif is_state("input_select.spotify_source", "KĆøkken") %} KĆøkken
        {% elif is_state("input_select.spotify_source", "Lejligheden") %} Lejligheden
        {% elif is_state("input_select.spotify_source", "iPad") %} iPad
        {% endif %}
  -  service: media_player.play_media
     data_template:
       entity_id: media_player.spotify
       media_content_type: playlist
       media_content_id: >
        {% if is_state("input_select.spotify_playlist", "Morning Commute") %} spotify:user:spotify:playlist:37i9dQZF1DX2MyUCsl25eb
        {% elif is_state("input_select.spotify_playlist", "Cinematic Chill-Out") %} spotify:user:spotify:playlist:37i9dQZF1DWVFJtzvDHN4L
        {% elif is_state("input_select.spotify_playlist", "FUTURESYNTH") %} spotify:user:12131571557:playlist:2JgjNysZhksrtRjuGbbWns
        {% elif is_state("input_select.spotify_playlist", "From a Smokey Bar") %} spotify:user:spotify:playlist:37i9dQZF1DWTlzJXLRpd4a 
        {% elif is_state("input_select.spotify_playlist", "Piano in the Background") %} spotify:user:spotify:playlist:37i9dQZF1DX7K31D69s4M1
        {% endif %}

automations.yaml

  - alias: 'Set Spotify Volume'
  trigger:
    platform: state
    entity_id: input_slider.spotify_volume
  action:
    service: media_player.volume_set
    data_template:
      entity_id: media_player.spotify
      volume_level: '{{  states.input_slider.spotify_volume.state  }}'

EDIT: Added missing customizes.yaml item

33 Likes

great addition, I was planning a similar approach, u saved me some time

edited the default volume though:

spotify_music:
alias: Play selected spotify playlist
sequence:
- service: media_player.volume_set
data:
entity_id: media_player.spotify
volume_level: ā€˜0.4ā€™
volume_level: ā€˜{{ states.input_slider.spotify_volume.state }}ā€™

also added:

spotify_music:
alias: Play selected spotify playlist
sequence:
ā€¦
- service: media_player.shuffle_set
data:
entity_id: media_player.spotify
shuffle: ā€˜trueā€™

4 Likes

Very, Very nice! I like this. I have copy it and it is working very good! Thanks!

I was wondering, is it posible to make it like a row switches? With activate behind it. Like this:

Playlist 1 Activate
Playlist 2 Activate
Playlist 3 Activate

A activate for every playlist. On this way i can use pictures from the cover in before the playlist nameā€¦
For my childeren. Then they can activate a playlist by see the picture and activate.

I like the shuffle function, did not think or knew that that was possible to do.

Iā€™m not sure if I understand you correctly, but you could have a input_bolion for every album and then a automation for every input_bolion - I donā€™t know to do it with multiple input_bolions and only one automation if that is what you mean? :slight_smile:

I like the childrenā€™s aspect of it, making them interact with the technology.

Thanks @GigabitGuy , i have make it how i want! Thanks for the input and example.
I make a tab on HA and build it out with all playlist and number we often lisen.

Also a part for the kids, then they can choose the music by there own. :grinning:

3 Likes

Looks great man, happy to help, how did you make it work under the hood? :slight_smile:

@GigabitGuy
Configuration.yaml
input_slider:
spotify_volume:
name: Volume
icon: mdi:volume-high
min: 0
max: 1
step: 0.05

input_boolean:
spotify_opwekking_kids_24:
name: Opwekking Kids 24
initial: off
spotify_opwekking_41:
name: Opwekking 41
initial: off
spotify_hillsong_netherlands:
name: Hillsong Netherlands
initial: off
spotify_ronald_koops_waardig_is_het_lam:
name: Ronald Koops - Waardig is het Lam
initial: off
spotify_opwekking_789_lopen_op_het_water:
name: Opwekking - Lopen op het water
initial: off

input_select:
spotify_source:
name: ā€˜Source:ā€™
options:
- ā€œRemcoā€™s Echo Dotā€
- ā€œNB-Remco-W10ā€
icon: mdi:speaker-wireless

Group
music_spotify:
name: Music Spotify
control: hidden
entities:

  • input_boolean.spotify_opwekking_kids_24
  • input_boolean.spotify_opwekking_41
  • input_boolean.spotify_hillsong_netherlands
  • input_boolean.spotify_ronald_koops_waardig_is_het_lam
  • input_boolean.spotify_opwekking_789_lopen_op_het_water
  • script.spotify_music

Script.yaml
spotify_music:
#alias: Play selected spotify playlist
sequence:

  • service: media_player.volume_set
    data:
    entity_id: media_player.spotify
    volume_level: ā€˜0.30ā€™
  • service: media_player.select_source
    data_template:
    entity_id: media_player.spotify
    source: >
    {% if is_state(ā€œinput_select.spotify_sourceā€, ā€œRemcoā€™s Echo Dotā€) %} Remcoā€™s Echo Dot
    {% endif %}
  • service: media_player.play_media
    data_template:
    entity_id: media_player.spotify
    media_content_type: playlist
    media_content_id: >
    {% if is_state(ā€œinput_boolean.spotify_opwekking_kids_24ā€, ā€œonā€) %} spotify:user:rmdejonge:playlist:7u964yP37Gan7GrrUbkFwa
    {% elif is_state(ā€œinput_boolean.spotify_opwekking_41ā€, ā€œonā€) %} spotify:user:rmdejonge:playlist:7wtwjL9IYsLnIiwPBs1J3s
    {% elif is_state(ā€œinput_boolean.spotify_hillsong_netherlandsā€, ā€œonā€) %} spotify:artist:3XADXns0e7hbwRg97SijaX
    {% elif is_state(ā€œinput_boolean.spotify_ronald_koops_waardig_is_het_lamā€, ā€œonā€) %} spotify:user:rmdejonge:playlist:5NsEIvYdTMcZ92MX1ytutn
    {% endif %}

Thanks for the shuffle code for Spotify! Got mine going today - perfect for my setup - I didnā€™t know you could do that either! VERY COOL!

Thanks for your code!

Had some issues in the script but itā€™s solved! Great :smiley:

Iā€™m getting either a 403 Client error or a 500 Server error message when trying this code. Any suggestions on where I should look? Iā€™m guessing it has something to do with either API keys or Redirect URI (which I have set to http://192.168.1.26:80/api/spotify, although I get a 404 Not found when trying to access this address).

I havenā€™t opened up for external access to HASS and Iā€™d rather not if I can avoid it.

okt 26 19:49:07 homeassistant hass[9192]: Traceback (most recent call last):
okt 26 19:49:07 homeassistant hass[9192]:   File "/root/.homeassistant/deps/lib/python3.5/site-packages/spotipy/client.py", line 121, in _internal_call
okt 26 19:49:07 homeassistant hass[9192]:     r.raise_for_status()
okt 26 19:49:07 homeassistant hass[9192]:   File "/usr/lib/python3/dist-packages/requests/models.py", line 840, in raise_for_status
okt 26 19:49:07 homeassistant hass[9192]:     raise HTTPError(http_error_msg, response=self)
okt 26 19:49:07 homeassistant hass[9192]: requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: https://api.spotify.com/v1/me/player/play
okt 26 19:49:07 homeassistant hass[9192]: During handling of the above exception, another exception occurred:
okt 26 19:49:07 homeassistant hass[9192]: Traceback (most recent call last):
okt 26 19:49:07 homeassistant hass[9192]:   File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
okt 26 19:49:07 homeassistant hass[9192]:     result = coro.throw(exc)
okt 26 19:49:07 homeassistant hass[9192]:   File "/usr/local/lib/python3.5/dist-packages/homeassistant/core.py", line 1026, in _event_to_service_call
okt 26 19:49:07 homeassistant hass[9192]:     yield from service_handler.func(service_call)
okt 26 19:49:07 homeassistant hass[9192]:   File "/usr/local/lib/python3.5/dist-packages/homeassistant/components/media_player/__init__.py", line 408, in async_service_handler
okt 26 19:49:07 homeassistant hass[9192]:     yield from getattr(player, method['method'])(**params)
okt 26 19:49:07 homeassistant hass[9192]:   File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
okt 26 19:49:07 homeassistant hass[9192]:     yield self  # This tells Task to wait for completion.
okt 26 19:49:07 homeassistant hass[9192]:   File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
okt 26 19:49:07 homeassistant hass[9192]:     future.result()
okt 26 19:49:07 homeassistant hass[9192]:   File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
okt 26 19:49:07 homeassistant hass[9192]:     raise self._exception
okt 26 19:49:07 homeassistant hass[9192]:   File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
okt 26 19:49:07 homeassistant hass[9192]:     result = self.fn(*self.args, **self.kwargs)
okt 26 19:49:07 homeassistant hass[9192]:   File "/usr/local/lib/python3.5/dist-packages/homeassistant/components/media_player/spotify.py", line 257, in play_media
okt 26 19:49:07 homeassistant hass[9192]:     self._player.start_playback(**kwargs)
okt 26 19:49:07 homeassistant hass[9192]:   File "/root/.homeassistant/deps/lib/python3.5/site-packages/spotipy/client.py", line 913, in start_playback
okt 26 19:49:07 homeassistant hass[9192]:     return self._put(self._append_device_id("me/player/play", device_id), payload=data)
okt 26 19:49:07 homeassistant hass[9192]:   File "/root/.homeassistant/deps/lib/python3.5/site-packages/spotipy/client.py", line 190, in _put
okt 26 19:49:07 homeassistant hass[9192]:     return self._internal_call('PUT', url, payload, kwargs)
okt 26 19:49:07 homeassistant hass[9192]:   File "/root/.homeassistant/deps/lib/python3.5/site-packages/spotipy/client.py", line 126, in _internal_call
okt 26 19:49:07 homeassistant hass[9192]:     headers=r.headers)
okt 26 19:49:07 homeassistant hass[9192]: spotipy.client.SpotifyException: http status: 500, code:-1 - https://api.spotify.com/v1/me/player/play:
okt 26 19:49:07 homeassistant hass[9192]:  Server error.
okt 24 18:56:51 homeassistant hass[511]: Traceback (most recent call last):
okt 24 18:56:51 homeassistant hass[511]:   File "/root/.homeassistant/deps/lib/python3.5/site-packages/spotipy/client.py", line 121, in _internal_call
okt 24 18:56:51 homeassistant hass[511]:     r.raise_for_status()
okt 24 18:56:51 homeassistant hass[511]:   File "/usr/lib/python3/dist-packages/requests/models.py", line 840, in raise_for_status
okt 24 18:56:51 homeassistant hass[511]:     raise HTTPError(http_error_msg, response=self)
okt 24 18:56:51 homeassistant hass[511]: requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://api.spotify.com/v1/me/player/play
okt 24 18:56:51 homeassistant hass[511]: During handling of the above exception, another exception occurred:
okt 24 18:56:51 homeassistant hass[511]: Traceback (most recent call last):
okt 24 18:56:51 homeassistant hass[511]:   File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
okt 24 18:56:51 homeassistant hass[511]:     result = coro.throw(exc)
okt 24 18:56:51 homeassistant hass[511]:   File "/usr/local/lib/python3.5/dist-packages/homeassistant/core.py", line 1026, in _event_to_service_call
okt 24 18:56:51 homeassistant hass[511]:     yield from service_handler.func(service_call)
okt 24 18:56:51 homeassistant hass[511]:   File "/usr/local/lib/python3.5/dist-packages/homeassistant/components/media_player/__init__.py", line 408, in async_service_
okt 24 18:56:51 homeassistant hass[511]:     yield from getattr(player, method['method'])(**params)
okt 24 18:56:51 homeassistant hass[511]:   File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
okt 24 18:56:51 homeassistant hass[511]:     yield self  # This tells Task to wait for completion.
okt 24 18:56:51 homeassistant hass[511]:   File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
okt 24 18:56:51 homeassistant hass[511]:     future.result()
okt 24 18:56:51 homeassistant hass[511]:   File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
okt 24 18:56:51 homeassistant hass[511]:     raise self._exception
okt 24 18:56:51 homeassistant hass[511]:   File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
okt 24 18:56:51 homeassistant hass[511]:     result = self.fn(*self.args, **self.kwargs)
okt 24 18:56:52 homeassistant hass[511]:   File "/usr/local/lib/python3.5/dist-packages/homeassistant/components/media_player/spotify.py", line 257, in play_media
okt 24 18:56:52 homeassistant hass[511]:     self._player.start_playback(**kwargs)
okt 24 18:56:52 homeassistant hass[511]:   File "/root/.homeassistant/deps/lib/python3.5/site-packages/spotipy/client.py", line 913, in start_playback
okt 24 18:56:52 homeassistant hass[511]:     return self._put(self._append_device_id("me/player/play", device_id), payload=data)
okt 24 18:56:52 homeassistant hass[511]:   File "/root/.homeassistant/deps/lib/python3.5/site-packages/spotipy/client.py", line 190, in _put
okt 24 18:56:52 homeassistant hass[511]:     return self._internal_call('PUT', url, payload, kwargs)
okt 24 18:56:52 homeassistant hass[511]:   File "/root/.homeassistant/deps/lib/python3.5/site-packages/spotipy/client.py", line 126, in _internal_call
okt 24 18:56:52 homeassistant hass[511]:     headers=r.headers)
okt 24 18:56:52 homeassistant hass[511]: spotipy.client.SpotifyException: http status: 403, code:-1 - https://api.spotify.com/v1/me/player/play:
okt 24 18:56:52 homeassistant hass[511]:  Forbidden.

same problemā€¦

mine is not showing up ā€¦

@anon35356645 how did you manage to get the link including username?

sorry I canceled my message, now I am not sure what you are referring to

You asked how to extract the playlist link including the username and playlist ID. Since you canceled your post I figured you found out in the meantime and iā€™m also interested how to do that :slight_smile:

I found out: the username is ā€¦ well your username (or others, or spotify for playlist made by spotify).

For the playlist id, is very simple, run it on your browser is the last string of characters.

FOr example

user spotify
playlist 37i9dQZF1DX4WYpdgoIcn6

you know why the SHUFFLE is not showing in HASS?

@rensvdn
Is this wrong?

  -  service: media_player.shuffle_set
     data:
       entity_id: media_player.spotify
       shuffle: 'true'

Thanks for explaining. I donā€™t have the playlists running yet nor have any experience with shuffle. Will look into it once I have it up and running.

you can keep 2 volume_level?