openHAB integration to Spotify Web Connect API (player)


(Patrick) #42

Hey again,

I added an option to transfer the playback directly without having to stop-start.

Simply add the command “transfer_playback” to the scene button:

 		<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>

And make sure you get the latest version of the spotify.py file.

Let me know!


(Unparagoned) #43

There are two ways to change the device. One way is to POST to a url with the device id in it and the other is just to put the device id in the message you post. So one method changes the post URL with play?device_id=66955b926defdf6d4187ac0281c6ce6a7863013, the other adds the device_ids to the json body. You can’t use them interchangeably, so if you want to play a context uri and change device you can’t use the method where both pieces of data are in the message.

My latest version of spotify.py, makes play more general purpose, it checks if there is a context_uri and/or device. Here we assume that a device has been specified.

 I say "Hey google spotify play bathroom",
IFTTT gets open hub to run 
spotify.py play bathroom
   Posts to https://api.spotify.com/v1/me/player , with the device_id in the message
Otherwise if there is a playlist, such as 
spotify.py play spotify:album:0hQOqvZv1nQvPiBjzyn363 bathroom
Posts to https://api.spotify.com/v1/me/player/play?device_id=66955b926defdf6d4187ac0281c6ce6a7863013 
With the conext uri in the message
your code goes here

edit: My current setup is connected to Hue sensors so when I go into the bathroom it switches to the bathroom echo and then when I come back into the main room it switches back to the main room computer pretty smoothly, no stopping/skipping or other issues. (Apart from some minor issues like my low update frequency and when my locks get stuck on)

I made some more changes. I’ve just updated github. (Sorry I don’t have github installed properly to autoupdate and am doing manually through the website). I’ve merged the habpanel stuff for reference. (I’ve screwed up the css for some menu stuff but…)

edit 3: Oh I’ve tried to make the outsides more dynamic but never managed to get around to making it 1337 enough, feel free to spice it up.


(Sasha) #44

Thanks for the script!

I’ve got an error with python as well.

/usr/bin/python /etc/openhab2/scripts/spotify.py
Traceback (most recent call last):
File "/etc/openhab2/scripts/spotify.py", line 6, in <module>
import requests
ImportError: No module named requests

That’s what I have in /usr/python:
python python2 python2.7 python3 python3.5 python3.5m python3m

What can that be?

And also, may I ask a really dumb question? How can I find the URI of my playlist?
I haven’t implemented the script yet, might be obvious when I do.
Thanks!!


(Bullet Proof Fool) #45

I am trying my best, but just can’t seem to get over the final hurdle:

When I execute the python script I get the logs below.

I have regenerated my keys and tried again.
restarted tutorial from scratch too

Thanks

