Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No longer able to activate any of my Spotify Connect devices #38

Closed
4 tasks done
milnivlek opened this issue Aug 18, 2024 · 13 comments
Closed
4 tasks done

No longer able to activate any of my Spotify Connect devices #38

milnivlek opened this issue Aug 18, 2024 · 13 comments

Comments

@milnivlek
Copy link

milnivlek commented Aug 18, 2024

System Health details

System Information

version core-2024.7.1
installation_type Home Assistant Container
dev false
hassio false
docker true
user root
virtualenv false
python_version 3.12.4
os_name Linux
os_version 6.6.31+rpt-rpi-v8
arch aarch64
timezone America/Los_Angeles
config_dir /config
Home Assistant Community Store
GitHub API ok
GitHub Content ok
GitHub Web ok
GitHub API Calls Remaining 4982
Installed Version 1.34.0
Stage running
Available Repositories 1392
Downloaded Repositories 36
HACS Data ok
AccuWeather
can_reach_server ok
remaining_requests 12
Home Assistant Cloud
logged_in false
can_reach_cert_server ok
can_reach_cloud_auth ok
can_reach_cloud ok
Dashboards
dashboards 3
resources 26
views 5
mode storage
Recorder
oldest_recorder_run August 16, 2024 at 5:16 AM
current_recorder_run August 17, 2024 at 7:11 PM
estimated_db_size 237.19 MiB
database_engine sqlite
database_version 3.45.3
SpotifyPlus
integration_version v1.0.49
clients_configured 1: K&M (premium)
api_endpoint_reachable ok

Checklist

  • I have enabled SmartInspect debug logging for my installation.
  • I have filled out the issue template to the best of my ability.
  • This issue only contains 1 issue (if you have multiple issues, open one issue for each issue).
  • This issue is not a duplicate issue of any previous issues..

Describe the issue

Since a few days ago, all my scripts stopped being able to activate my Spotify Connect devices.

Specifically, when I call this:

service: spotifyplus.player_resolve_device_id
data:
  device_value: 1st Floor Speakers
  entity_id: media_player.spotifyplus
  verify_user_context: true

I get the expected response with a device ID, e.g.

result: 26195de030cfc972b3435a8c25026022988eb5e3

However, this device ID doesn't actually work. When I attempt to start a playback with this device ID, it doesn't recognize the device ID. Instead, I get this error:

Player command failed: No active device found

Moreover, when I go to https://developer.spotify.com/documentation/web-api/reference/get-a-users-available-devices and run the Get Available Devices API request, I don't see my device in the returned list. It looks like player_resolve_device_id didn't login my account on the device at all.

I also tried calling spotifyplus.get_spotify_connect_device instead (with verify_user_context: true), but the outcome was the same. I even tried calling spotifyplus.zeroconf_device_connect directly with all the discovered device details. Still no luck.

I checked my Spotify Connect username and password in the SpotifyPlus integration options, and they are still correct. I confirmed that I can still log in via the Spotify desktop web UI with those same credentials. It's just not working through SpotifyPlus.

Not sure if this is relevant, but I did some web searches and noticed this thread on the librespot project which indicated that Spotify just stopped supporting username/password based authentication for ZeroConf: librespot-org/librespot#1308 (comment). Could SpotifyPlus be affected by the same issue?

Reproduction steps

See above write-up for steps.

Debug logs

n/a

Diagnostics dump

No response

@thlucas1
Copy link
Owner

thlucas1 commented Aug 18, 2024

@milnivlek
I do believe it is related to Spotify making some changes to their login processes, which is also affecting librespot. But before we go there, let's see what is registered in ZeroConf.

What do you see when you issue the following ZeroConf mDNS query from a DOS prompt / terminal window?
dns-sd -B _spotify-connect._tcp. local.

Should look something like this (me environment example), listing all of your Spotify Connect devices that are known to Zeroconf:

