openHAB integration to Spotify Web Connect API (player)

nice script!
but im having troubles getting it working.
it shows the current title, track artwork, but i cant get the commands like play/pause/volume working.
always getting 403.
any ideas?
do i need spotify premium for it?

2018-01-04 14:52:43.728 [ome.event.ItemCommandEvent] - Item 'spotify_action' received command pause

2018-01-04 14:52:43.742 [vent.ItemStateChangedEvent] - spotify_action changed from next to pause

2018-01-04 14:52:44.610 [vent.ItemStateChangedEvent] - spotify_current_playing changed from ON to OFF

==> /var/log/openhab2/openhab.log <==

2018-01-04 14:52:44.634 [WARN ] [rest.core.internal.item.ItemResource] - Received HTTP PUT request at 'items/spotify_lastConnectionDateTime/state' with an invalid status value '2018-01-04T13:52:44+0000'.

2018-01-04 14:52:44.720 [INFO ] [lipse.smarthome.model.script.Spotify] - 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: Pause

Successfully posted state to OpenHab: spotify_current_playing = OFF

403

Error posting state to OpenHab: spotify_lastConnectionDateTime (HTTP Response State could not be parsed: 2018-01-04T13:52:44+0000)

Done in 0.4285800457 seconds
1 Like

Hello Guy´s
i need help at this step. I am a newbie in openhab
How and where do i check that the spotify_auth_code is set in OpenHab
How and where do i Set the REDIRECT_URI in spotify.py to the right value
How do i use the spotify.py

Thanks for the hard work, however i guess the spotify.py is for python 2x do any of you have the equivalent for python 3?

Never mind - bodged shuffle functionality myself

Shuffle on is:
/usr/bin/python /etc/openhab2/scripts/spotify.py shuffle

Shuffle off is:
/usr/bin/python /etc/openhab2/scripts/spotify.py shuffleoff

Didn’t checkout any repos - will wait for an official release:
Here is my current script

Thisis an edit of one of the scripts referenced above - very little of it is my own code.
All credit to @pmpkk

#
# Use the Spotify Web Connect API using credentials auth code and tokens.
#

import json
import requests
import time
import urlparse
import sys
from myopenhab import openhab
from myopenhab import mapValues
from myopenhab import getJSONValue


