openHAB integration to Spotify Web Connect API (player)


(Jonas) #247

The fix to my issue:

You have to make the python script executable - otherwhile the OS will open the script in the terminal and produce the errors i posted above (OS X):

sudo chmod +x file-name.py

After this add

#!/usr/bin/env python2.7

to the top of the python script! (Yes, with # )

:slight_smile:


(Unparagoned) #248

I’m pretty sure it’s written in python 2. So when you are running it from terminal it’s probably running python2.7, but when you run it from the rule its python 3.

Have a look at your rule. You should be able to specify what version of python. The following works for me

executeCommandLine("/usr/bin/python /etc/openhab2/scripts/spotify.py " + receivedCommand.toString, 500)

But you could specify the version of python

executeCommandLine("/usr/bin/python2.7 /etc/openhab2/scripts/spotify.py " + receivedCommand.toString, 500)

(Jonas) #249

oh nice, i’ll try that!

Yeah i installed python 3 the other day (while dealing with grafana) and now i think the highest version of python is used.

I’ll try your answer :slight_smile:

EDIT: Your solution works as well!
So it does not matter where you specify the environment. either the rule that calls the script or the script itself.


(Edwin de Boer) #250

Hello,

The design looks really good. Currently thinking about the theme to go and use.
But for now I would like to get the Spotify working without this theme.

I get NULL values.
The connection with Spotify seems not to work.
The Authentication was succesfull though.
Running the spotify.py is giving me errors.

Successfully got state from OpenHab: spotify_client_id
Successfully got state from OpenHab: spotify_client_secret
Successfully got state from OpenHab: spotify_access_token
Successfully got state from OpenHab: spotify_refresh_token
Successfully got state from OpenHab: spotify_token_issued
Successfully got state from OpenHab: spotify_token_expiry
-- Calling Token Refresh Service
{'Content-Length': '70', 'Keep-Alive': 'timeout=600', 'Server': 'nginx', 'Connection': 'keep-alive', 'Date': 'Mon, 11 Jun 2018 17:29:02 GMT', 'Content-Type': 'application/json'}
{u'error_description': u'Invalid client secret', u'error': u'invalid_client'}
Successfully got state from OpenHab: spotify_auth_code
-- Calling Token Service for the first time
{'Content-Length': '70', 'Keep-Alive': 'timeout=600', 'Server': 'nginx', 'Connection': 'keep-alive', 'Date': 'Mon, 11 Jun 2018 17:29:02 GMT', 'Content-Type': 'application/json'}
{u'error_description': u'Invalid client secret', u'error': u'invalid_client'}
-- Calling Service: Update
{u'error': {u'status': 401, u'message': u'Invalid access token'}}
 -> Item node missing from response :(
Successfully posted state to OpenHab: spotify_lastConnectionDateTime = 2018-06-11T17:29:02+0000
Done in 0.625561952591 seconds

Does anyone have any Idea whats going wrong here?

Regards, Edwin


(Pavel) #251

Can anybody provide dashboard from head or similar? It can be exported as json in settings.


(Kris K) #252

Does anyone know if under devices it would list an airplay device on my lan if the habpanel device is an android ? It lists the spotify connect device ok.


(Jonas) #253

Hi!

Is there a way to run the script every second ONLY when spotify is playing?
Maybe we can build a rule that fires every 30 sec to check if it’s playing and if so change the interval to 1 s?
I also don’t get the part of the rule:


rule "Spotify Action"
when
		Item spotify_action received update
	then		
			val resp =  executeCommandLine("/usr/bin/python2.7 /scripts/spotify.py " + spotify_action.state.toString, 5000)
			logInfo("Spotify", resp)
end

what’s that supposed to do?
The first part runs the script, when i push a button …

Thank you!


(Kris K) #254

Any thoughts as to why Playlist, Devices or Volume dont work? Play/Stop work fine.

Devices doesnt update unless I use the Spotify app to actually play something in it, then the device is visible in OH2. It doesnt show a ‘list’ of devices on my LAN, only one device thats playing.

Album art, artist and song all work


(Kris K) #255

@Dries I have the same issue with devices .

I have a LINN DS player on my LAN, it has proper spotfiy connect intergration but only shows in HABPanel when i click play or use it in the Official App

Did you sort this out?

Ideally I should get a list of devices I can choose but I dont

@tr1cks relevant for you


(Dries) #256

Unfortunately not


(Pavel) #257

Hi!

I tried to keep lists as json in String item. It working well, but only when I open page first time. After refresh they vanish. May be it’s related to ng-init. It’s hard to say for me, because I am almost not familiar with Angular. What can be wrong?

<div class="widget">
    <div class="icon off">
        <svg viewBox="0 0 48 48">
            <use xlink:href="/static/matrix-theme/squidink.svg#box"></use>
        </svg>
    </div>
    <div class="name">Devices</div>
    <div class="sceneGroup" ng-init="deviceList = $eval(itemValue('spotify_device_list'))">
        <div class="scene" ng-class="{true:'on', false:''}[itemValue('spotify_current_device_id')==device.id]"
             ng-repeat="device in deviceList"
             ng-click="sendCmd('spotify_current_device_id', device.id);sendCmd('spotify_action', 'transfer_playback')">
            {{device.name}}
        </div>
    </div>
</div>

(Unparagoned) #258

I had some issues with the devices and playlists not updating. My current setup works well but it’s a branch and I think the way devices is different to the main branch so you may need to adapt it. There is a refresh button which updates devices, and then I make sure the interface has the latest set of devices with a mouseover function.

Note: The way devices works may be different in the main branch. 

      <div class="widget" ng-init="devices=$eval(itemValue('spotify_devices')).devices">
        <div class="icon off" ng-click="sendCmd('spotify_device_update', 'ON'); devices=$eval(itemValue('spotify_devices')).devices"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#double-arrow"></use></svg></div>
        <div class="nameGroup"><div class="name">Devices</div></div>
        <div class="btn-group" dropdown-append-to-body="true" uib-dropdown >            
          <button id="single-button" type="button" class="btn btn-primary" uib-dropdown-toggle  ng-click="devices=$eval(itemValue('spotify_devices')).devices" ng-mouseover="devices=$eval(itemValue('spotify_devices')).devices">
            {{itemValue('spotify_current_device')}} <span class="caret"></span>
          </button>
          <ul class="mydropdown-menu" uib-dropdown-menu role="menu" style="overflow: auto; max-height:300px; overflow-x:hidden" aria-labelledby="single-button" >   
            <div ng-repeat="dev in devices" ng-if="dev.state!='NULL'" >
              <li role="menuitem"><a ng-click='sendCmd("spotify_action", "play \"" + dev.id + "\"")'>{{dev.name}}</a></li>
            </div>
          </ul>
        </div>
      </div>

(Kris K) #259

How does that look visiually @unparagoned


(Unparagoned) #260

It’s a circle arrow for refresh and a drop-down to select devices. There is a picture here Matrix Theme for HABPanel


(Pavel) #261

Just for mention. https://api.spotify.com/v1/me/player/ can return 204 with empty body. It will lead to exception on r.json() and error “Failure: <type ‘exceptions.ValueError’>” in log.


(Pavel) #262

Have somebody problems lately like “Invalid client Id” or “Invalid refresh token”?


(Kris K) #263

@Edwin_de_Boer did you fix this? I have the same issue now


(Unparagoned) #264

Do you have an actual problem or do you just want to make the logs look clean?


(Kris K) #265

An actual problem @unparagoned

I switched off my receiver thats used for spotify and all of a sudden when I reauth, which works fine, I see the logs showing token issues.

Nothing had changed. Looking in influx, I cant see it storing the token either.

I recreated the app in Spotify Dev console, entered in the new secret/client id and auth works. But the token part is failing and ive no idea why. This worked fine before.

Successfully got state from OpenHab: spotify_client_secret

Successfully got state from OpenHab: spotify_access_token
Successfully got state from OpenHab: spotify_refresh_token
Successfully got state from OpenHab: spotify_token_issued
Successfully got state from OpenHab: spotify_token_expiry
– Calling Token Refresh Service
{‘client_secret’: ‘XXXXXXXX’, ‘redirect_uri’: ‘http://192.168.0.3:8080/static/spotify-auth.html’, ‘client_id’: ‘CCCCC518’, ‘refresh_token’: ‘NULL’, ‘grant_type’: ‘refresh_token’}
{‘Content-Length’: ‘69’, ‘Keep-Alive’: ‘timeout=600’, ‘Server’: ‘nginx’, ‘Connection’: ‘keep-alive’, ‘Date’: ‘Thu, 05 Jul 2018 00:31:34 GMT’, ‘Content-Type’: ‘application/json’}
{u’error_description’: u’Invalid refresh token’, u’error’: u’invalid_grant’}
Successfully got state from OpenHab: spotify_auth_code
– Calling Token Service for the first time
{‘Content-Length’: ‘68’, ‘Keep-Alive’: ‘timeout=600’, ‘Server’: ‘nginx’, ‘Connection’: ‘keep-alive’, ‘Date’: ‘Thu, 05 Jul 2018 00:31:34 GMT’, ‘Content-Type’: ‘application/json’}
{u’error_description’: u’Invalid redirect URI’, u’error’: u’invalid_grant’}
– Calling Service: Play
Successfully got state from OpenHab: spotify_current_device_id
401
– Calling Service: Update
{u’error’: {u’status’: 401, u’message’: u’Invalid access token’}}
-> Item node missing from response :frowning:
– Calling Service: Get Devices
-> Device List Failure: <type ‘exceptions.KeyError’>
– Calling Service: Get Playlists
{u’error’: {u’status’: 401, u’message’: u’Invalid access token’}}
-> Playlist List Failure: <type ‘exceptions.KeyError’>
Successfully posted state to OpenHab: spotify_lastConnectionDateTime = 2018-07-05T00:31:36.000+0000
Done in 3.3187558651 seconds


(Unparagoned) #266

What do you mean reauth? The way it should work is you auth once, then the script will handle all the authorisation and getting new keys in the background.

Make sure you go through the instructions thoroughly and it should work.

If you are still struggling you can try a widget to made, it should cover the main instruction on setting up authorisation.

image

Remember to change the clientid, secret, openhab name/ip:port then you should be good to go.

<div class="section" ng-init="new_client_id='clientid';new_client_secret='secret'">
  <widget>
    <div class="title">Spotify Creds</div>
    <div class="name"> Sign up to spotify to develop your own app to get a client ID and client secret <a href="https://developers.spotify.com/my-application/">developers.spotify.com/my-application/</a> then add http://openhabian:8080/static/spotify-auth.html to the redirect uri and save changes. Complete id and secret below and click buttons to update them. then click authenticate link and authenticate</div>

    <div class="name">Current ID: {{itemValue('spotify_client_id')}} </div> &#13; <div class="name">  Enter new spotify_client_id <input style="color: black;" ng-model="new_client_id"  size="35"  />
    <button ng-click="sendCmd('spotify_client_id', new_client_id)">Update Client ID</button></div>
    <div class="name">Current secret: {{itemValue('spotify_client_secret')}}</div> &#13; <div class="name"> Enter new spotify_client_secret <input style="color: black;" ng-model="new_client_secret" size="35" />
    <button ng-click="sendCmd('spotify_client_secret', new_client_secret)">Update Client Secret</button></div>
    <div class="title">&#10;<a href="http://openhabian:8080/static/spotify-auth.html" target="_blank">Click open authenication link!</a></div>
    <div class="controlGroup">
      <div class="heading">&#10;Blow clears other creds credential- DANGEROUS</div>
      <div class="name" ng-init="display=0">Click below to see and reset auth codes</div>
      <div class="name" ng-click="display=1">ENABLE RESET - DANGER</div>
      <div class="nameGroup" ng-if="display==1">
        <button ng-click="sendCmd('spotify_auth_code','NULL')">Reset</button><div> {{itemValue('spotify_auth_code')}}</div>
        <button ng-click="sendCmd('spotify_access_token','NULL')">Reset</button><div> {{itemValue('spotify_access_token')}}</div>
        <button ng-click="sendCmd('spotify_refresh_token','NULL')">Reset</button><div> {{itemValue('spotify_refresh_token')}}</div>
        <button ng-click="sendCmd('spotify_token_expiry','NULL')">Reset</button><div> {{itemValue('spotify_token_expiry')}}</div>
      </div>
    </div>
  </widget>
</div>