Spotify media player authorization problem

I use cache_path: /home/homeassistant/.homeassistant/.spotify-token-cache and now there is a .spotify-token-cache file in HA config folder but I have in log something about expired token:

17-04-10 21:20:35 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/helpers/entity_component.py", line 359, in async_process_entity
    new_entity, self, update_before_add=update_before_add
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/helpers/entity_component.py", line 189, in async_add_entity
    yield from self.hass.loop.run_in_executor(None, entity.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/components/media_player/spotify.py", line 152, in update
    self.refresh_spotify_instance()
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/components/media_player/spotify.py", line 139, in refresh_spotify_instance
    spotipy.oauth2.is_token_expired(self._token_info))
AttributeError: 'module' object has no attribute 'is_token_expired'

I’m not sure why that would be, it works in my tests. But try this!

Change line 139 from

spotipy.oauth2.is_token_expired(self._token_info))
to
self._oauth.is_token_expired(self._token_info))

Unfortunately still the same error.

Did you install spotipy from my fork?

It can’t be exactly the same error, if that line was changed.

If I add the cache path and make the required change the modal box for authorization becomes empty after linking and then disappears. A .spotify-token-cache file (with JSON content) is then written to my HA directory.

No media_player shows up though, but the logs do indicate something went wrong with it:

Apr 10 22:40:38 homeassistant hass[2072]: 17-04-10 22:40:38 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Apr 10 22:40:38 homeassistant hass[2072]: Traceback (most recent call last):
Apr 10 22:40:38 homeassistant hass[2072]:   File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
Apr 10 22:40:38 homeassistant hass[2072]:     result = coro.throw(exc)
Apr 10 22:40:38 homeassistant hass[2072]:   File "/srv/hass/lib/python3.5/site-packages/homeassistant/helpers/entity_component.py", line 359, in async_process_entity
Apr 10 22:40:38 homeassistant hass[2072]:     new_entity, self, update_before_add=update_before_add
Apr 10 22:40:38 homeassistant hass[2072]:   File "/srv/hass/lib/python3.5/site-packages/homeassistant/helpers/entity_component.py", line 189, in async_add_entity
Apr 10 22:40:38 homeassistant hass[2072]:     yield from self.hass.loop.run_in_executor(None, entity.update)
Apr 10 22:40:38 homeassistant hass[2072]:   File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
Apr 10 22:40:38 homeassistant hass[2072]:     yield self  # This tells Task to wait for completion.
Apr 10 22:40:38 homeassistant hass[2072]:   File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
Apr 10 22:40:38 homeassistant hass[2072]:     future.result()
Apr 10 22:40:38 homeassistant hass[2072]:   File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
Apr 10 22:40:38 homeassistant hass[2072]:     raise self._exception
Apr 10 22:40:38 homeassistant hass[2072]:   File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
Apr 10 22:40:38 homeassistant hass[2072]:     result = self.fn(*self.args, **self.kwargs)
Apr 10 22:40:38 homeassistant hass[2072]:   File "/home/hass/.homeassistant/custom_components/media_player/spotify.py", line 154, in update
Apr 10 22:40:38 homeassistant hass[2072]:     item = current.get('item')
Apr 10 22:40:38 homeassistant hass[2072]: AttributeError: 'NoneType' object has no attribute 'get'

I am using your forked spotipy.

This particular exception seems to occur if no media is playing at Spotify.

I then pressed Play on my desktop client and restarted HA.
The media_player then showed up with proper artist/title and fanart. Next seems to work fine as well!

So a few minor things to tweak I guess are:

  1. Deal with caching (e.g. cache = hass.config.path(DEFAULT_CACHE_PATH) like the Ring component is using seems to work better)
  2. Dealing with the token refresh, your change for L139 seems to work
  3. Dealing with a non-playing player where no result is being given

I use this component https://github.com/home-assistant/home-assistant/pull/6980/files#diff-b4e0de3960c941b2052c28b3eabda74b and install spotipy by pip install spotipy==2.4.4 --target ~/.homeassistant/deps. Error isn’t exactly the same. My bad.

17-04-10 23:09:55 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/helpers/entity_component.py", line 359, in async_process_entity
    new_entity, self, update_before_add=update_before_add
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/helpers/entity_component.py", line 189, in async_add_entity
    yield from self.hass.loop.run_in_executor(None, entity.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/components/media_player/spotify.py", line 152, in update
    self.refresh_spotify_instance()
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/components/media_player/spotify.py", line 139, in refresh_spotify_instance
    self._oauth.is_token_expired(self._token_info))