#   API Gateway
ACCOUNT_URL = 'https://accounts.spotify.com/api/token'
API_ROOT_URL = 'https://api.spotify.com/v1/me/player/'
REDIRECT_URI = 'http://192.168.0.131:8080/static/spotify-auth.html'
RAW_ROOT_URL = 'https://api.spotify.com/v1/me/'
class spotify(object):
    """
    
    A wrapper for the Spotify Web Connect API

    https://developer.spotify.com/web-api/web-api-connect-endpoint-reference/

    """
    def __init__(self):

        self.debug = False 
        self.oh = openhab()

        self.client_id = self.oh.getState('spotify_client_id')
        self.client_secret = self.oh.getState('spotify_client_secret')

        self.access_token = self.oh.getState('spotify_access_token')
        self.refresh_token = self.oh.getState('spotify_refresh_token')
        self.token_issued = self.oh.getState('spotify_token_issued')
        self.token_expiry = self.oh.getState('spotify_token_expiry')

        if(self.token_expiry == "NULL"):
            self.refreshCredentials()
        if (self.access_token == "NULL"):
            self.generateCredentials()
        else:
            if (time.time() > float(self.token_expiry)):
                self.refreshCredentials()
      
    def generateCredentials(self):
        """
        Generate auth and refresh token for the very first time.
        """

        #   Send OAuth payload to get access_token
        payload = { 'code':self.oh.getState('spotify_auth_code'), 'client_id':self.client_id, 'client_secret':self.client_secret, 'redirect_uri':REDIRECT_URI, 'grant_type':'authorization_code' }
        
        print "-- Calling Token Service for the first time"

        try:
            r = requests.post(ACCOUNT_URL, data=payload, allow_redirects=False)

            if (self.debug): print r.headers
            if (self.debug): print r.json()
            resp = r.json()

            if(r.status_code == 200):
                access_token = resp['access_token']
                refresh_token = resp['refresh_token']
                expires_in = resp['expires_in']

                #   Set and Save the access token
                self.access_token = access_token
                self.refresh_token = refresh_token
                self.token_expiry = time.time() + float(expires_in)
                self.token_issued = time.strftime("%Y-%m-%dT%H:%M:%S")
                self.saveCredentials()
            else:
                print " -> Error getting token:" + str(resp)

        except:
            print " -> Error getting token:" + str(sys.exc_info()[1])

    def refreshCredentials(self):
        """
        If previous auth token expired, get a new one with refresh token.
        """

        #   Send OAuth payload to get access_token
        payload = { 'refresh_token':self.refresh_token, 'client_id':self.client_id, 'client_secret':self.client_secret, 'redirect_uri':REDIRECT_URI, 'grant_type':'refresh_token' }
        
        print "-- Calling Token Refresh Service"

        try:
            r = requests.post(ACCOUNT_URL, data=payload, allow_redirects=False)

            if (self.debug): print r.headers
            if (self.debug): print r.json()
            resp = r.json()

            if(r.status_code == 200):
                access_token = resp['access_token']
                expires_in = resp['expires_in']
                if('refresh_token' in resp): 
                    refresh_token = resp['refresh_token']
                    self.refresh_token = refresh_token

                #   Set and Save the access token
                self.access_token = access_token
                self.token_expiry = time.time() + float(expires_in)
                self.token_issued = time.strftime("%Y-%m-%dT%H:%M:%S")
                self.saveCredentials()
            else:
                print " -> Error refreshing token:" + str(resp)

        except:
            print " -> Error refreshing token:" + str(sys.exc_info()[1])

    def saveCredentials(self):
        """
        Save current tokens to the openhab.
        """

        self.oh.sendCommand('spotify_access_token',self.access_token)
        self.oh.sendCommand('spotify_refresh_token',self.refresh_token)
        self.oh.sendCommand('spotify_token_expiry',self.token_expiry)
        self.oh.sendCommand('spotify_token_issued',self.token_issued)

    def call(self, path, mode=None, payload=None):
        """
        Call the API at the given path.
        """
        print path 
        if path == "playlists" :
            print "playlists"
        else:  
            path  = "player/" + path 
        print RAW_ROOT_URL + path
        if (time.time() > self.token_expiry):
            self.refreshCredentials()
        headers = {"Authorization": "Bearer " + self.access_token, "Content-Type": "application/json" }
        if mode == "POST":
            r = requests.post(RAW_ROOT_URL + path,  headers=headers, data=payload)
            if(r.status_code != 202):
                print r.content
            return r.status_code
        elif mode == "PUT":
            r = requests.put(RAW_ROOT_URL + path,  headers=headers, data=payload)
            if(r.status_code != 202):
                print r.content
            return r.status_code
        else:
            r = requests.get(RAW_ROOT_URL + path,  headers=headers)
            if(r.status_code != 202 and r.status_code != 200 and r.status_code != 201 ):
                print r.content
            return r.json()

    def update(self):
        """
        Get a current player state.
        """
        print "-- Calling Service: Update"
        try:
            resp = self.call("")
            if (self.debug): print resp
            if ('item' in resp):

                self.oh.sendCommand('spotify_current_track', getJSONValue(resp, ['item','name']))
                self.oh.sendCommand('spotify_current_artist', getJSONValue(resp, ['item', 'artists', 0, 'name']))
                self.oh.sendCommand('spotify_current_cover', getJSONValue(resp, ['item', 'album', 'images', 1, 'url']))
                self.oh.sendCommand('spotify_current_duration', getJSONValue(resp, ['item', 'duration_ms']))
                self.oh.sendCommand('spotify_current_progress', getJSONValue(resp, ['progress_ms']))
                self.oh.sendCommand('spotify_current_progress', getJSONValue(resp, ['progress_ms']))
                self.oh.sendCommand('spotify_current_playing', mapValues(getJSONValue(resp, ['is_playing']), { 'True': 'ON', 'False': 'OFF' }))
                self.oh.sendCommand('spotify_current_device', getJSONValue(resp, ['device', 'name']))
                self.oh.sendCommand('spotify_current_volume', getJSONValue(resp, ['device', 'volume_percent']))
                self.oh.sendCommand('spotify_current_device_id', getJSONValue(resp, ['device', 'id']))

                print " -> Success"
            else:
                print " -> Item node missing from response :("
        except:
            print " -> Failure: ", sys.exc_info()[0]
            resp = ""

        return resp

    def volumeAdjust(self, adjustment = None):
        """
        Volume adjust by adjustment
        """
        print "-- Calling Service: Volume Up"
        try:
            vol = int(self.oh.getState('spotify_current_volume'))
            vol = int(round(vol/10)*10 + adjustment)
            if(vol>100): 
                vol = 100
            resp = self.volume(vol)
            
            if (self.debug): print resp
        except:
            print " -> VolumeUp Failure: ", sys.exc_info()[0]
            resp = ""

        return resp
   
    def volume(self, newVol = None):
        """
        Volume to newVol
        """
        print "-- Calling Service: Volume set"
        try:
            print "Volume To:" + str(newVol)
            resp = self.call("volume?volume_percent=" + str(newVol),"PUT" )
            self.oh.sendCommand('spotify_current_volume',newVol)
            if (self.debug): print resp
        except:
            print " -> VolumeDown Failure: ", sys.exc_info()[0]
            resp = ""

        return resp    
    
    

    def pause(self):
        """
        Pause player
        """
        print "-- Calling Service: Pause"
        try:
            resp = self.call("pause","PUT")
            self.oh.sendCommand('spotify_current_playing',"OFF")
            if (self.debug): print resp
        except:
            print " -> Pause Failure: ", sys.exc_info()[0]
            resp = ""

        return resp    
    
    def play(self, context_uri = None, new_device = None):
        """
        Resume player device
        """
        print "-- Calling Service: Play device"
         
        if (new_device is None or len(new_device)==0):
            action_url = "play"
            print "basic url match"
            print action_url
            if (context_uri is None):
                payload = {}
            else:
                payload = json.dumps({ 'context_uri': context_uri })
        else:
            if (context_uri is None):
                payload = json.dumps({ 'device_ids': [new_device] })
                action_url = ""
            else:
                payload = json.dumps({ 'context_uri': context_uri })
                action_url = "play?device_id=" + str(new_device)
        print payload
        print action_url

        try:
            resp = self.call(action_url,"PUT", payload = payload)
            if (self.debug): print resp
            self.update()
        except:
            print " -> Play Failure: ", sys.exc_info()[0]
            resp = ""

        return resp    

    def previous(self):
        """
        Skip to previous track
        """
        print "-- Calling Service: Previous"
        try:
            resp = self.call("previous","POST")
            if (self.debug): print resp
            self.update()  
        except:
            print " -> Previous Failure: ", sys.exc_info()[0]
            resp = ""

        return resp        

    def next(self):
        """
        Skip to next track
        """
        print "-- Calling Service: Next"
        try:
            resp = self.call("next","POST")
            if (self.debug): print resp
            self.update()
        except:
            print " -> Next Failure: ", sys.exc_info()[0]
            resp = ""

        return resp
    
    def shuffle(self):
        """
        Shuffle track
        """
        print "-- Calling Service: Shuffle"
        try:
            resp = self.call("shuffle?state=true","PUT")
            if (self.debug): print resp
            self.update()
        except:
            print " -> Shuffle Failure: ", sys.exc_info()[0]
            resp = ""

        return resp

    def shuffleoff(self):
        """
        Don't Shuffle track
        """
        print "-- Calling Service: Shuffle Off"
        try:
            resp = self.call("shuffle?state=false","PUT")
            if (self.debug): print resp
            self.update()
        except:
            print " -> Shuffle Failure: ", sys.exc_info()[0]
            resp = ""

        return resp

    def device_match(self, device_pick = None):
        """
        Identify device input type,(name, id or index).
        """
        print "-- Calling Service: devices_match"

        device_id_match=""
        index_test=""
        array_index=-1