vanwyks@openHab2:/etc/openhab2/items$ /usr/bin/python /etc/openhab2/scripts/spotify.py
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
_CaseInsensitiveDict({'content-length': '69', 'keep-alive': 'timeout=600', 'server': 'nginx', 'connection': 'keep-alive', 'date': 'Fri, 01 Sep 2017 13:22:52 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_
_CaseInsensitiveDict({'content-length': '68', 'keep-alive': 'timeout=600', 'server': 'nginx', 'connection': 'keep-alive', 'date': 'Fri, 01 Sep 2017 13:22:52 GMT', 'content-type': 'application/json'})_
_{u'error_description': u'Invalid redirect URI', u'error': u'invalid_grant'}_
_-- 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 = 2017-09-01T13:22:51+0000_
_Done in 0.616595029831 seconds_

(Patrick) #46

@BulletProofFool1 Looks like your auth credentials are missing or invalid. Did you follow the instructions and auth the app? Can you verify that the token is properly stored when you open the authentication HTML page?


(Patrick) #47

@sasha_jpr You’re missing the requests module:


(Bullet Proof Fool) #48

Hi - just checked this (in hope) - but not i:

openHab2:/etc/openhab2$ sudo apt-get install python-requests
Reading package lists... Done
Building dependency tree
Reading state information... Done
**python-requests is already the newest version.**
python-requests set to manually installed.

(Bullet Proof Fool) #49

I followed the instructions to auth the app,

Went through the html page and got the status change from red to green, with a message “New Auth Code successfully saved to OpenHab”

If I use the karaf console to check item values, I get:

openhab> smarthome:items list | grep AQ
spotify_auth_code (Type=StringItem, State=[xxxxxxxxxxxxxx]

and

openhab> smarthome:items list | grep spotify_clie
spotify_client_id (Type=StringItem, State=[xxxxxxxxxxxx], Label=null, Category=null)
spotify_client_secret (Type=StringItem, State=[xxxxxxxx]

all with the valid params populated

I am using RR4DJ for persistence, since it was quick and easy to setup - could this have something to do with it?

======================= MORE INFO ========================

When I look at the auth page URL after authentication, I get the uri: http://192.168.0.168:8080/static/spotify-auth.html?code=AQAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
in the Auth code field one the HTML page however, it tells me the auth code is QA… (no A at the start)

checking my params in the karaf console, I see
openhab> smarthome:items list | grep AQ
spotify_auth_code (Type=StringItem, State=AQA9 again.

bug perhaps?


(Patrick) #50

Could you reset (empty) your item states and try again?


(Bullet Proof Fool) #51

Sure - here’s what I currently have

spotify_forceupadte (Type=SwitchItem, State=NULL, Label=null, Category=null)
spotify_auth_code (Type=StringItem, State=xxx
spotify_client_id (Type=StringItem, State=xxx, Label=null, Ca
spotify_client_secret (Type=StringItem, State=xxx, Label=null
spotify_access_token (Type=StringItem, State=xxx
spotify_refresh_token (Type=StringItem, State=NULL, Label=RefreshToken, Category=null)
spotify_token_expiry (Type=StringItem, State=NULL, Label=TokenExpiry, Category=null)
spotify_token_issued (Type=DateTimeItem, State=NULL, Label=TokenIssued, Category=null)
spotify_current_track (Type=StringItem, State=NULL, Label=null, Category=null)
spotify_current_artist (Type=StringItem, State=NULL, Label=null, Category=null)
spotify_current_cover (Type=StringItem, State=NULL, Label=null, Category=null)
spotify_current_duration (Type=StringItem, State=NULL, Label=null, Category=null)
spotify_current_progress (Type=StringItem, State=NULL, Label=null, Category=null)
spotify_current_progress_percent (Type=NumberItem, State=NULL, Label=null, Category=null)
spotify_current_playing (Type=SwitchItem, State=NULL, Label=null, Category=null)
spotify_current_context_uri (Type=StringItem, State=NULL, Label=null, Category=null)
spotify_current_device (Type=StringItem, State=NULL, Label=null, Category=null)
spotify_current_device_id (Type=StringItem, State=NULL, Label=null, Category=null)
spotify_current_volume (Type=NumberItem, State=NULL, Label=null, Category=null)
spotify_action (Type=StringItem, State=NULL, Label=null, Category=null)
spotify_lastConnectionDateTime (Type=DateTimeItem, State=2017-09-01T14:28:05.000+0100, Lab
spotify_device_list (Type=StringItem, State=NULL, Label=null, Category=null)
openhab>

I’ll blank everything, regen the App in Spotify Dev again and update you:

Update code:

openhab> smarthome:update spotify_access_token
Usage: smarthome:update <item> <state> - sends a status update for an item
openhab> smarthome:update spotify_access_token empty
Update has been sent successfully.
openhab> smarthome:update spotify_client_id empty
Update has been sent successfully.
openhab> smarthome:update spotify_client_secret empty
Update has been sent successfully.
openhab> smarthome:update spotify_auth_code empty
Update has been sent successfully.
openhab>

and from rest:

{"link":"http://192.168.0.168:8080/rest/items/spotify_auth_code","state":"empty","type":"String","name":"spotify_auth_code","tags":[],"groupNames":[]}


(Patrick) #52

Looks like the state is now the string “empty”. It should be NULL.


(Bullet Proof Fool) #53

OK - was doing exactly as I was told earlier (perhaps I should have used some sense)
Anyway, continuing

{"link":"http://192.168.0.168:8080/rest/items/spotify_auth_code","state":"NULL","type":"String","name":"spotify_auth_code","tags":[],"groupNames":[]}

QQ - Docs say:

Save the Client ID to spotify_client_id in OpenHab (e.g. through openhab CLI smarthome:update spotify_client_id {your_id})
Copy the Client Secret to spotify_client_secret in OpenHab (e.g. through the rest API)

I assume doing the following in karaf is ok?

openhab> smarthome:update spotify_client_id xyz123
Update has been sent successfully.
openhab> smarthome:update spotify_client_secret xyzabc
Update has been sent successfully.

(Patrick) #54

Yep, and now re-auth the app


(Bullet Proof Fool) #55

Oh FFS.

I am so sorry for wasting your time - went through this a THIRD time . . .and realised I’d missed one little thing:

> Set the REDIRECT_URI in spotify.py to the right value

Got a feeling I may have overwritten my original edit and then not changed it again
For anyone else who gets this:

– Calling Token Refresh Service
CaseInsensitiveDict({‘content-length’: ‘69’, ‘keep-alive’: ‘timeout=600’, ‘server’: ‘nginx’, ‘connection’: ‘keep-alive’, ‘date’: ‘Fri, 01 Sep 2017 13:22:52 GMT’, ‘content-type’: ‘application/json’})
{u’error_description’: u’Invalid refresh token’, u’error’: u’invalid_grant’}

Please make VERY sure that you’ve updated spotify.py

Issue resolved - thanks for your time - no doubt, you’ll hear from me again!


(Patrick) #56

No worries! :slight_smile:


(Bullet Proof Fool) #57

Thanks again.

2 quick questions:

  1. How often do the Spotify items get updated?
  2. Have you implemented the code above to allow device selection?

(Patrick) #58

Device selection is implemented already.

It’s up to you how often you want to update. Right now it’s on demand. I will try a suggestion to auto update while HabPanel is open when I have time.


(Bullet Proof Fool) #59

Coolios,

In my case I want to autoupdate regularly, since I have Amazon echo all over the house running Spotify . . but when someone launches music via the voice command on alexa, I want to trap this and redirect the music to a dedicated Spotify client (re purposed Android TV device, plugged into several AV receivers around the house)

Workflow runs like this:

Spotify.py detects device change
if (device.match(“Kitchen Echo”)){
Make music in kitchen
} else if (device.match(“Loft Echo”)){
Make music in loft
}

The $1million is what happens when I am playing spotify to a Group

But these are my worries :slight_smile:

Super work - thanks again!

I’ll sort through the .py code for now - but according to: https://github.com/pmpkk/openhab_spotify-webconnect-api the only current params are:

Use

spotify.py
parameters:
none = refresh data
play = resume playing
play uri = play suported uris (album, artist or playlist), e.g. spotify:user:spotify:playlist:37i9dQZF1DX5OepaGriAIm
pause = pause
next = next track
previous = previous track
volume_up = 10% up
volume_down = 10% down


(Patrick) #60

The doc was outdated. Fixed now.

Please note that the transfer of playback from one device to another works by setting the openhab item to the right id and then calling “transfer_playback”.


(Bullet Proof Fool) #61

Thanks,

Tested, works if I set spotify_current_device_id

and execute:

vanwyks@openHab2:/etc/openhab2/rules$ sudo /usr/bin/python /etc/openhab2/scripts/spotify.py transfer_playback

Fails if I set spotify_current_device and execute code above (no probs, I can work around this - I suspect the array containing device to device_id mappings is not getting updated.

I have a small feature request…
Are you able to retrieve whether the current track is tagged as “Explicit” so I can skip these during hours where the kids are downstairs?

Thanks again for all the help - huge progress today

How would you suggest I set this up to constantly update? cron job?