Idea for Binding: Spotify Connect binding

Tags: #<Tag:0x00007f0142882fd0> #<Tag:0x00007f0142882e40>

(Gad Ofir) #63

Hi i have issue with step 6 on github

  1. so i have the bdining installed i can see it in paper UI
  2. i have secert and clinet id
  3. i added a thing with the above
:24:22.977 [INFO ] [smarthome.event.ItemStateChangedEvent] - infoDate changed from 2018-09-23T14:21:22.976+0300 to 2018-09-23T14:24:22.977+0300
14:24:44.854 [ERROR] [est.core.internal.thing.ThingResource] - Exception during HTTP PUT request for update config at 'things/spotify:player:SpotifyBridge/config'
java.lang.IllegalStateException: Thing with UID spotify:player:SpotifyBridge has no handler attached.
        at org.eclipse.smarthome.core.thing.internal.ThingRegistryImpl.

can someone please tell me how to add this to the item file?
i dont like doing it from UI…

OH 2.3
Windows run
using this guide

(Masssssy) #64

I have done some experimenting with this today and come to a few conclusions. The Chromecast issue can be solved by hosting a x86 Android machine, run Tasker on that and then trigger that virtual tablet to cast to the correct device. The binding will then automatically update current device etc. This should be possible to automate 100% from OpenHAB calls to Tasker on this “virtual tablet”.

It’s not very pretty but it seems there is no support for anything better by Spotify/Google as of now.

Update: It is possible to ask Google assistant to “play music on the tv” to trigger the Spotify Chromecast device to wake up.

(Dennis) #65

Hi! Kudos for all your work.
I think there is a bug with the binding, so i explain what i want to do :).
I have a Amazon Echo infrastructure at home, but dont like the sound. I have a parallel Soundtouch (Bose) Infrastructure and i would like to hear the music with the soundtouch infrastructure, although triggering natural (without skills) commands to the echo in the room. (i.e. Alexa, play music).
Therefore my idea is: Track the Player State and afterwards check which device plays. Detect the corresponding Soundtouch Device and transfer the current play to the soundtouch device.

The Problem is:
The following doesnt work:
“Also if you want to transfer playing to another device you can simply start play on the other device in openHAB (you have to add that device as thing and start play on it). It will then start playing the song already playing on the other device.”

When i press the play button on another device although there is already a device playing, simply nothing happens.

Therefore i have made an (i dislike it because it could be all done with this binding) own solution by making a curl request to switch to the device( spotify api supports it-> Transfer a User’s Playback in Spotify Api Console).Great thanks to that, because i can use the authorizationtoken from the related item, to make my curl request :slight_smile:
Do you think you can fix this?

Another question:

Do you have an example things file for the binding? This way we could choose whether we want to add things via paperui or manually as file (my preferred way)

best regards

(Gunfrem) #66

I’ve got the same problem. The controlls of the device don’t work. If I start music via my mobile on a connected device, I can pause, play, change playlist via the bridge, but the controlls of the devices don’t work. Also switching to an other device does not work.

Here my spotify items and sitemap:


Player SpotifyPlayer_Bridge_Control "Spotify Control" (GF_LivingRoom_Spotify, gSpotify) {channel="spotify:player:393b0003:trackPlayer"}
Switch SpotifyPlayer_Bridge_Shuffle "Shuffle" (GF_LivingRoom_Spotify, gSpotify)  {channel="spotify:player:393b0003:deviceShuffle"}
Dimmer SpotifyPlayer_Bridge_Volume "Volume" (GF_LivingRoom_Spotify, gSpotify)   {channel="spotify:player:393b0003:deviceVolume"}
String SpotifyPlayer_Bridge_Title "Title [%s]" (GF_LivingRoom_Spotify, gSpotify)         {channel="spotify:player:393b0003:trackName"}
String SpotifyPlayer_Bridge_Interpret "Interpret [%s]" (GF_LivingRoom_Spotify, gSpotify)         {channel="spotify:player:393b0003:artistName"}
String SpotifyPlayer_Bridge_Album "Album [%s]"  (GF_LivingRoom_Spotify, gSpotify)       {channel="spotify:player:393b0003:albumName"}
String SpotifyPlayer_Bridge_Duration "Duration [%s]"  (GF_LivingRoom_Spotify, gSpotify) {channel="spotify:player:393b0003:trackDuration"}
String SpotifyPlayer_Bridge_Progress "Progress [%s]"  (GF_LivingRoom_Spotify, gSpotify) {channel="spotify:player:393b0003:trackProgress"}
String SpotifyPlayer_Bridge_TrackPlay "TackPlay" (GF_LivingRoom_Spotify, gSpotify)      {channel="spotify:player:393b0003:trackPlay"}


