This binding implements a bridge to the Spotify Player Web API and makes it possible to discover Spotify Connect Devices available on your Spotify Premium account.
The binding requires you to register an Application with Spotify Web API at https://developer.spotify.com - this will get you a set of Client ID and Client Secret parameters to be used by your binding configuration.
Follow the instructions in the tutorial at https://developer.spotify.com/web-api/tutorial/. Skip into and follow instructions under:
When registering your new Spotify Application for openHAB Spotify Bridge you have to specify the allowed "Redirect URIs" aka white-listed addresses. Here you have to specify the URL to the Bridge Authentication Servlet on your server.
If you run your openHAB server on "http://openhab.mydomain.com:8080" you should add "http://openhab.mydomain.com:8080/connectspotify/authorize" to the Redirect URIs.
This is important since the authentication process with Spotify takes place using your client web browser and Spotify will have to know the right URL to your local openHAB server for the authentication to be completed. When you have authenticated with Spotify, this Redirect URI is where authorization tokens for your openHAB Spotify Brigde will be sent and they have to be received by the servlet on "/connectspotify".
Now that you have got your bridge ONLINE it is time to discover your devices! Go to openHAB Inbox and search for Spotify Connect Devices. Any device currently available on your account should show up immediately.
If no devices show up you can start Spotify App on your PC/Mac/iOS/Android and start playing on your devices as you run discovery. This should make any Spotify Connect devices and Spotify Apps discoverable. You may have to trigger the openHAB discovery several times as bridge will only find active devices known by the Spotify Web API at the time the discovery is triggered.
Should the bridge configuration be broken for any reason, the authentication procedure can be reinitiated from step 6 whenever required. You can force reinitialization simply by removing the refreshToken of the bridge configuration and save. Make sure you leave Client ID and Client Secret intact and correct. Press save.
If you get a browser message such as this when you try to authorize:
INVALID_CLIENT: Invalid client
Then you have to check your Client ID and Client Secret settings of the bridge and make sure you have the same values as given by the Spotify Application. This message means that Spotify cannot find a matching client configuration for the bridge you are trying to authorize.
All Spotify Connect capable devices should be discoverable through this binding. If you can control them from Spotify Player app on your PC/Mac/iPhone/Android/xxx you should be able to add it as a thing. Some devices can be restricted and not available for playing. The bridge will make these available in the discovery of devices, but they will never be ONLINE.
As long as Spotify Connect devices are available in the context of the user account configured with the bridge/bridges they should show up whenever you initiate discovery of things.
If no devices are showing up, try to connect to the device(s) from your smartphone or computer to make sure the device(s) are in use by your user account.
The discovery of devices in the Spotify Web API is based on what is known by Spotify. There is difference from e.g. smartphones and computers which can discover devices on the local network - the Web API cannot do that. It only knows about a device if your account is currently associated with the device.
The channels on the bridge are the ones used to both control the active device and get details of currently playing music on the Spotify Account associated with the bridge.
Common Channels:
Channel Type ID | Item Type | Read/Write | Description |
---|---|---|---|
deviceName | String | Read-only | Name of the currently active Connect Device |
deviceVolume | Dimmer | Read-write | Get or set the active Connect Device volume |
trackPlay | String | Read-write | Set which music to play on the active device. This channel accepts Spotify URIs and Hrefs. |
trackPlayer | Player | Read-write | The Player Control of the active device. Play/Pause/Next/Previous commands. |
trackRepeat | String | Read-only | The current device Repeat Mode setting |
trackShuffle | Switch | Read-only | The current device Shuffle setting |
trackName | String | Read-only | The name of the currently played track |
trackDuration | String | Read-only | The duration (m:ss) of the currently played track |
trackProgress | String | Read-only | The Progress (m:ss) of the currently played track. This is updated as the refreshPeriod of the Bridge. |
albumName | String | Read-only | Album Name of the currently played track |
artistName | String | Read-only | Artist Name of the currently played track |
Advanced Channels:
Channel Type ID | Item Type | Read/Write | Description |
---|---|---|---|
accessToken | String | Read-only | The current accessToken used in communication with Web API. This can be used in client-side scripting towards the Web API if you would like to maintain your playlists etc. |
customRequest | String | Read-write | Assign an WebAPI GET url and the JSON response will be available in the customReply channel |
customReply | String | Read-only | Holds the result from latest WebAPI GET request in customRequest channel |
trackId | String | Read-only | Track Id of the currently played track. |
trackHref | String | Read-only | Track Href of the currently played track. |
trackUri | String | Read-only | Track Uri of the currently played track. |
trackType | String | Read-only | Type of the currently played track. |
trackNumber | String | Read-only | Number of the track on the album/record. |
trackDiscNumber | String | Read-only | Disc Number of the track on the album/record. |
trackPopularity | Dimmer | Read-only | Currently played track popularity |
albumId | String | Read-only | Album Id of the currently played track. |
albumUri | String | Read-only | Album Uri of the currently played track. |
albumHref | String | Read-only | Album Href of the currently played track. |
albumType | String | Read-only | Album Type of the currently played track. |
artistId | String | Read-only | Artist Id of the currently played track. |
artistUri | String | Read-only | Artist Uri of the currently played track. |
artistHref | String | Read-only | Artist Href of the currently played track. |
artistType | String | Read-only | Artist Type of the currently played track. |
There are channels on the devices that seemingly overlap those of the bridge. The difference between these overlapping channels are that the device channels always acts in the context of the particular device. E.g. if you assign a playlist to the trackPlay channel of the device, the playing of that playlist will be activated on that particular device. Assigning a playlist to the trackPlay channel of the bridge will start playing the list on whatever device is active.
Common Channels:
Channel Type ID | Item Type | Read/Write | Description |
---|---|---|---|
trackPlay | String | Read-write | Track to play on the device. Assigning a track, playlist, artist etc will activate the device and make it the currently playing device. |
deviceName | String | Read-only | Name of the device |
deviceVolume | Dimmer | Read-write | Volume setting for the device |
devicePlayer | Player | Read-write | Player Control of the device |
deviceShuffle | Switch | Read-write | Turn on/off shuffle play |
Advanced Channels:
Channel Type ID | Item Type | Read/Write | Description |
---|---|---|---|
deviceId | String | Read-only | The Spotify Connect device Id. |
deviceType | String | Read-only | The type of device e.g. Speaker, Smartphone |
deviceActive | Switch | Read-only | Indicated if the device is active or not. Should be the same as Thing status ONLINE/OFFLINE |
deviceRestricted | Switch | Read-only | Indicates if this device allows to be controlled by the API or not. If restricted it cannot be controlled |
This is a roughly what I have used to test the binding in development. Auto created items, and I added separate items in files for the Player channel. Don't know how to set it up in sitemap under basicui. So I mapped a Switch to the Player channel and referenced that from the sitemap to start/stop playing. The channel supports stepping tracks forward/backward.
In this example there is a bridge configured with Thing ID user1 and illustrating that the bridge is authorized to play in the context of the Spotify user account user1.
spotify.items:
Switch device1Player {channel="spotify:device:user1:3b4...ed4:devicePlayer"}
Switch device2Player {channel="spotify:device:user1:abc...123:devicePlayer"}
Switch TriggerAPICall
String SpotifyPlayerBridge_CustomRequest {channel="spotify:device:user1:3b4...ed4:customRequst"}
String SpotifyPlayerBridge_CustomReply {channel="spotify:device:user1:3b4...ed4:customReply"}
spotify.sitemap
sitemap spotify label="Spotify Sitemap" {
Frame label="Test custom WebAPI request" {
Switch item=TriggerAPICall
}
Frame label="Spotify Player Info" {
Text item=spotify_player_user1_trackRepeat label="Currently Player repeat mode: [%s]"
Text item=spotify_player_user1_trackShuffle label="Currently Player shuffle mode: [%s]"
Text item=spotify_player_user1_trackProgress label="Currently Played track progress: [%s]"
Text item=spotify_player_user1_trackDuration label="Currently Played track duration: [%s]"
Text item=spotify_player_user1_trackName label="Currently Played Track Name: [%s]"
Text item=spotify_player_user1_albumName label="Currently Played Album Name: [%s]"
Text item=spotify_player_user1_artistName label="Currently Played Artist Name: [%s]"
}
Frame label="My Spotify Device 1" {
Selection item=spotify_device_user1_3b4....ed4_trackPlay label="Playlist" icon="music" mappings=[
"spotify:user:spotify:playlist:37i9dQZF1DXdd3gw5QVjt9"="Morning Acoustic",
"spotify:user:spotify:playlist:37i9dQZEVXcMncpo9bdBsj"="Discover Weekly",
]
Text item=spotify_device_user1_3b4...ed4_deviceName label="Device Name [%s]"
Switch item=device1Player
Slider item=spotify_device_user1_3b4...ed4_deviceVolume
Switch item=spotify_device_user1_3b4...ed4_deviceShuffle
}
Frame label="My Spotify Device 2" {
Selection item=spotify_device_user1_abc....123_trackPlay label="Playlist" icon="music" mappings=[
"spotify:user:spotify:playlist:37i9dQZF1DXdd3gw5QVjt9"="Morning Acoustic",
"spotify:user:spotify:playlist:37i9dQZEVXcMncpo9bdBsj"="Discover Weekly",
]
Text item=spotify_device_user1_abc...123_deviceName label="Device Name [%s]"
Switch item=device2Player
Slider item=spotify_device_user1_abc...123_deviceVolume
Switch item=spotify_device_user1_abc...123_deviceShuffle
}
}
Spotify.rules
rule "Trigger call"
when
Item TriggerAPICall changed
then
sendCommand(SpotifyPlayerBridge_CustomRequest, "https://api.spotify.com/v1/me")
end
rule "Spotify Reply"
when
Item SpotifyPlayerBridge_CustomReply received update
then
logInfo("spotify", "SpotifyPlayerBridge_CustomReply: " + SpotifyPlayerBridge_CustomReply.state)
// For you to do: Parse JSON response and make use of it
end
The model of the binding is such that the bridge act as a player in the context of a specific user. All devices currently associated with the user account are available to control.
You can add multiple bridges to allow playing in the context of multiple Spotify user accounts. Therefor a device can exist multiple times - one time for every bridge configured. This is seen in the Thing ID which includes the name of the bridge it is bound to.
The Web API and its documentation does not imply a certain model and it can be argued whether the model chosen matches it or not. The current model is different in the sense that a Spotify Application only controls the active device and you then transfer playback to another available device. In this binding the model allows you to control any device discovered at any time if they are available. As soon as you press play, next, prev or assign a playlist to the device it will be activated.
At the time of writing, the Spotify Web API does not allow you to take over playing of a Spotify Connect device. This is different from what you see in smartphone app or the computer application. There you are able to actively take over playing of a device even if someone else is playing on it.