Binding for Spotify and Spotify Connect Devices

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.

Configuring the binding

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.

Create Spotify Application

Follow the instructions in the tutorial at https://developer.spotify.com/web-api/tutorial/. Follow instructions under:

  1. Setting Up Your Account
  2. Registering Your Application
  • Step 6: entering Website information can be skipped.
  • Step 7: setting Redirect URIs is very important

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 Authorization Servlet on your server.

For example if you run your openHAB server on http://openhabianpi:8080 you should add http://openhabianpi:8080/connectspotify as the redirect URIs.

This is important since the authorize process with Spotify takes place using your client web browser and Spotify will have to know the right URLs to your openHAB server for the authorization to be completed. When you have authorized 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.

Configure binding

  1. Install the binding and make sure the Spotify Binding is listed on your server
  2. Complete the Spotify Application Registation if you have not already done so, see above.
  3. Make sure you have your Spotify Application Client ID and Client Secret identities available.
  4. Go to to your preferred openHAB admin UI and add a new Thing. Select the "Spotify Player Bridge". Choose new Id for the player, unless you like the generated one, put in the Client ID and Client Secret from the Spotify Application registration in their respective fields of the bridge configuration. You can leave the refreshPeriod as is. Save the bridge.
  5. The bridge thing will stay in state INITIALIZING and eventually go OFFLINE - this is fine. You have to authorize this bridge with Spotify.
  6. Go to the authorization page of your server. http://<your openHAB address>:8080/connectspotify. Your newly added bridge should be listed there.
  7. Press the "Authorize Player" button. This will take you either to the login page of Spotify or directly to the authorization screen. Login and/or authorize the application. If the Redirect URIs are correct you will be returned and the entry should show you are authorized with you Spotify user name/id. If not, go back to your Spotify Application and ensure you have the right Redirect URIs.
  8. The binding will be updated with a refresh token and go ONLINE. The refresh token is used to re-authorize the bridge with Spotify Connect Web API whenever required.

Now that you have got your bridge ONLINE it is time to discover your devices! Go to Paper UI 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 authorization procedure can be reinitiated from step 6 whenever required. You can force reinitialization by authorize on the connect Spotify page if the page would show it as authorized. This will reset the refresh token.

The following configuration options are available on the Spotify Bridge player:

Parameter Description
clientId This is the Client ID provided by Spotify when you add a new Application for openHAB to your Spotify Account. Go to https://developer.spotify.com/ (Required)
clientSecret This is the Client Secret provided by Spotify when you add a new Application for openHAB to your Spotify Account. (Required)
refreshPeriod This is the frequency of the polling requests to the Spotify Connect Web API in seconds.

The following configuration option is available on the Spotify device:

Parameter Description
id This is the device ID provided by Spotify (Required).

Supported Things

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. A Spotify web player in a browser is only available as long as the page is open. It will get a unique id for that session. If you close the page it will be gone. Opening a new web player will result in a new id. Some devices will not be visible (i.e. Chrome casts) when they are not active. They go into a sleep mode and are not visible through the Spotify Web API. The binding will them show as GONE.

Discovery

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.

Channels

Bridge / Player

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 Selection Read-only Name of the currently active Connect Device, set the device id to transfer play to that it
deviceVolume Dimmer Read-write Get or set the active Connect Device volume.
deviceShuffle Switch Read-write Turn on/off shuffle play on the active device.
trackPlay String Read-write Set which music to play on the active device. This channel accepts Spotify URIs and URLs.
trackPlayer Player Read-write The Player Control of the active device. PLAY/PAUSE/NEXT/PREVIOUS commands.
trackRepeat String Read-only 'track' repeats the current track. 'context' repeats the current context. 'off' turns repeat off.
trackName String Read-only The name of the currently played track.
trackDuration String Read-only The duration (m:ss) of the currently played track.
trackDurationMs Number Read-only The duration of the currently played track in milliseconds. This is updated every second.
trackProgress String Read-only The Progress (m:ss) of the currently played track. This is updated every second.
trackProgressMs Number Read-only The Progress of the currently played track in milliseconds.
playlist Selection Read-only This channel will be populated with the users playlists. Set the playlist id to start.
albumName String Read-only Album Name of the currently played track.
albumImage RawType Read-only Album Image of the currently played track.
artistName String Read-only Artist Name of the currently played track.

Note: The deviceName and playlist channels are Selection channels. They will dynamically be populated with the user specific devices and playlists.EXCEPTION_MESSAGE_CLOSED

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. | | trackId | String | Read-only | Track Id of the currently played track. | | trackHref | String | Read-only | Track URL 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 | Number | 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 URL 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 URL of the currently played track. | | artistType | String | Read-only | Artist Type of the currently played track. |

Devices

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.

Full Example

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.things:

Bridge spotify:player:user1 "Me" [clientId="<your client id>", clientSecret="<your client secret>"] {
  Things:
    device device1 "Device 1" [id="<spotify device id>"]
    device device2 "Device 2" [id="<spotify device id>"]
}

spotify.items:

Player device1Player  {channel="spotify:device:user1:device1:devicePlayer"}
Player device2Player  {channel="spotify:device:user1:device2:devicePlayer"}

spotify.sitemap

sitemap spotify label="Spotify Sitemap" {

  Frame label="Spotify Player Info" {
    Selection item=spotify_player_user1_deviceName label="Active device [%]"
    Player item="spotify_player_user1_trackPlayer
    Text item=spotify_player_user1_deviceShuffle label="Currently Player shuffle mode: [%s]"
    Text item=spotify_player_user1_trackRepeat label="Currently Player repeat 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]"
    Selection item=spotify_player_user1_trackPlay label="Playlist" icon="music"
  }

  Frame label="My Spotify Device 1" {
    Text item=spotify_device_user1_device1_deviceName label="Device Name [%s]"
    Player item=device1Player
    Slider item=spotify_device_user1_device1_deviceVolume
    Switch item=spotify_device_user1_device1_deviceShuffle
  }

   Frame label="My Spotify Device 2" {
    Text item=spotify_device_user1_device2_deviceName label="Device Name [%s]"
    Player item=device2Player
    Slider item=spotify_device_user1_device2_deviceVolume
    Switch item=spotify_device_user1_device2_deviceShuffle
  }
}

Binding model and Spotify Web API

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