openHAB integration to Spotify Web Connect API (player)


(Andrew Pawelski) #90

So should the detection of a song playing happen without any refresh to then fire the rule?


(Jonas) #91

Hi! I followed your tutorial on github and i got everything done. now i don’t know how to change values (for example just play/pause).
in the tut you write that this is done with the python script. can you please explain that a little bit for me? i can see the items in the habpanel but i created a button and mapped play/pause spotify current playing to it (seems like it’s only a read variable) so it does not work.
what do i to do need if i want to control things?

thanks a lot!

addition:
i successfully created a dummy label that shows me the current track.
it does show the last track played when i did run the python script in the terminal.
how can i execute the script from a rule? is that the way it should be working? :wink:
and at last of course: how can i actually control stuff. Thanks! :slight_smile:


(Andrew Pawelski) #92

So it looks like there is no detection of when Spotify starts playing - are people just running the script every 10 seconds to capture changes in state?


(sceppi) #93

I’m having the same issue. When I play from a device, the label and the title shows up fine on my HabPanel. I can see which track is playing, and also the progress bar. Only: I cannot control thingsfrom Habpanel. For example:

  • When I change my volume from 100 to 50 in habpanel nothing happens
  • However when I change the volume in spotify itself for example from 100 to 50 and then press update in HabPane, then the volume is updated from 100 to 50.

–> So it retrieves the information correctly from spotify, but I cannot control or send actions from HabPanel


(Patrick) #94

To find the problem, try:

  1. Call the spotify.py command from the shell:

e.g. on Raspberry Pi:

/usr/bin/python /etc/openhab2/scripts/spotify.py play
  1. Did you wire up the rule to pass the spotify action item into the python command?
rule "Spotify Action"
when
		Item spotify_action received update
	then		
			val resp =  executeCommandLine("/usr/bin/python /etc/openhab2/scripts/spotify.py " + spotify_action.state.toString, 5000)
			logInfo("Spotify", resp)
end

(Florian) #95

Hey @pmpkk,

Thank you very much for your great work. Most the things I am currently missing are issues on spotify’s table (real time updates e.g. via websockets or webhooks and the possibility to control all devices that are available in the apps e.g. Chromecast).

One thing however that is not working for me is the persistence. I installed influxdb (together with grafana) and it’s working. But since I didn’t want to track every single item update I wanted to now which items actually have to be saved (and restored after a reboot?).

This is how my influxdb.persist currently looks like:

Strategies {
    everyMinute : "0 * * * * ?"
    everyHour   : "0 0 * * * ?"
    everyDay    : "0 0 0 * * ?"
}

Items {
    spotify_auth_code      : strategy = everyUpdate
    spotify_client_id      : strategy = everyUpdate, restoreOnStartup
    spotify_client_secret  : strategy = everyUpdate, restoreOnStartup
    spotify_access_token   : strategy = everyChange
    spotify_refresh_token  : strategy = everyChange
    spotify_token_expiry   : strategy = everyChange
    spotify_token_issued   : strategy = everyChange
}