C:\Users\thluc>dns-sd -B _spotify-connect._tcp. local.
Browsing for _spotify-connect._tcp..local.
Timestamp     A/R Flags if Domain                    Service Type              Instance Name
13:54:33.369  Add     3  5 local.                    _spotify-connect._tcp.    Bose-ST300
13:54:33.369  Add     3  5 local.                    _spotify-connect._tcp.    Bose-ST10-1 + Bose-ST10-2 (L+R)
13:54:33.369  Add     3  5 local.                    _spotify-connect._tcp.    Bose-ST10-2
13:54:33.369  Add     2  5 local.                    _spotify-connect._tcp.    Bose-ST10-1
13:54:33.417  Add     2  5 local.                    _spotify-connect._tcp.    HAVM-SpotifyConnect

Also, do you have the Spotify LoginId value set (as well as userid and password) in your SpotifyPlus configuration options?

@milnivlek
Copy link
Author

Thanks thlucas1 for your quick follow-up.

Here's what I see when I ran the command you gave:

$ dns-sd -B _spotify-connect._tcp. local.
Browsing for _spotify-connect._tcp..local.
DATE: ---Sat 17 Aug 2024---
22:50:55.202  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Attic Speaker
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Master Bedroom Speaker
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Kitchen Speaker
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Living Room Soundbar
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Dining Room Speaker
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. All Speakers
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Dining & Kitchen
22:50:55.328  Add        2  15 local.               _spotify-connect._tcp. 1st Floor Speakers
22:50:55.540  Add        2  15 local.               _spotify-connect._tcp. f84a989346fb84a24fa545fde1a3102645d1ffca
22:50:55.598  Add        2  15 local.               _spotify-connect._tcp. cde82ced6ff067791e7bf8e70a58e9e40092887b
22:50:56.165  Add        2  15 local.               _spotify-connect._tcp. SpZc-A6E9C4

And yes, I do have all these fields set: canonical loginid, username, password.

Hope this helps!

@thlucas1
Copy link
Owner

thlucas1 commented Aug 19, 2024

I just realized from this discussion thread that you are utilizing SnapCast to control your devices. I believe there are still ongoing librespot issues related to Spotify Authentication that is preventing Spotify Connect from "seeing" your devices as noted in this librespot issue thread. Not sure on that though - you might reach out to the librespot folks to confirm. Note that SpotifyPlus does not use librespot or SpotCast server to do its thing.

With that said ...

Questions:
Are these ChromeCast / GoogleCast devices?
What do you get for the following service call:

action: spotifyplus.get_spotify_connect_device
data:
  entity_id: media_player.spotifyplus
  device_value: "1st Floor Speakers"
  refresh_device_list: true
  activate_device: false

Should look something like this (note these results are for one of my Bose SoundTouch devices):

user_profile:
  country: US
  display_name: Todd L
  email: thl... redacted ...
  id: 31l77... redacted ...
  product: premium
  type: user
  uri: spotify:user:31l77... redacted ...