String SpotifyPlayer_HeosWZ_TrackPlay "TackPlay" (GF_LivingRoom_Spotify, gSpotify)      {channel="spotify:device:393b0003:19c9:trackPlay"}
Player SpotifyPlayer_HeosWZ_DevicePlayer "Player" (GF_LivingRoom_Spotify, gSpotify) {channel="spotify:device:393b0003:19c9:devicePlayer"}
String SpotifyPlayer_HeosWZ_DeviceName "Name" (GF_LivingRoom_Spotify, gSpotify) {channel="spotify:device:393b0003:19c9:deviceName"}

DEVICE Google Home

String SpotifyPlayer_GoogleHomeWohnzimmer_TrackPlay "TackPlay" (GF_LivingRoom_Spotify, gSpotify {channel="spotify:device:393b0003:d47a:trackPlay"}
Player SpotifyPlayer_GoogleHomeWohnzimmer_DevicePlayer "Player" (GF_LivingRoom_Spotify, gSpotify) {channel="spotify:device:393b0003:d47a:devicePlayer"}
String SpotifyPlayer_GoogleHomeWohnzimmer_DeviceName "Name" (GF_LivingRoom_Spotify, gSpotify) {channel="spotify:device:393b0003:d47a:deviceName"}

Sitemap snippit:

        Frame label="Spotify Bridge" {
            Default item=SpotifyPlayer_Bridge_Control
            Default item=SpotifyPlayer_Bridge_Shuffle
            Default item=SpotifyPlayer_Bridge_Volume
            Default item=SpotifyPlayer_Bridge_Title
            Default item=SpotifyPlayer_Bridge_Interpret
            Default item=SpotifyPlayer_Bridge_Album
            Default item=SpotifyPlayer_Bridge_Duration
            Default item=SpotifyPlayer_Bridge_Progress
            Selection item=SpotifyPlayer_Bridge_TrackPlay label="Playlist Spotify Heos" icon="music" mappings=["spotify:user:1121824159:playlist:7jzBjCIY8VSwshWJxqU17Z"="Gartenparty","spotify:user:europa.kinderprogramm:playlist:5e6XxV3vhHhdfqcjXScH8o"="3 ???"]
        Frame label="Spotify auf Heos WZ" {
            Default item=SpotifyPlayer_HeosWZ_DeviceName
            Default item=SpotifyPlayer_HeosWZ_DevicePlayer
            Selection item=SpotifyPlayer_HeosWZ_TrackPlay label="Playlist Spotify Heos" icon="music" mappings=["spotify:user:1121824159:playlist:7jzBjCIY8VSwshWJxqU17Z"="Gartenparty","spotify:user:europa.kinderprogramm:playlist:5e6XxV3vhHhdfqcjXScH8o"="3 ???"]
        Frame label="Spotify auf GoogleHome Wohnzimmer" {
            Default item=SpotifyPlayer_GoogleHomeWohnzimmer_DeviceName
            Default item=SpotifyPlayer_GoogleHomeWohnzimmer_DevicePlayer
            Selection item=SpotifyPlayer_GoogleHomeWohnzimmer_TrackPlay label="Playlist Spotify Heos" icon="music" mappings=["spotify:user:1121824159:playlist:7jzBjCIY8VSwshWJxqU17Z"="Gartenparty","spotify:user:europa.kinderprogramm:playlist:5e6XxV3vhHhdfqcjXScH8o"="3 ???"]

(Hilbrand Bouwkamp) #67

I’ve updated the Spotify binding jar with several Fixes:

  • Fixed playing tracks: it now detects if it’s a track or other (e.g. playlist, etc).
  • Fixed device id: it’s now a configuration property so it can be used to configure the device manually. (prior it was not possible to manually configure a device)
  • Renamed channel devicePlay to devicePlayer since that better reflects the name.
  • Removed channel deviceId from device thing: it’s already available as a property, so no need to have it as a channel.
  • Improved readme: added manual things file configuration example.
  • The dashboard tile has been removed. There is still some work in progress on the authorization part to bring it in line with other similar oauth2 usages in openHAB, so this part is expected to be changing. This won’t affect the working of the binding, only the way the refreshtoken is obtained.

If you manually configured the bridge thing you need to set the refreshToken in the configuration. You can see this refreshToken after you have authorized the binding in Paper UI in edit mode of the bridge. If you don’t add the refreshToken to your configuration you need to re-authorize after each restart (or for example if you update the binding jar) because with manual configuration the refreshToken is reset on init if not set manually. When you have added the bridge via PaperUI this won’t happen.

(Dennis) #68

Hi Hilbrand!

Thanks for the update :).

From my understanding this does not address the problem i have mentioned, does it?

Best regards

(Hilbrand Bouwkamp) #69

I could not see from your comment if you had manually created the things or via Paper UI. If you manually created the things you could not transfer playing, that did not work. That has been fixed. It should now work if you play on another device player it should start playing on the other device. It doesn’t call the specific transfer api, but simply calls play with a device id. This gives the same result. Did you have manual configured things? and if so does it now works for you?

(Dennis) #70

I Created my things via Paperui because i failed with creating the things via things file.
I Created my items in item file but later i tried to do all this via paperui with the same result: i can play and pause the current playing device, but nothing happens when i press play on another device. i will test it and reply you later :slight_smile:

(Hilbrand Bouwkamp) #71

For configuration information look in the readme from the pull request: . That url will always contain the latest information (until the binding is merged) the URL you referred to is outdated and will not be updated. In fact that whole repository is outdated and is not updated anymore.

(Dennis) #72

Just tried to create manual things with the following jar:

The bridge is created successfully, while the devices arent. the ID is not passed correctly.
When i add the things from Paperui, they are online.

May you provide a new .jar which contains all your changes as im not the born developer to compile by myself in a minute?:slight_smile:
I will test the behaviour of playing tracks by another device with the new version.

Best regards

(Hilbrand Bouwkamp) #73

The jar contains all the changes. So that should not be the problem :smile: Can you provide your configuration?Maybe a typo? of does it log any error?

(Dennis) #74

Oh okay :).

Thats my things file. I masked the sensitive Data. My openhab.log does not show any syntax errors. The things are created in Paperui, but without ID.

Bridge spotify:player:anonym "anonym" [clientId="asdfg", clientSecret="asdfg", refreshToken="asdfg"]
Thing device 3b01 "Soundtouch10" [id="asdfg"]
//Thing device f4f8 "Soundtouch 300 Wohnzimmer Spotify" [id="ijklm"]

Some additional info: The ID exactly matches the one i got by adding the thing via paperui and checked the property :slight_smile:

Best regards

(Hilbrand Bouwkamp) #75

Hmm. It works on my machine :slight_smile: Maybe some caching of the old jar. In Paper UI can you edit the id of the device Thing? If not you would still have the old version loaded. (The jar should be 75443 bytes) You could disable the spotify things in the things file (if you haven’t tried it) and wait till they are removed, and then enable them again Or give the thing another id for example something else instead of the 3b01 Otherwise I’m not sure what causes this problem or it might be a different openHAB version. I’m running a 2.4 snapshot.

(Dennis) #76

Indeed i used the old version! With the new one and the things file i already sent, i get a NPE (the bridge stays offline). in Trace mode i can see that spotify API is still reachable, because it obtained a new refreshtoken:

[INFO ] [nternal.handler.SpotifyBridgeHandler] - Unexpected error during polling status, please report if this keeps ocurring:
java.lang.NullPointerException: null
        at org.openhab.binding.spotify.internal.handler.SpotifyDeviceHandler.updateDeviceStatus( ~[?:?]
        at org.openhab.binding.spotify.internal.handler.SpotifyBridgeHandler.lambda$5( ~[?:?]
        at$1MatchSink.accept( ~[?:?]
        at java.util.ArrayList$ArrayListSpliterator.tryAdvance( ~[?:?]
        at ~[?:?]
        at ~[?:?]
        at ~[?:?]
        at ~[?:?]
        at$MatchOp.evaluateSequential( ~[?:?]
        at$MatchOp.evaluateSequential( ~[?:?]
        at ~[?:?]
        at ~[?:?]
        at org.openhab.binding.spotify.internal.handler.SpotifyBridgeHandler.lambda$4( ~[?:?]
        at$2$1.accept( [?:?]
        at java.util.ArrayList$ArrayListSpliterator.forEachRemaining( [?:?]
        at [?:?]
        at [?:?]
        at$ForEachOp.evaluateSequential( [?:?]
        at$ForEachOp$OfRef.evaluateSequential( [?:?]
        at [?:?]
        at [?:?]
        at org.openhab.binding.spotify.internal.handler.SpotifyBridgeHandler.updateDevicesStatus( [241:org.openhab.binding.spotify:]
        at org.openhab.binding.spotify.internal.handler.SpotifyBridgeHandler.pollStatus( [241:org.openhab.binding.spotify:]
        at org.openhab.binding.spotify.internal.handler.SpotifyBridgeHandler.initialize( [241:org.openhab.binding.spotify:]
        at sun.reflect.GeneratedMethodAccessor75.invoke(Unknown Source) ~[?:?]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke( ~[?:?]
        at java.lang.reflect.Method.invoke( ~[?:?]
        at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect( [94:org.eclipse.smarthome.core:0.10.0.oh240M3]
        at [94:org.eclipse.smarthome.core:0.10.0.oh240M3]
        at [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker( [?:?]
        at java.util.concurrent.ThreadPoolExecutor$ [?:?]
        at [?:?]

any hints?

(Hilbrand Bouwkamp) #77

I think this can happen if you have a thing that was created with the old jar and is now loaded with the new jar. In that case internally the id is null (Because it was previously set in another place). So please remove all previously added/created things (possible only need for the once created via Paper UI).

(Dennis) #78

Ich have done that by moving the Things File and moving this one Back. Should ne enough,shouldnt IT?ah okay ich understood. Letzte me try:)

(Dennis) #79

OK. Update:
Things and items working .but play in another device does not work. Tolles reproduce: play Something in Spotify app in Smartphone and send to another device via Spotify Connect in App.
Then click play in another device via paperui. Result: IT changes icon to play and immediately back to pause. It does not start playing the chosen track in MS device selected in paperui. Instead IT Plays in the device chosen in Spotify app in Smartphone. In trace log i cant see the request that normally is performed when pressing play

(Hilbrand Bouwkamp) #80

I’ve updated the Spotify Binding jar. It contains an improvement with transferring playing to another device. This will improve start playing on another device to be more reliable. (Thanks goes to @Der_Gute for helping test this improvement). If you have an earlier or older version of the jar installed and you might need to recreate the things and/or clear your cache in order it work again.

(Niklas H.) #81

Hi, i’ve updated to the latest version.

Some remarks:
After a restart of openhab the bridge and things stay offline, but everything works as expected.
The Authorization need to be done only once?

Could you provide a Example .thing file?
The refreshTokes ia automatically updated by the binding?

A minor issue is, after I play a playlist, the ShuffleMode is always set back to OFF.

Thank you :slight_smile:

PS: In combnation with the Allplay binding, i could combine players for multimroom audio and change between a Stream and Spotify. :+1:

(Hilbrand Bouwkamp) #82

After a restart of openhab the bridge and things stay offline, but everything works as expected.
The Authorization need to be done only once?

Did you create the brigde/thing with Paper UI or via a things file? If created via Paper UI then the authorization should have to be done only once. If not let me know. If created via things file you need to set the refreshToken in the things file otherwise you need to authorize after each restart, or even each time the things file is updated.

Could you provide a Example .thing file?

See the README. (Note, as mentioned above add the refreshToken to the bridge configuration to avoid having to reauthorize, this information is not yet clearly mentioned in the readme)

The refreshTokes ia automatically updated by the binding?

No only when you have clicked on authorize in the connectspotify page is it set once. After that only the accessToken is set automatically. That’s why you need to set the refreshToken in a things file (if you use a things file). If for some reason the refreshToken becomes invalid you need to reauthorize it via the connectspotify page.

A minor issue is, after I play a playlist, the ShuffleMode is always set back to OFF.

If the SuffleMode is set back to off this might be a something the Spotify Api does by itself. The binding just updates to the state as reported by Spotify. You might see if there is any information on this on the Spotify forums.