#Dynamic check of id length against current id, with backup test if current id is null.
      
        try:
            if(device_pick):
                current_device_id = self.oh.getState('spotify_current_device_id')
                if( len(device_pick) == len(current_device_id) or len(device_pick) == 40):
                    array_index=1
                    print "id: ", device_pick        
                else:
                    if (device_pick.isdigit() and len(device_pick) < 3):
                        array_index=2
                        print "index: ", device_pick  
                    else:
                        print "name: ", device_pick
                        array_index=0           

        except:
            print " -> Failure: ", sys.exc_info()[0]          

        return array_index

    def playlists(self):
        """
        Get users recent playlists
        """
        print "-- Calling Service: get playlists"

        try:
            
            resp = self.call("playlists")
            if (self.debug): print resp
            self.oh.sendCommand('spotify_playlists', json.dumps(resp))

        except:
            print " -> Failure: ", sys.exc_info()[0]
            resp = ""
        
        return resp            

    def devices(self, name = None, idNum = None, devIndex = None):
        """
        Get a current player devices and helper function to play device.
        """
        print "-- Calling Service: get devices"
        exitStatus=" -> Success"
        selected_device=""
        
        if (name) or (idNum) or (devIndex): exitStatus = ""
        if (devIndex) : iIndex = int(devIndex)
        else: iIndex = -1
        arrayDesc=[name,idNum,iIndex]    
        try:
            resp = self.call("devices")
            if (self.debug): print resp
            if ('devices' in resp):
                self.oh.sendCommand('spotify_devices', json.dumps(resp))
   
                initOrder = 0
                partial = ""
                j = 0
                k = 1
                while(exitStatus == ""):
                    idx = 1
                    searchName = arrayDesc[(j%3)]
                    print "Match :", searchName , " or ", arrayDesc[((1 + j)%3)], "index: ", iIndex
                    intmed = str(searchName)
                    print intmed                   
                    print json.dumps(searchName)
                    for i in resp['devices']:
                        loopName = getJSONValue(i, ['name'])
                        
                        searchid = getJSONValue(i, ['id'])
                        print idx, "Device : " , loopName , "id :" ,searchid 
                        if (arrayDesc[(j%3)] ==  loopName) or (arrayDesc[((1 + j)%3)] == searchid) or (iIndex == idx ):
                            self.oh.sendCommand('spotify_device_name', loopName)
                            self.oh.sendCommand('spotify_device_id', searchid)
                            self.oh.sendCommand('spotify_device_index', idx)
                            exitStatus="Match Sucess"
                            selected_device = searchid
                            return selected_device
                        #Performs partial match serach if no results found
                        if (searchName): 
                            if searchName.lower() in loopName.lower():
                                partial =  searchid                              
                        idx = idx + 1
                    #Looks at the various inputs and seraches on each input in various fields                    
                    iIndex=""
                    j+=1
                    if( j > 3): exitStatus="FAILED"   
                    if (j == k):
                        k = 2
                        dev_desp=""
                        if (idNum): 
                            dev_desp = idNum
                            idNum=""
                            j  = 0
                            initOrder = 1
                            print "idNum serach" 
                        elif (devIndex) : 
                            dev_desp = devIndex
                            devIndex=""
                            j  = 0
                            iIndex=-1
                            initOrder = 2
                            print "devinx serach" 
                        elif (name) :
                            dev_desp = name
                            j  = 0
                            name = ""
                            initOrder = 0
                            print "name serach"                         
                        if (dev_desp):
                            smart_index = self.device_match(dev_desp)
                            if(smart_index > 0):
                                arrayDesc[smart_index] = dev_desp
                                if (smart_index == 2): 
                                    iIndex = int(dev_desp)
                                if (smart_index == initOrder): j = j + 1
                                
                        elif (partial):
                            k = 10
                            j = 3
                            arrayDesc[1] = partial
                            print "partial serach"

                print exitStatus
            else:
                print " -> Device list error :("
        except:
            print " -> Failure: ", sys.exc_info()[0]
            resp = ""
        return selected_device
    def removequotes(self,s): return "".join(i for i in s if i != "\"")
    def argsort(self, theargs = None):
        spotifyString="spotify:"
        myargs = ["",""]

        for i in range(2, len(theargs)):
            print theargs[i]
            stream=self.removequotes(theargs[i]).strip()            
            if spotifyString in theargs[i].lower():
                myargs[0] = myargs[0]  + stream + " "
            else: 
                myargs[1] = myargs[1] + stream + " "
        
        return self.removeEmpty(myargs)
    
  
    def removeEmpty(self, inString = None):
        print inString        
        for i in range(len(inString)):        
            if(inString[i] == ""):  inString[i] = None
            else: inString[i]=inString[i].strip()    
        return inString

    def sanitiseActions(self, uristring = None, device_string = None):
        new_device_id = self.devices(device_string)
        current_device = self.oh.getState('spotify_current_device_id')
        currently_playing = self.oh.getState('spotify_current_playing')
        ma=[uristring,device_string]
        if (current_device == new_device_id):
            ma[1]=""
        
        return ma

    
    def updateConnectionDateTime(self):
        self.oh.sendCommand('spotify_lastConnectionDateTime',time.strftime("%Y-%m-%dT%H:%M:%S.000+0000",time.gmtime(time.time())))   
        # self.oh.sendCommand('spotify_lastConnectionDateTime',time.strftime("%Y-%m-%dT%H:%M:%S+0000",time.gmtime(time.time())))     