result:
  Id: 30fbc80e35598f3c242f2120413c943dfd9715fe
  Name: Bose-ST10-1
  WasReConnected: false
  DeviceInfo:
    SpotifyError: 0
    Status: 101
    StatusString: OK
    ResponseSource: null
    AccountReq: DONTCARE
    ActiveUser: ... redacted ...
    Aliases: []
    Availability: ""
    BrandDisplayName: Bose
    ClientId: 79ebcb21... redacted ...
    DeviceId: 30fbc80e35598f3c242f2120413c943dfd9715fe
    DeviceType: SPEAKER
    GroupStatus: NONE
    LibraryVersion: 3.88.29-gc4d4bb01
    ModelDisplayName: Soundtouch
    ProductId: 70001
    PublicKey: eDzNVMgBm... redacted ...
    RemoteName: Bose-ST10-1
    ResolverVersion: "0"
    Scope: streaming
    SupportedCapabilities: null
    SupportedDrmMediaFormats: []
    TokenType: accesstoken
    Version: 2.7.1
    VoiceSupport: "YES"
    IsActiveDevice: false
    IsInDeviceList: true
  DiscoveryResult:
    DeviceName: Bose-ST10-1
    Domain: .local
    HostIpAddress: 192.168.1.81
    HostIpAddresses:
      - 192.168.1.81
    HostIpPort: 8200
    HostTTL: 120
    Key: bose-st10-1._spotify-connect._tcp.local.
    Name: Bose-ST10-1._spotify-connect._tcp.local.
    Priority: 0
    OtherTTL: 4500
    Server: Bose-SM2-341513fbeeae.local.
    ServerKey: bose-sm2-341513fbeeae.local.
    ServiceType: _spotify-connect._tcp.local.
    Weight: 0
    Properties:
      - Name: CPath
        Value: /zc
      - Name: VERSION
        Value: "1.0"
    SpotifyConnectCPath: /zc
    SpotifyConnectIsInDeviceList: false
    SpotifyConnectVersion: "1.0"
    ZeroconfApiEndpointAddUser: http://192.168.1.81:8200/zc?action=addUser&version=1.0
    ZeroconfApiEndpointGetInformation: http://192.168.1.81:8200/zc?action=getInfo&version=1.0
    ZeroconfApiEndpointResetUsers: http://192.168.1.81:8200/zc?action=resetUsers&version=1.0

@milnivlek
Copy link
Author

milnivlek commented Aug 20, 2024

Oops, I realized I made a typo in that other discussion thread. I use Snapcast, not Spotcast. In short, my Spotify Connect devices are Snapcast services that represent various groupings of my actual physical speakers. It's like Sonos groups, basically. But I do my playback via buttons on the Home Assistant UI using your SpotifyPlus integration. Or via the Spotify app (which has always worked fine with my Snapcast devices).

Sorry for the confusion. I just corrected my typo in the other thread.

As for your other question: here's the output of get_spotify_connect_device:

user_profile:
  country: US
  display_name: xxxxxxx
  email: xxxxxxx
  id: xxxxxxx
  product: premium
  type: user
  uri: spotify:user:xxxxxxx
result:
  Id: 26195de030cfc972b3435a8c25026022988eb5e3
  Name: 1st Floor Speakers
  WasReConnected: false
  DeviceInfo:
    SpotifyError: 0
    Status: 101
    StatusString: ERROR-OK
    ResponseSource: null
    AccountReq: PREMIUM
    ActiveUser: ""
    Aliases: []
    Availability: ""
    BrandDisplayName: librespot
    ClientId: null
    DeviceId: 26195de030cfc972b3435a8c25026022988eb5e3
    DeviceType: Speaker
    GroupStatus: NONE
    LibraryVersion: 0.4.2
    ModelDisplayName: librespot
    ProductId: null
    PublicKey: xxxxxxx
    RemoteName: 1st Floor Speakers
    ResolverVersion: "0"
    Scope: null
    SupportedCapabilities: null
    SupportedDrmMediaFormats: []
    TokenType: null
    Version: 2.7.1
    VoiceSupport: "NO"
    IsActiveDevice: true
    IsInDeviceList: true
  DiscoveryResult:
    DeviceName: 1st Floor Speakers
    Domain: .local
    HostIpAddress: 192.168.1.43
    HostIpAddresses:
      - 172.18.0.1
      - 172.17.0.1
      - 192.168.1.43
    HostIpPort: 34723
    HostTTL: 120
    Key: 1st floor speakers._spotify-connect._tcp.local.
    Name: 1st Floor Speakers._spotify-connect._tcp.local.
    Priority: 0
    OtherTTL: 4500
    Server: home.local.
    ServerKey: home.local.
    ServiceType: _spotify-connect._tcp.local.
    Weight: 0
    Properties:
      - Name: VERSION
        Value: "1.0"
      - Name: CPath
        Value: /
    SpotifyConnectCPath: /
    SpotifyConnectIsInDeviceList: false
    SpotifyConnectVersion: "1.0"
    ZeroconfApiEndpointAddUser: http://192.168.1.43:34723/?action=addUser&version=1.0
    ZeroconfApiEndpointGetInformation: http://192.168.1.43:34723/?action=getInfo&version=1.0
    ZeroconfApiEndpointResetUsers: http://192.168.1.43:34723/?action=resetUsers&version=1.0

