@m4tthall73
Yes, that makes perfect sense. I could probably enhance the card to display the current track favorite status. The information is already there, it’s just hidden in the information popup. I will look into it.
Wonderful, thanks
@thlucas I’m speachless!
I’m trying to improve the control of my soundsystem and multiroom from ages, and your work seems amazing. Maybe I’ll say goodbye to Spotcast.
I want also to try to add a media browser popup to my dashboard, I could bother you if (when) I’ll need help.
Thank you!
@thlucas The SpotifyPlus Card is awsomme. Just what I have been looking for. Thanks!!
After sorting som issues with credentials for the Spotify Connect device in the Sportify Plus integration, I have started playing with the new card.
One thing that is not working on my end is to start playing when tapping og clicking the items in Playlists, Fovorites, etc. Long press endables the right More info. It just don’t shift over to the playlist/track/album, etc. I’m clicking.
Any suggestions.
@witno i would make sure that the latest SpotifyPlus integration version is installed, and the latest SpotifyPlus Card version is installed.
The Card is still in beta test mode, so it could be a bug. If you can open an issue on the wiki for this that would be great, so I can track it. Try to list the exact steps that you took before the issue occurs - screen captures are helpful, as well as the track / playlist your are trying to play.
Sorry. It’s prabably not the card. Been playing with it on a laptop with touch-screen. I can’t get the tracks/playlist’s etc. to start when tapping the touchpad, however when tapping the screen it started. Tried it on a desktop. No issue on the with using the mouse on that device.
@witno
I know there is extra logic in the code for touch support, versus mouse support. This sounds like BOTH were detected, and it’s recognizing the touch screen (e.g. touch support) controls over the touchpad (e.g. mouse support).
Not sure there is a fix for that scenario, as some users prefer one over the other. I will look into it though - maybe it’s something I can add a configuration option for to prioritize which option it chooses when both are available?
For my needs it’s no problem. I’m mainly setting it up as part of a wall mounted tablet dashboard. And I don’t think it has anything to do with a bug in the card.
However i got me curious, so I tried to plug an external mouse into the MS Surface laptop. It turns out, that worked. But the touchpad dosn’t (not tapping it nor clicking). Suppose it’s different commands being sendt og hw malfunctin on the laptop.
Anyways. Card is SUPER!
FYI - just released a new version of the SpotifyPlus integration
[ 1.0.65 ] - 2024/11/15
- Updated underlying
spotifywebapiPython
package requirement to version 1.0.119.
I also released the SpotifyPlus Card Dashboard, which is a front-end UI to the SpotifyPlus integration media player. Check it out if you get some time.
Hey there Todd,
thanks for this awesome integration! Did you by chance ever try one of denons heos speakers? I guess they are similar to your bose soundtouchs. They are spotify connect only devices and seem to have a dynamic spotify device id. I just cant get them to respond reliably.
Everytime I leave home and use spotify within my car for example, home assistant completely loses the devices and the spotify integration only registers new spotify device ids, which are not translated to human readable names I gave them (e.g. kitchen, bathroom, etc).
As soon as I start to play some spotify songs on one of the speakers, the home assistant integration shows the correct names again.
I hoped, that SpotifyPlus would solve this and I think it really can.
I build a simple script that does the following:
action: spotifyplus.player_media_play_tracks
metadata: {}
data:
uris: spotify:playlist:4FhyjgN9pPxxxx
entity_id: media_player.spotifyplus_xxx
device_id: Badezimmer
However 9 out of 10 times I’m getting the following error. The 10th time it works flawlessly and the speaker starts playing:
Fehler: SAM0001E - An unhandled exception occured while processing method “GetInformation”. HTTPConnectionPool(host=‘192.168.1.32’, port=51952): Max retries exceeded with url: /zc/0?action=getInfo&version=2.7.1 (Caused by NewConnectionError(‘<urllib3.connection.HTTPConnection object at 0x7f4d98f710>: Failed to establish a new connection: [Errno 111] Connection refused’))
The good thing is: It seems to know, how to address the speaker, even if home assistants spotify integration doesnt. It correctly resolves its ip address.
Do you have any advice maybe?
@z3p337
Sorry, I do not have any experience with Denons heos speakers.
The Connection refused
in the error message leads me to believe that it found the speaker at the IP address, but the Spotify Connect web service running on the speaker refused to reply to the request. This could mean a few different things: the speaker is busy servicing another request (cannot handle multiple requests); the speaker is in a deep sleep state; etc.
You might try calling the player_transfer_playback
service to force activate the device, just in case it’s in sleep mode / dropped the connection due to inactivity (see example below).
Prior to calling the player_transfer_playback
, you will want to make sure you have the following SpotifyPlus integration options set: LoginId, UserName, and Password. These options are required in order to re-activate a Spotify Connect device.
action: spotifyplus.player_transfer_playback
data:
entity_id: media_player.spotifyplus_xxx
device_id: Badezimmer
play: true
delay: 0.5
refresh_device_list: true
force_activate_device: true
Hi,
You meant the “SpotifyPlus: Get track recommendations” service?
Can you pls explain a little bit more how you use it? It sounds very interesting. Thank you!
Thanks so much for the quick support! Tried it out. It behaves the same. Sometimes it works, sometimes it doesnt and throws the “connection refused” error.
Seems like 50:50 success rate actually.
I tried to open the speakers ip-address with the port stated in the error (eg http://badezimmer:51952) and get the same error. Chrome states “ERR_CONNECTION_REFUSED”.
The port that spotifyplus uses seems to be dynamic. Maybe denon heos only allows some of the used ports or something…
I’ll figure it out somehow! Thanks so much <3
@z3p337
Check out the Spotify Connect Troubleshooting page for detailed instructions on how to find the port that the Denton HEOS speaker is using. This is basically the process that the SpotifyPlus player_transfer_playback uses to reconnect a device.
It could be that the speaker just needs time in its wake up / reconnect process. You might try increasing the “delay” argument from 0.5 to 7.0. This will cause the service to wait for 7 seconds instead of 500 milliseconds.
If that doesn’t work, then you will need to run some network traces (if you’re familiar with how to do that) to see how the Spotify desktop app is waking up the device. It involves tracing the Zeroconf / mDNS calls and responses.
yes, that’s the service i actually meant. I created a script for the creation of playlists with a few input fields/sliders for the different parameters of that service call, like for example the ‘seed_tracks’ or ‘max_speechiness’.
This script then gets called via an automation once a day with different settings for those parameters and automatically creates 4 playlists for different moods, for example a slow instrumenal only playlist based on a certain song.
Wow. Sounds nice! I hope you are happy to share the script.
sure! i realized afterwards that it would be a better approach to just delete/add tracks to the same playlists instead of recreating the whole playlist every time. Most of the script is also quite specific for my use case, but the parts with 'get track recommendations" and “add songs to playlist” should give you a good starter to create your own little playlist creator.
To make this more usable i also integrated a template which extracts the IDs from the given Spotify Playlists link(s), so it is possible to just paste the full song link into the field.
i used ai to remove some personal data in the script, just let me know if this broke something:
alias: Spotify | Create Playlist
sequence:
- alias: Create Playlist
sequence:
- variables:
mix_number: |-
{%- if mix_title == 'Chill Mix 🌿' -%}
1
{%- elif mix_title == 'Happy Mix 🔆' -%}
2
{%- elif mix_title == 'Work Mix ☕' -%}
3
{%- elif mix_title == 'Psy Mix 🕉️' -%}
4
{%- endif -%}
alias: Set mix_number
- variables:
ids_extracted: |-
{%- set ids = '' -%} {%- for track in mix_tracks -%}
{%- if track is string -%}
{%- set url_parts = track.split('?')[0] -%}
{%- if 'playlist/' in url_parts -%}
{%- set id = url_parts.split('playlist/')[1] -%}
{%- elif 'track/' in url_parts -%}
{%- set id = url_parts.split('track/')[1] -%}
{%- endif -%}
{%- if id is defined -%}
{%- if not loop.first -%},{%- endif -%}
{{- id -}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
alias: Extract Spotify IDs
enabled: true
- action: input_text.set_value
metadata: {}
data:
value: "{{ ids_extracted }}"
target:
entity_id: input_text.mix_{{ mix_number }}_playlist_tracks
alias: Save Selected Tracks
- action: spotifyplus.unfollow_playlist
metadata: {}
data:
entity_id: media_player.your_spotifyplus_player
playlist_id: >-
{{ states('input_text.mix_' ~ mix_number ~ '_playlist_url') |
regex_replace(find='spotify:playlist:', replace='',
ignorecase=False) }}
alias: SpotifyPlus | Delete Playlist
enabled: true
- alias: SpotifyPlus | Get Songs
action: spotifyplus.get_track_recommendations
data:
entity_id: media_player.your_spotifyplus_player
limit: 50
seed_tracks: |-
{% if ids_extracted != '' %}
{{ ids_extracted }}
{% else %}
{{ states('input_text.mix_' ~ mix_number ~ '_playlist_tracks') }}
{% endif %}
max_speechiness: "{{ max_speechiness | default (false) }}"
min_popularity: "{{ min_popularity | default (false) }}"
min_liveness: "{{ min_liveness | default (false) }}"
min_instrumentalness: "{{ min_instrumentalness | default (false) }}"
min_energy: "{{ min_energy | default (false) }}"
min_acousticness: "{{ min_acousticness | default (false) }}"
enabled: true
response_variable: track_recommendations
- alias: SpotifyPlus | Create Playlist
data:
entity_id: media_player.your_spotifyplus_player
name: "{{ mix_title }} | {{ now().strftime('%-d.%m.%y') }}"
description: >-
#{{ track_recommendations.result.tracks[0].artists[0].name }}, #{{
track_recommendations.result.tracks[1].artists[0].name }}, #{{
track_recommendations.result.tracks[2].artists[0].name }}, #{{
track_recommendations.result.tracks[3].artists[0].name }}, #{{
track_recommendations.result.tracks[4].artists[0].name }}, #MORE
🧙♂️🪄 50 Songs, specially created for you on {{ now().strftime('%-d.%m.%y') }} at {{
states('sensor.time') }}!
public: false
collaborative: false
image_path: www/images/Playlists/mix_{{ mix_number }}.jpg
action: spotifyplus.playlist_create
response_variable: playlist
- data:
entity_id: media_player.your_spotifyplus_player
playlist_id: >-
{{ playlist.result.href |
regex_replace(find='https://api.spotify.com/v1/playlists/',
replace='', ignorecase=False) }}
uris: >-
{{ track_recommendations.result.tracks[0].uri }}, {{
track_recommendations.result.tracks[1].uri }}, {{
track_recommendations.result.tracks[2].uri }}, {{
track_recommendations.result.tracks[3].uri }}, {{
track_recommendations.result.tracks[4].uri }}, {{
track_recommendations.result.tracks[5].uri }}, {{
track_recommendations.result.tracks[6].uri }}, {{
track_recommendations.result.tracks[7].uri }}, {{
track_recommendations.result.tracks[8].uri }}, {{
track_recommendations.result.tracks[9].uri }}, {{
track_recommendations.result.tracks[10].uri }}, {{
track_recommendations.result.tracks[11].uri }}, {{
track_recommendations.result.tracks[12].uri }}, {{
track_recommendations.result.tracks[13].uri }}, {{
track_recommendations.result.tracks[14].uri }}, {{
track_recommendations.result.tracks[15].uri }}, {{
track_recommendations.result.tracks[16].uri }}, {{
track_recommendations.result.tracks[17].uri }}, {{
track_recommendations.result.tracks[18].uri }}, {{
track_recommendations.result.tracks[19].uri }}, {{
track_recommendations.result.tracks[20].uri }}, {{
track_recommendations.result.tracks[21].uri }}, {{
track_recommendations.result.tracks[22].uri }}, {{
track_recommendations.result.tracks[23].uri }}, {{
track_recommendations.result.tracks[24].uri }}, {{
track_recommendations.result.tracks[25].uri }}, {{
track_recommendations.result.tracks[26].uri }}, {{
track_recommendations.result.tracks[27].uri }}, {{
track_recommendations.result.tracks[28].uri }}, {{
track_recommendations.result.tracks[29].uri }}, {{
track_recommendations.result.tracks[30].uri }}, {{
track_recommendations.result.tracks[31].uri }}, {{
track_recommendations.result.tracks[32].uri }}, {{
track_recommendations.result.tracks[33].uri }}, {{
track_recommendations.result.tracks[34].uri }}, {{
track_recommendations.result.tracks[35].uri }}, {{
track_recommendations.result.tracks[36].uri }}, {{
track_recommendations.result.tracks[37].uri }}, {{
track_recommendations.result.tracks[38].uri }}, {{
track_recommendations.result.tracks[39].uri }}, {{
track_recommendations.result.tracks[40].uri }}, {{
track_recommendations.result.tracks[41].uri }}, {{
track_recommendations.result.tracks[42].uri }}, {{
track_recommendations.result.tracks[43].uri }}, {{
track_recommendations.result.tracks[44].uri }}, {{
track_recommendations.result.tracks[45].uri }}, {{
track_recommendations.result.tracks[46].uri }}, {{
track_recommendations.result.tracks[47].uri }}, {{
track_recommendations.result.tracks[48].uri }}, {{
track_recommendations.result.tracks[49].uri }}
action: spotifyplus.playlist_items_add
enabled: true
alias: SpotifyPlus | Add Songs to Playlist
- action: input_text.set_value
metadata: {}
data:
value: >-
{{ playlist.result.href |
regex_replace(find='https://api.spotify.com/v1/playlists/',
replace='spotify:playlist:', ignorecase=False) }}
target:
entity_id: input_text.mix_{{ mix_number }}_playlist_url
enabled: true
alias: Playlist Sensor | Set Playlist URL
- action: spotifyplus.playlist_cover_image_add
metadata: {}
data:
playlist_id: >-
{{ playlist.result.href |
regex_replace(find='https://api.spotify.com/v1/playlists/',
replace='', ignorecase=False) }}
image_path: www/images/Playlists/mix_{{ mix_number }}.jpg
entity_id: media_player.your_spotifyplus_player
alias: SpotifyPlus | Add Cover Image
description: Create dynamic playlist with SpotifyPlus.
icon: mdi:spotify
fields:
mix_title:
selector:
select:
options:
- Chill Mix 🌿
- Happy Mix 🔆
- Work Mix ☕
- Psy Mix 🕉️
name: Playlist Title
required: true
default: Chill Mix 🌿
mix_tracks:
selector:
text:
multiple: true
multiline: false
default: []
name: "Insert Song Links:"
required: true
max_speechiness:
name: Maximum Speechiness
description: Maximum value for speech-like characteristics (0.0 to 1.0)
selector:
number:
min: 0
max: 1
step: 0.1
min_popularity:
name: Minimum Popularity
description: Minimum popularity rating (0 to 100)
selector:
number:
min: 0
max: 100
step: 1
min_liveness:
name: Minimum Liveness
description: Minimum liveness value (0.0 to 1.0)
selector:
number:
min: 0
max: 1
step: 0.1
min_instrumentalness:
name: Minimum Instrumentalness
description: Minimum instrumentalness value (0.0 to 1.0)
selector:
number:
min: 0
max: 1
step: 0.1
min_energy:
name: Minimum Energy
description: Minimum energy value (0.0 to 1.0)
selector:
number:
min: 0
max: 1
step: 0.1
min_acousticness:
name: Minimum Acousticness
description: Minimum acousticness value (0.0 to 1.0)
selector:
number:
min: 0
max: 1
step: 0.1
Cool. I will give it a try! Thank you very much for sharing!
@shpongledsummer
Just wanted to mention that it’s possible for the service to return less than 50 items in the tracks collection depending on the criteria specified. I mention it due to the hard coded array item references you are doing (eg result.tracks[n], etc). Another alternative is to use a loop.
You probably won’t have any issues if your criteria is pretty generic though.
Just wanted you to be aware though.
haha yes i know, my code is not very elegant and I should have mentioned that there will be an error if the search results is less than 50 tracks. which happens quite fast if the search parameters are too specific. thanks for pointing this out!