AttributeError: 'SpotifyOAuth' object has no attribute 'is_token_expired'

That’s the original library. Until the open PR for it has been merged you’ll have to install his fork:

pip3 install https://github.com/happyleavesaoc/spotipy/archive/544614f4b1d508201d363e84e871f86c90aa26b2.zip#spotipy==2.4.4

The original doesn’t yet have support for Spotify Connect.

1 Like

@syphernl Thanks for the notes. I pushed a commit that should address all of those things: https://github.com/home-assistant/home-assistant/pull/6980/commits/e6fedf36dce12942c2b2072e58abdffba910ca76

I was never able to get a “non-playing” state that was empty, only “paused” or “playing”.

@Bieniu Yes, install spotipy the way syphernl specified. Your version is old and doesn’t support the new web connect API, or apparently token refresh in the way the component does it.

1 Like

I installed spotipy like @syphernl shows and player is working! Greate job @happyleaves. Thank you guys for help.
But I have small isuue. When I turn to standby my Spotify player (Denon AVR) in HA log appears this error few times:

17-04-11 07:16:19 ERROR (MainThread) [homeassistant.helpers.entity] Update for media_player.spotify fails
Traceback (most recent call last):
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/helpers/entity.py", line 225, in async_update_ha_state
    None, self.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/components/media_player/spotify.py", line 167, in update
    self._volume = current.get('device').get('volume_percent') / 100
TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'

Tested it this morning and seems to work a lot better. Awesome stuff, works like a charm!

I wonder whether it would be possible for the player to return to an idle state, because now it always stays at paused indefinite if you pause it at one point?

I installed newest version spotify.py from PR and player appears after restart HA.

Yes, I think so. How do you get Spotify into a non-paused/playing state?

Strange, today morning media player appeared after HA restart when no player was active, now not appears after restart.

Is your cache file still there? Is there any error in the log?

After a HA restart I’m now getting the same log error as @Bieniu, the volume calculation error. As a result, the player doesn’t show up anymore.

Yes, everything is in place. Sometimes when I restarted HA with all Spotify players off media_player don’t appears. But only sometimes. In this cases in log there are errors about volume. When media_player appears everything is working but I have this error:

17-04-11 20:39:06 WARNING (MainThread) [homeassistant.helpers.entity] Update of media_player.spotify is taking over 10 seconds.
17-04-11 20:39:06 ERROR (MainThread) [homeassistant.helpers.entity] Update for media_player.spotify fails
Traceback (most recent call last):
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/helpers/entity.py", line 225, in async_update_ha_state
    None, self.update)
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/homeassistant/components/media_player/spotify.py", line 153, in update
    current = self._player.current_playback()
  File "/home/homeassistant/.homeassistant/deps/spotipy/client.py", line 856, in current_playback
    return self._get("me/player", market = market)
  File "/home/homeassistant/.homeassistant/deps/spotipy/client.py", line 148, in _get
    return self._internal_call('GET', url, payload, kwargs)
  File "/home/homeassistant/.homeassistant/deps/spotipy/client.py", line 125, in _internal_call
    -1, '%s:\n %s' % (r.url, r.json()['error']['message']),
  File "/srv/homeassistant/homeassistant_venv/lib/python3.4/site-packages/requests/models.py", line 866, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3.4/json/__init__.py", line 318, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.4/json/decoder.py", line 343, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.4/json/decoder.py", line 361, in raw_decode
    raise ValueError(errmsg("Expecting value", s, err.value)) from None
ValueError: Expecting value: line 1 column 1 (char 0)

When I restarted HA with Spotify player on there is no errors.

Wow, I hadn’t heard about this plugin before and it sounds like something I may need to try out.

I don’t want to derail the thread but I got to ask if I got it right; can you use this to start any spotify uri (like spotify:user:spotify:playlist:4BKT5olNFqLB1FAa8OtC8k) on any compatible spotify device in the network? Chromecasts etc?

If so I am definitely going to test it tomorrow.

@chrio If your chromecast shows up in Spotify Connect, then yes (mine doesn’t … on my Fire TV, Echo dot, etc)

I pushed an update that hopefully should address the idle/volume issue.

Thanks for this awesome component. Looks like something i can make use for my echo dots.

May i know can it work without exposing my HA to the internet?