@thlucas1
Copy link
Owner

thlucas1 commented Aug 20, 2024

The ModelDisplayName: librespot indicates that these Spotify Connect device entries are being defined by librespot. I was hoping the device itself was running the Spotify Connect Zeroconf interface, but it does not appear that is the case. Basically, librespot has registered the device to Spotify Connect Zeroconf, so librespot will control when / how the device connects to the Spotify backend to play content.

Are you seeing any of the following messages in your HA System Log? or in a librespot log maybe?
ERROR librespot] Connection failed: Login failed with reason: Bad credentials
These errors are mentioned in a librespot Authentication Issues thread thread.

There is also this issue on the SnapCast issues page that talks about Bad Credentials errors (due to underlying librespot functionality).

At this point you probably need to reach out to either the librespot team or SnapCast team to troubleshoot why the devices are able to connect. Once you figure that out, the SpotifyPlus and Spotify integrations should start working again.

Wish I could help more, but I don't use / know librespot functionality.

@milnivlek
Copy link
Author

milnivlek commented Aug 20, 2024

I really appreciate you trying your best to help, thlucas1. Thanks for all your hard work in supporting me and others.

One thing to clarify though: Snapcast/librespot provides two login mechanisms:

  • Hard-coded username/password -- Rather than using client-provided credentials, the device itself decides the account it will use. This is what the threads in those other projects are about. But that's not what I'm using.

  • ZeroConf credentials -- This is what I'm using. I don't have any credentials specified in my Snapcast config. Instead, the server provides the standard ZeroConf API just like any other Spotify Connect device, and passes on the credentials data provided by the Spotify client (in this case, SpotifyPlus).

I can still use the Spotify app to switch between different accounts on my Snapcast device. So the device itself is able to login with the credentials provided by the Spotify app. This gives me hope that this can be fixed solely on the client side.

While I'm obviously not an expert (unlike you), I suspect the key issue here is that your Spotify API client library is constructing the addUser credentials blob using the username and password: https://github.com/thlucas1/SpotifyWebApiPython/blob/57143f66d5cb5cb7ac17beaf7fb41a288a4dcb6c/spotifywebapipython/zeroconfapi/zeroconfconnect.py#L548-L549. This is the part that's no longer supported by Spotify, I think(?). Instead, I think you now need to construct the credentials blob differently--probably using some output from the OAuth process. Unfortunately I have no idea what this other blob format needs to be. But maybe that's the part you need to figure out...?

Just out of curiosity, are you still able to login on your own Spotify Connect device? That is, if you switch your device to another user (e.g. via the Spotify app), is SpotifyPlus able to switch it back to the original user?

Thank you once again!

@milnivlek
Copy link
Author

milnivlek commented Aug 20, 2024

Actually - I just realized that you recently implemented sending the OAuth token in addUser for Sonos devices. Is there any way I can try enabling that for my device too?

EDIT: Just to test it out, I made a local change to disable the condition on this line. I went through your instructions for generating the token file, and copied it to ./config/.storage/spotifyplus_tokens.json. However, I keep getting this error:

Error: Spotify Desktop Client Application access token was not authorized

even though I supposedly do have a valid token:

# cat /config/.storage/spotifyplus_tokens.json
{
    "SpotifyWebApiAuthCodePkce/65b708073fc0480ea92a077233ca87bd/<<redacted>>": {
        "access_token": "BQA_qXg<<redacted>>",
        "expires_at": 1724140428.8688881,
        "expires_in": 3600,
        "refresh_token": "AQCAwVcg<<redacted>>",
        "scope": [
            "streaming"
        ],
        "token_type": "Bearer"
    }
}

Not sure what I did wrong here. I can't use Smart Inspect since I don't have a Windows machine (only Mac and Linux).