def main():

    t1 = time.time()

    c = spotify()

    args = sys.argv
    
    if(len(args) == 1):
        c.update()
    else:

        if(args[1] == "volume_up"):
            c.volumeAdjust(10)
        if(args[1] == "volume_down"):
            c.volumeAdjust(-10)
        if(args[1] == "volume"):
            c.volume(args[2])
        if(args[1] == "mute"):
            c.volume("0")              
        if(args[1] == "play"):
            if(len(args)>2):
                ma = c.argsort(args)                                
                c.play(ma[0],c.devices(ma[1]))                
            else:
                c.play()
        if(args[1] == "playlists"):
            c.playlists()
        if(args[1] == "pause"):
            c.pause()
        if(args[1] == "previous"):
            c.previous()
        if(args[1] == "next"):
            c.next()
        if(args[1] == "shuffle"):
            c.shuffle()
        if(args[1] == "shuffleoff"):
            c.shuffleoff()
        if(args[1] == "devices"):
            if(len(args)>2):
                ma = c.argsort(args)  
                c.devices(ma[1])
            else:               
                c.devices()
        if(args[1] == "device_id"):
            if(len(args)>2):
                c.devices(None,args[2])
            else:
                c.devices()
        if(args[1] == "device_name"):
            if(len(args)>2):
                ma = c.argsort(args)  
                c.devices(ma[1])
            else:            
                c.devices()
        if(args[1] == "device_index"):
            if(len(args)>2):            
                c.devices(None, None, args[2])
            else:            
                c.devices()
        if(args[1] == "play_device"):
            ma = c.argsort(args)  
            c.play(ma[0], c.devices(ma[1]))
        if(args[1] == "play_device_name"):
            ma = c.argsort(args)  
            c.play(ma[0], c.devices(ma[1]))
                   
                              
    c.updateConnectionDateTime()

    t2 = time.time()
    print "Done in " + str(t2-t1) + " seconds"