But since I have to do the auth dance (http://openhabianpi.local:8080/static/spotify-auth.html) every time after a reboot I think it’s not working correctly. What does your persist file look like?

Regards,
Florian


(Patrick) #96

Cool!

I persist all items on everyChange, everyDay and restoreOnStartUp.

I’ve been running for a year now and generate 100MB a month worth of log data, which is totally fine for me.

Did you try to change it to this just to see if it works:

Items {
	* : strategy = everyChange, everyDay, restoreOnStartup
}

(Florian) #97

[SOLVED] Now it works. This is how it looks now:

Items {
    spotify_auth_code      : strategy = everyUpdate, restoreOnStartup
    spotify_client_id      : strategy = everyUpdate, restoreOnStartup
    spotify_client_secret  : strategy = everyUpdate, restoreOnStartup
    spotify_access_token   : strategy = everyUpdate, restoreOnStartup
    spotify_refresh_token  : strategy = everyUpdate, restoreOnStartup
    spotify_token_expiry   : strategy = everyUpdate, restoreOnStartup
    spotify_token_issued   : strategy = everyUpdate, restoreOnStartup
}

(sceppi) #98

I tried the python.py play command. Here is what I get:

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 Service: Play
Successfully got state from OpenHab: spotify_current_device_id
403
– Calling Service: Update
{u’progress_ms’: 32130, u’timestamp’: 1507109776031L, u’repeat_state’: u’off’, u’shuffle_state’: False, u’item’: {u’album’: {u’album_type’: u’single’, u’name’: u’Together’, u’external_urls’: {u’spotify’: u’https://open.spotify.com/album/2WPc1NxJDtzVLk0StBEbMz’}, u’uri’: u’spotify:album:2WPc1NxJDtzVLk0StBEbMz’, u’href’: u’https://api.spotify.com/v1/albums/2WPc1NxJDtzVLk0StBEbMz’, u’artists’: [{u’name’: u’Klaas’, u’external_urls’: {u’spotify’: u’https://open.spotify.com/artist/25sJFKMqDENdsTF7zRXoif’}, u’uri’: u’spotify:artist:25sJFKMqDENdsTF7zRXoif’, u’href’: u’https://api.spotify.com/v1/artists/25sJFKMqDENdsTF7zRXoif’, u’type’: u’artist’, u’id’: u’25sJFKMqDENdsTF7zRXoif’}], u’images’: [{u’url’: u’https://i.scdn.co/image/7894006d2c2c8c3e29d0ab498c959fadd8722f44’, u’width’: 600, u’height’: 600}, {u’url’: u’https://i.scdn.co/image/62dda60ccc3ae36a3bd63248d1dbdfc779eb9923’, u’width’: 300, u’height’: 300}, {u’url’: u’https://i.scdn.co/image/f4a985352a5852d05ea234a911b5cc07f0e14d2b’, u’width’: 64, u’height’: 64}], u’type’: u’album’, u’id’: u’2WPc1NxJDtzVLk0StBEbMz’, u’available_markets’: []}, u’name’: u’Together - Chris Gold Edit’, u’uri’: u’spotify:track:1pgWrCu36Rd221g0u4GTWo’, u’external_urls’: {u’spotify’: u’https://open.spotify.com/track/1pgWrCu36Rd221g0u4GTWo’}, u’popularity’: 57, u’explicit’: False, u’preview_url’: None, u’track_number’: 2, u’disc_number’: 1, u’href’: u’https://api.spotify.com/v1/tracks/1pgWrCu36Rd221g0u4GTWo’, u’artists’: [{u’name’: u’Klaas’, u’external_urls’: {u’spotify’: u’https://open.spotify.com/artist/25sJFKMqDENdsTF7zRXoif’}, u’uri’: u’spotify:artist:25sJFKMqDENdsTF7zRXoif’, u’href’: u’https://api.spotify.com/v1/artists/25sJFKMqDENdsTF7zRXoif’, u’type’: u’artist’, u’id’: u’25sJFKMqDENdsTF7zRXoif’}, {u’name’: u’Chris Gold’, u’external_urls’: {u’spotify’: u’https://open.spotify.com/artist/3k2ntYCRYwchneYCxhOZFN’}, u’uri’: u’spotify:artist:3k2ntYCRYwchneYCxhOZFN’, u’href’: u’https://api.spotify.com/v1/artists/3k2ntYCRYwchneYCxhOZFN’, u’type’: u’artist’, u’id’: u’3k2ntYCRYwchneYCxhOZFN’}], u’duration_ms’: 178064, u’external_ids’: {u’isrc’: u’DEMA61700402’}, u’type’: u’track’, u’id’: u’1pgWrCu36Rd221g0u4GTWo’, u’available_markets’: []}, u’context’: {u’href’: u’https://api.spotify.com/v1/users/spotify/playlists/37i9dQZF1DXcZDD7cfEKhW’, u’type’: u’playlist’, u’uri’: u’spotify:user:spotify:playlist:37i9dQZF1DXcZDD7cfEKhW’, u’external_urls’: {u’spotify’: u’http://open.spotify.com/user/spotify/playlist/37i9dQZF1DXcZDD7cfEKhW’}}, u’device’: {u’name’: u’L5415’, u’volume_percent’: 78, u’is_active’: True, u’is_restricted’: False, u’type’: u’Computer’, u’id’: u’e7ffcf8ac5247647604d61a0ec759a0643ecfe4e’}, u’is_playing’: False}
Successfully posted state to OpenHab: spotify_current_track = Together - Chris Gold Edit
Successfully posted state to OpenHab: spotify_current_artist = Klaas
Successfully posted state to OpenHab: spotify_current_cover = https://i.scdn.co/image/62dda60ccc3ae36a3bd63248d1dbdfc779eb9923
Successfully posted state to OpenHab: spotify_current_duration = 178064
Successfully posted state to OpenHab: spotify_current_progress = 32130
Successfully posted state to OpenHab: spotify_current_playing = OFF
Successfully posted state to OpenHab: spotify_current_device = L5415
Successfully posted state to OpenHab: spotify_current_volume = 78
Successfully posted state to OpenHab: spotify_current_context_uri = spotify:user:spotify:playlist:37i9dQZF1DXcZDD7cfEKhW
Successfully posted state to OpenHab: spotify_current_device_id = e7ffcf8ac5247647604d61a0ec759a0643ecfe4e
Successfully posted state to OpenHab: spotify_current_progress_percent = 18.04
-> Success
Successfully posted state to OpenHab: spotify_lastConnectionDateTime = 2017-10-04T09:36:59+0000
Done in 0.796753883362 seconds

Everything is successful… but spotify doens’t start playing.
I have the spotify.rules in the rules folder

The only thing I should mention is my setup: I’m running on a synology NAS. Only thing I had to change was the directory from /etc/openhab2/scripts/spotify.py to /volume1/@appstore/openHAB2/conf/scripts.spotify.py

I’ve changed this in the spotify.rules file

If I look at above log, seems I get a 403 error, which I believe is a ‘forbidden’ error. I guess I’m not having the correct rights to execute the commands?


(Andrew Pawelski) #99

Can anyone tell me if I need to be running the script continuously to get the state change of Spotify starting to play? I’m guessing so but would like to hear from people successfully running


(Florian) #100

Yes, @Andrew_Pawelski, spotify states are only updated through spotify.py. So you will constantly have to trigger the script. You can do this within your spotify.rules with a cron expression. I am currently only pulling twice a minute 0/30 * * ? * * * and hitting the update button when I want to get the current state (this could also archived with Page Visibility API dont’t you think @pmpkk? )

I am waiting for spotify to release a webook or some kind of aparatus that sends realtime updates to the client.

P.S.: This is what my spotify.rules currently looks like:

rule "Spotify run script"
when
	Time cron "0/30 * * * * ? *" or
	Item spotify_forceupadte received update
then		
	val resp =  executeCommandLine("/usr/bin/python /etc/openhab2/scripts/spotify.py", 5000)
	logInfo("Spotify", resp)
end


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

(Andrew Pawelski) #101

how much data does that use every 30 seconds?


(Andrew Pawelski) #102

Has anyone seen the spotify unofficial binding? Wondering if this binding is “aware”?


(Dries) #103

I wanted to ask the same question. I see some interaction on this forum on the spotify.py solution, but not on the Spotify Binding. How do both compare? From an architectural perspective, I prefer a binding instead of a py-script. But the py-script seems to be more mature (and more used).

Anyone else cares to share their experience?


(Jonas) #104

Hi!
I am making some progress!
It now works really nice but i am still not able to send commands.
Is this even possible?
The commands are labeled with “current” -> current playing for instance.
Can i fire play/pause?
If yes, how? :slight_smile:
Thank you!!


(Florian) #105

@Jonas88, the best way to learn this spotify integration is to look at the code of the custom ground floor widget in the matching matrix theme. It’s also from @pmpkk (you should load the widget and then use habpanel’s build in widget code editor to examine the relevant code.)

If you do not want to use a custom widget but directly take habpanel widgets you would have to use a “button” widget and set it to fire (alternating) events to item spotify_action. See this image:

However I would suggest that to use a custom widget, for example the Music Control Widget, and connect it to the right items (spotify_action, etc.).


(Jonas) #106

hi!
I’ll look at the code, thank you :slight_smile:
however - i can’t see your snapshot.


(Jonas) #107

Ok, i am feeling dumb right now. i just didn’t find it.
For the other guys:
just send commands to the spotify_action item like:
play pause etc … you don’t even need to code, you can just use a button widget for example.

Thank you very much! :slight_smile:


(Jonas) #108

Only “problem” i got now is that my log is growing like crazy because i call the script quite frequently … i did manage to get rid of the status update but if spotify is running the item change (current time) is getting mad. i tried to find a solution to exclude a single item from the log but it doesn’t seem to be that easy …


(Patrick) #109

You could remove the print statements in the python scripts to reduce the log output.