Oh well. Unfortunately I'll be out of town starting tomorrow, so I won't be able to try anything else for a bit. Hopefully you can reproduce the problem too on your end.

@thlucas1
Copy link
Owner

Do you have the latest v1.0.52 version installed? I had to move the token cache file to the ./config/.storage/spotifyplus_tokens.json folder with that release, as it used to be under the /config/custom_components/spotifyplus/data/tokens.json location and was getting deleted when the SpotifyPlus version was upgraded. In other words, v1.0.51 and prior is still looking in the old location for the token cache file. To be sure, I would upgrade to the latest SpotifyPlus version, which should then find your token in the ./config/.storage/spotifyplus_tokens.json folder.

My Bose SoundTouch devices still function fine using the user-id and password credentials, but I believe that is because the Bose cloud is doing something to convert them into Zeroconf credentials. No problems yet with those devices. My Sonos Symfonisk is working fine with the SpotifyPlus OAuth2 token logic. The Spotify Web and Mobile players of course work fine - I believe they are using the same OAuth2 process to login to the devices with. In fact, the AuthTokenGenerator.py script that you ran to create the token simply specifies the Spotify Desktop application client id and prompts you to authorize that client id for your Spotify user-id.

If you have Sonos devices, then you should be able to control them directly from SpotifyPlus without the need for SnapCast. I am not sure how that works though in your case, as I did not see any sonosRINCON... entries in your Zeroconf mDNS output from earlier:

$ dns-sd -B _spotify-connect._tcp. local.
Browsing for _spotify-connect._tcp..local.
DATE: ---Sat 17 Aug 2024---
22:50:55.202  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Attic Speaker
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Master Bedroom Speaker
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Kitchen Speaker
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Living Room Soundbar
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Dining Room Speaker
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. All Speakers
22:50:55.328  Add        3  15 local.               _spotify-connect._tcp. Dining & Kitchen
22:50:55.328  Add        2  15 local.               _spotify-connect._tcp. 1st Floor Speakers
22:50:55.540  Add        2  15 local.               _spotify-connect._tcp. f84a989346fb84a24fa545fde1a3102645d1ffca
22:50:55.598  Add        2  15 local.               _spotify-connect._tcp. cde82ced6ff067791e7bf8e70a58e9e40092887b
22:50:56.165  Add        2  15 local.               _spotify-connect._tcp. SpZc-A6E9C4

This is what I see in my dns-sd -B _spotify-connect._tcp. local. output for my Sonos device:

C:\Users\thluc>dns-sd -B _spotify-connect._tcp. local.
Browsing for _spotify-connect._tcp..local.
Timestamp     A/R Flags if Domain                    Service Type              Instance Name
 8:18:29.499  Add     3  5 local.                    _spotify-connect._tcp.    sonosRINCON_38420B909DC801400

I wonder if SnapCast (or librespot) is doing something to unregister the sonosRINCON... entries in your Zeroconf mDNS registration, and replacing them with the friendly names (e.g. Living Room Soundbar, etc). That would not make sense though, as the Sonos device should be registering its presence to Zeroconf / mDNS.

Anyhow, you should be able to query the Sonos device directly using the zeroconf_device_getinfo with it's IP, Port, and CPath info - like so for my Sonos Symfonisk:

action: spotifyplus.zeroconf_device_getinfo
data:
  entity_id: media_player.spotifyplus_todd_l
  host_ipv4_address: 192.168.1.91
  host_ip_port: 1400
  cpath: /spotifyzc

Receiving output like this (abbreviated and redacted):

user_profile:
  display_name: Todd L
  ...
result:
  ...
  BrandDisplayName: Sonos
  ClientId: 9b377073ea334637b1406f329ce005de
  DeviceId: f87342b3ad455375317d5af8aabde64a28bd49d0
  DeviceType: SPEAKER
  GroupStatus: NONE
  ModelDisplayName: Bookshelf
  ProductId: 1233
  RemoteName: Office
  Scope: streaming
  SupportedCapabilities: 3
  TokenType: authorization_code