if __name__ == '__main__':
    main()

HI guys

I already have the spotify web api running, but on every startup i lost the auth.

I saw in the configuration that you have to enable presistence but i dont know how to do that, can you help me please?

Best regards

For MySQL see e.g. this tutorial, it did work out for me: openHAB2 & MySQL persistence setup

Same problem @OliM! Have you already found a solution?

Hello! Please I need help, following the tutorial I have a problem at the end, I copy the result below.
I do not know what to try

Blockquote

pi@Domotica:~ $ /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
-> Error refreshing token:{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
Successfully posted state to OpenHab: spotify_access_token = XXXXXXXXXXXXXXXXXXXXGIE9oAsIPkvtNdrjL3km3i7B9g9x5kW379fAgC6PJOkmXe1PKYBFLjGIHQOqn8G02bjjCjhLj62aiQT7OWc5WMQxsH2w35H0-6dtvhDEpUNoSFd87FRLleFz9tY9thS0l5nA3QBTKlb9HH4
Successfully posted state to OpenHab: spotify_refresh_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXDt6cr-33Z9s0lXFR2sW4MO5pn6JCwegcSsacZV6VwH3DfUfH1g6Go3t3K8tS9nLqJZEpvdsPlqyYirIJjVfJsqHZX8K3YRw
Successfully posted state to OpenHab: spotify_token_expiry = 1516801970.35
Successfully posted state to OpenHab: spotify_token_issued = 2018-01-24T13:52:50
– Calling Service: Update

https://api.spotify.com/v1/me/player/
-> Failure: <class ‘simplejson.scanner.JSONDecodeError’>
Successfully posted state to OpenHab: spotify_lastConnectionDateTime = 2018-01-24T12:52:50.000+0000
Done in 1.43034410477 seconds

Where is the error?

Hi all!

If I click on the next song, I have to click on the update-button and then reload the page to see the new cover-image. Why?

Next song: ng-click="sendCmd(‘spotify_action’, ‘next’)"
Update: ng-click=“sendCmd(‘spotify_forceupadte’, ‘ON’)“
Cover-image: ng-style=”{‘background-image’: ‘url(’ + itemValue(‘spotify_current_cover’) + ‘)’}”

I got two rules:
Spotify-test:
rule “Spotify run script"
when
Time cron “0/1 * * * * ? *” or
Item spotify_forceupadte received update
then
val resp = executeCommandLine(”/usr/bin/python /etc/openhab2/scripts/spotify.py", 2000)
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, 2000)
logInfo(“Spotify”, resp)
end

Spotify:
rule “Spotify run script"
when
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

Not sure. I get the image to load pretty much instantly when I press next or back. Maybe 10 seconds or so. No need to update status or refresh the page.

You have a time cron running every second all the time which might be a bit much for the spotify servers so they are limiting your connection which you only notice when you try and get an image. I have one that runs once every 30 seconds, but if spotify is playing then it will update every 5 seconds. I then used js as posted above to smooth the progress bar over those 5 sec.

Edit: I lied only update every 30 when spotify is active and once every half an hour otherwise, which is probably too conservative.

rule "spotify live update"
    when
        Time cron "0/30 * * * * ?"
    then

        if ( spotify_current_playing.state == ON && parse(spotify_lastConnectionDateTime.state.toString).plusSeconds(20).isBefore(now)){            
            sendCommand(spotify_forceupadte, ON)
            logInfo("Spotify", "Chrom live update run")	            
        }
end


	
rule "spotify update"
    when
        Time cron "0 0/30 * * * ?"
    then
        logInfo("Spotify", "Chron prelock")
        if (parse(spotify_lastConnectionDateTime.state.toString).plusSeconds(45).isBefore(now)){			

            sendCommand(spotify_forceupadte, ON)
            logInfo("Spotify", "Chrom  update run")	
        }
end
1 Like

I have the same problem, I have set the Windows variables and can call python from the CMD line, but openHAB is still looking for its default path and resolving the variable;

Execution failed (Exit value: -559038737. Caused by java.io.IOException: Cannot run program "\usr\bin\python" (in directory ".")

Is there an option to change the biding or script to look for a Windows variables, or how can I get Windows to recognize that “\usr\bin\python” actually is C:\Python27. I am pretty sure that system variables cannot include "/"s

Whoops, this is clearly defined and can get set using true path in the spotify.rules file.

val resp =  executeCommandLine("C:\\Python27\\python.exe D:\\openHAB\\conf\\scripts\\spotify.py", 5000)

I must have been getting tunnel vision on the actual scripts themselves - Cheers

Hi All,

It’s all working fine, thanks for the work!!

Except when I update the items file or reboot openhab I have to manually assign id and secret and then authenticate on spotify-auth.html.
Any solution for this, or am I missing something?

Thanks!

PS. Persistence is recording any change:

Strategies {
	everyMinute : "0 * * * * ?"
	everyHour 	: "0 0 * * * ?"
	everyDay	: "0 0 0 * * ?"
	default = everyChange
}

Items {
	// persist everything when the value is updated, just a default, and restore them from database on startup
	* : strategy = everyChange, everyMinute, restoreOnStartup
}

I´ve got always :

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: Update
 -> Failure:  <type 'exceptions.ValueError'>

Is the redirect URI REDIRECT_URI = ‘http://openhabianpi.local:8080/static/spotify-auth.html’ correct in spotify.py ???

Thanks for help

Mad

Edit : Got it

I’m running this on a mac so I changed the redirect URI to http://localhost:8080/static/spotify-auth.html

Samanthas-iMac:scripts SamanthaAllen$ python 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 Service: Update
-> Failure: <type ‘exceptions.ValueError’>
Error posting state to OpenHab: spotify_lastConnectionDateTime (HTTP Response State could not be parsed: 2018-02-20T16:33:17+0000)
Done in 1.39271020889 seconds

This helps :

openHAB integration to Spotify Web Connect API (player)

Thanks. I’m at the point where I need to configure a persistence db and when I try installing mysql in terminal for mac it asks for a password. I have no clue what this password could possibly be. It’s not my mac password and the habopen default password I read about is not working. Any ideas?

It took me a while to figure out that you have to set it in spotify.py, and also set it in the app settings in the Spotify developer dashboard. I don’t see that 2nd step identified anywhere here.

So I am having trouble with persistence. I have to re-auth every time Openhab restarts. Where can I put the values for spotify_client_id and spotify_client_secret so that they can be loaded when Openhab starts?

I’ve got some items updated on the startup, I’ve included Spotify id’s but I still have to re-authenticate…
Would love it to be a permanent thing

rule "Initialize items on startup"
when
    System started
then
    postUpdate(spotify_client_id, "99852********************923d5b")
    postUpdate(spotify_client_secret, "c5a47bf********************69c039")
end
1 Like