Note the BrandDisplayName: Sonos indicates this is a Sonos device.

The brand value differs from your SnapCast BrandDisplayName: librespot definition, which indicates that SnapCast / librespot is defining the device for you and registering it with Zeroconf so that Spotify players can find it. At that point, SnapCast / librespot have control of the device.

Hope that makes sense.

@milnivlek
Copy link
Author

Hi @thlucas1 -- Just wanted to close the loop and let you know that your new librespot-specific credential handling in v1.0.59 has resolved my issue! SpotifyPlus now works fine once again with all my Spotify Connect devices exposed by my Snapcast server.

Not sure if you had my case in mind when you made this change. But regardless -- thank you so much for your dedication to building this HA integration. SpotifyPlus is amazing. I use it every day to automatically start music in the background, for my whole family's enjoyment. Thanks for making a small yet very real and tangible difference in the world! :)

@thlucas1
Copy link
Owner

thlucas1 commented Oct 8, 2024

@milnivlek
Thank you for your kind words - much appreciated.

My apologies, but I totally forgot about your SnapCast issue. If memory serves, I think I was waiting for you to respond after you returned from being out of town. No worries though, as the librespot fix sounds like it took care of the problem.

The v1.0.59 release seems to have fixed quite a few issues with products that utilize librespot: spotifyd, Spotify Connect AddOn, etc. Per your comment, it seems SnapCast falls into this category too since it utilizes librespot under the covers.

Just curious as to how you configured the SnapCast portion of your setup with SpotifyPlus. I would like to add a SnapCast Configuration section to my existing librespot Device Support documentation, if you don't mind sharing how you set it up.

Did you just create a /config/.storage/SpotifyWebApiPython_librespot_credentials.json from your librespot credentials.json file? Or do you still specify a Spotify userid / password somewhere in the SnapCast configuration somewhere?

@milnivlek
Copy link
Author

milnivlek commented Oct 8, 2024

Hey, that's the best kind of bugfix -- when you fix the deep root cause that's behind a whole bunch of other bugs, including some that you haven't even debugged fully yet!

Happy to help you with the instructions for Snapcast, though there's not much to say honestly. Basically, Snapcast exposes a "cache" configuration parameter for setting librespot's cache directory. So I just set this parameter, connected from the Spotify app, and grabbed the credentials.json file.

To be more precise, here's what I did:

  1. Edit my /etc/snapserver.conf to add the cache parameter to one of my defined librespot devices (which Snapcast calls a "source"):

    source = spotify:///librespot?bitrate=320&devicename=All Speakers&cache=/tmp/snapserver-cache

  2. Restart the Snapcast server: sudo systemctl restart snapserver

  3. Use my Spotify mobile app to connect to the Snapcast device that I configured the cache for. In this case, it's "All Speakers" as mentioned in step 1.

  4. Revert the change in /etc/snapserver.conf and restarted the server again.

  5. Grab the librespot credentials from /tmp/snapserver-cache/credentials.json. Then copy it over to SpotifyWebApiPython_librespot_credentials.json per your instructions.

And nope I don't have to specify my Spotify username and password anywhere else, since I'm using ZeroConf. Snapcast does provide its own mechanism to pass hardcoded credentials to librespot, but that's not relevant to the use case where we need SpotifyPlus to do ZeroConf device activation.

Hope this is sufficient to get you going with your documentation. Thanks again @thlucas1!

@thlucas1
Copy link
Owner

thlucas1 commented Oct 8, 2024

Perfect - that’s exactly what I needed. I will get the docs updated with that today. Thank you for taking the time to do that, as I don’t have SnapCast installed. Appreciate it.

@thlucas1
Copy link
Owner

@milnivlek
I put together a SpotifyPlus Card UI Beta Test announcement, if you're still interested in beta testing the new SpotifyPlus user-interface for Home Assistant? Just reply to the discussion link if you are, and feel free to download the card and give it a whirl.

Thanks - Todd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants