The branch, frodo has been updated
       via  18ea10ddd44b06902d28333518d6ef353dfbc41d (commit)
      from  174c6718d269fa07d5f2cc219831b01d4c514e01 (commit)

- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/scripts;a=commit;h=18ea10ddd44b06902d28333518d6ef353dfbc41d

commit 18ea10ddd44b06902d28333518d6ef353dfbc41d
Author: Martijn Kaijser <[email protected]>
Date:   Sat Feb 1 14:16:20 2014 +0100

    [script.sonos] 1.0.2

diff --git a/script.sonos/addon.xml b/script.sonos/addon.xml
index 97a97e8..64bb099 100644
--- a/script.sonos/addon.xml
+++ b/script.sonos/addon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="script.sonos" name="Sonos" version="1.0.0" 
provider-name="robwebset">
+<addon id="script.sonos" name="Sonos" version="1.0.2" 
provider-name="robwebset">
        <requires>
                <import addon="xbmc.python" version="2.1.0"/>
                <import addon="script.module.requests" version="1.1.0"/>
diff --git a/script.sonos/changelog.txt b/script.sonos/changelog.txt
index 624356f..a9b44bf 100644
--- a/script.sonos/changelog.txt
+++ b/script.sonos/changelog.txt
@@ -1,2 +1,9 @@
+v1.0.2
+- Mini Sonos controller added with album art
+
+v1.0.1
+- Don't display notification on startup if Sonos is not playing
+- Initial version of controller
+
 v1.0.0:
 - Initial release
diff --git a/script.sonos/default.py b/script.sonos/default.py
index 62cf4d3..8c242af 100644
--- a/script.sonos/default.py
+++ b/script.sonos/default.py
@@ -22,6 +22,9 @@ from soco import SoCo
 from soco import SonosDiscovery
 from soco import SoCoException
 
+# Import the Mock Sonos class for testing where there is no live Sonos system
+from mocksonos import TestMockSonos
+
 
 def log(txt):
     if __addon__.getSetting( "logEnabled" ) == "true":
@@ -42,30 +45,358 @@ class Settings():
         return __addon__.getSetting("ipAddress")
 
     @staticmethod
-    def getNotificationDisplayDuration():
+    def getRefreshInterval():
         # Convert to milliseconds before returning
-        return int(float(__addon__.getSetting("notifDisplayDuration"))) * 1000
+        return int(float(__addon__.getSetting("refreshInterval")) * 1000)
 
     @staticmethod
-    def getNotificationCheckFrequency():
-        # Convert to milliseconds before returning
-        return int(float(__addon__.getSetting("notifCheckFrequency"))) * 1000
+    def useTestData():
+        return __addon__.getSetting("useTestData") == 'true'
+
 
+#####################################################
+# Main window for the Sonos controller
+#####################################################
+class SonosControllerWindow(xbmcgui.WindowXMLDialog):
+    ALBUM_ART = 801
+    ARTIST_LABEL = 802
+    TITLE_LABEL = 803
+    ALBUM_LABEL = 804
+    NEXT_LABEL = 805
+    
+    TRACK_POSITION_LABEL = 810
+    DURATION_LABEL = 812
+    SLIDER_SEEK = 811
+    
+    # Button IDs
+    BUTTON_PREVIOUS = 600
+    BUTTON_PLAY = 601
+    BUTTON_PAUSE = 602
+    BUTTON_STOP = 603
+    BUTTON_NEXT = 604
+    
+    BUTTON_NOT_MUTED = 620
+    BUTTON_MUTED = 621
+    SLIDER_VOLUME = 622
+    
+
+    def __init__( self, *args, **kwargs ):
+        self.closeRequested = False
+        # Copy off the key-word arguments
+        # The non keyword arguments will be the ones passed to the main 
WindowXML
+        self.sonosDevice = kwargs.pop('sonosDevice')
+        self.currentTrack = None
+        
+        self.delayedRefresh = 0
+
+    # Static method to create the Window Dialog class
     @staticmethod
-    def useXbmcNotifDialog():
-        return __addon__.getSetting("xbmcNotifDialog") == 'true'
+    def createSonosControllerWindow(sonosDevice):
+        return SonosControllerWindow("script-sonos-controller.xml", __cwd__, 
sonosDevice=sonosDevice)
+
+    def isClose(self):
+        return self.closeRequested
+
+    # Handle the close action
+    def onAction(self, action):
+        # ACTION_PREVIOUS_MENU        10
+        # ACTION_NAV_BACK             92
+        if (action == 10) or (action == 92):
+            log("SonosControllerWindow: Close Action received: %s" % 
str(action))
+            self.close()
+
+    # Handle the close event - make sure we set the flag so we know it's been 
closed
+    def close(self):
+        self.closeRequested = True
+        xbmcgui.WindowXMLDialog.close(self)
+
+    def updateDisplay(self):
+        # Get the current track information
+        track = sonosDevice.get_current_track_info()
+
+        # Only update if the track has changed
+        if (track != None) and ((self.currentTrack == None) or (track['uri'] 
!= self.currentTrack['uri'])):
+            # Get the album art if it is set (Default to the Sonos icon)
+            albumArtImage = __icon__
+            if track['album_art'] != "":
+                albumArtImage = track['album_art']
+    
+            # Need to populate the popup with the artist details
+            albumArt = self.getControl(SonosControllerWindow.ALBUM_ART)
+            albumArt.setImage(albumArtImage)
+    
+            artistLabel = self.getControl(SonosControllerWindow.ARTIST_LABEL)
+            artistLabel.reset()
+            artistLabel.addLabel(track['artist'])
+    
+            titleLabel = self.getControl(SonosControllerWindow.TITLE_LABEL)
+            titleLabel.reset()
+            titleLabel.addLabel(track['title'])
+    
+            albumLabel = self.getControl(SonosControllerWindow.ALBUM_LABEL)
+            albumLabel.reset()
+            albumLabel.addLabel(track['album'])
+
+            nextTrackLabel = self.getControl(SonosControllerWindow.NEXT_LABEL)
+            # Clear the current text
+            nextTrackLabel.reset()                
+
+            # Display the track duration
+            durationLabel = 
self.getControl(SonosControllerWindow.DURATION_LABEL)
+            durationLabel.setLabel(self._stripHoursFromTime(track['duration']))
 
+            # If the duration is 00:00:00 then this normally means that 
something like radio
+            # is steaming so we shouldn't show any timing details
+            if track['duration'] == '0:00:00':
+                durationLabel.setVisible(False)
+            else:
+                durationLabel.setVisible(True)
 
+            #################################################################
+            # Note: the code below gives the next track in the playlist
+            # not the next track to be played (which is the case if random)
+            # No way to do that at the moment
+            #################################################################
 
+            # Check if there is a next track            
+#             if track['playlist_position'] != "" and 
int(track['playlist_position']) > -1:
+#                 # Also get the "Next Track" Information
+#                 # 0 would be the current track
+#                 nextTrackList = 
sonosDevice.get_queue(int(track['playlist_position']), 1)
+#      
+#                 if (nextTrackList != None) and (len(nextTrackList) > 0):
+#                     nextTrackItem = nextTrackList[0]
+#                     nextTrackText = "[COLOR=FF0084ff]%s:[/COLOR] %s - %s" % 
("Next", nextTrackItem['title'], nextTrackItem['artist'])
+#                     nextTrackLabel.addLabel(nextTrackText)
 
-###########################################################################
-# NOTE
-# ====
-# This section is all temporary - it is just to show what future versions
-# will be able to do
-###########################################################################
+        self.currentTrack = track
 
-if __name__ == '__main__':
+        # Display the track position
+        trackPositionLabel = 
self.getControl(SonosControllerWindow.TRACK_POSITION_LABEL)
+        
trackPositionLabel.setLabel(self._stripHoursFromTime(track['position']))
+
+        # Get the initial state of the device
+        playStatus = sonosDevice.get_current_transport_info()
+        
+        # Set the play/pause button to the correct value
+        playButton = self.getControl(SonosControllerWindow.BUTTON_PLAY)
+        if (playStatus != None) and (playStatus['current_transport_state'] == 
'PLAYING'):
+            playButton.setVisible(False)
+        else:
+            playButton.setVisible(True)
+        
+        # Check to see what the current state of the mute button is
+        muteButton = self.getControl(SonosControllerWindow.BUTTON_NOT_MUTED)
+        if sonosDevice.mute() == 0:
+            muteButton.setVisible(True)
+        else:
+            muteButton.setVisible(False)
+
+        # The following controls need a delayed refresh, this is because they
+        # are controls like sliders, so we do not want to update them until
+        # the slider operation is complete
+        if self.delayedRefresh < 1:
+    
+            # Get the current volume and set the slider
+            # Will return a value between 0 and 100
+            currentVolume = sonosDevice.volume()
+            # Get the slider control
+            volumeSlider = self.getControl(SonosControllerWindow.SLIDER_VOLUME)
+            # Don't move slider is already in correct position
+            currentSliderPosition = int(volumeSlider.getPercent())
+            if currentSliderPosition != currentVolume:
+                volumeSlider.setPercent(currentVolume)
+
+            # Set the seek slider
+            self._setSeekSlider(track['position'],track['duration'])
+
+        else:
+            self.delayedRefresh = self.delayedRefresh - 1
+
+
+    # Do the initial setup of the dialog
+    def onInit(self):
+        self.updateDisplay()
+
+    # Handle the operations where the user clicks on a button
+    def onClick(self, controlID):
+
+        # Play button has been clicked
+        if controlID == SonosControllerWindow.BUTTON_PLAY:
+            log("SonosControllerWindow: Play Requested")
+
+            # Send the play message to Sonos
+            sonosDevice.play()
+            self.setFocusId(SonosControllerWindow.BUTTON_PAUSE)
+
+        elif controlID == SonosControllerWindow.BUTTON_PAUSE:
+            log("SonosControllerWindow: Pause Requested")
+
+            # Send the pause message to Sonos
+            sonosDevice.pause()
+            self.setFocusId(SonosControllerWindow.BUTTON_PLAY)
+
+        elif controlID == SonosControllerWindow.BUTTON_NEXT:
+            log("SonosControllerWindow: Next Track Requested")
+            sonosDevice.next()
+
+        elif controlID == SonosControllerWindow.BUTTON_PREVIOUS:
+            log("SonosControllerWindow: Previous Track Requested")
+            sonosDevice.previous()
+
+        elif controlID == SonosControllerWindow.BUTTON_STOP:
+            log("SonosControllerWindow: Stop Requested")
+            sonosDevice.stop()
+
+        elif controlID == SonosControllerWindow.BUTTON_NOT_MUTED:
+            log("SonosControllerWindow: Mute Requested")
+            sonosDevice.mute(True)
+            self.setFocusId(SonosControllerWindow.BUTTON_MUTED)
+
+        elif controlID == SonosControllerWindow.BUTTON_MUTED:
+            log("SonosControllerWindow: Mute Requested")
+            sonosDevice.mute(False)
+            self.setFocusId(SonosControllerWindow.BUTTON_NOT_MUTED)
+
+        elif controlID == SonosControllerWindow.SLIDER_VOLUME:
+            # Get the position of the slider
+            volumeSlider = self.getControl(SonosControllerWindow.SLIDER_VOLUME)
+            currentSliderPosition = int(volumeSlider.getPercent())
+
+            log("SonosControllerWindow: Volume Request to value: %d" % 
currentSliderPosition)
+
+            # Before we send the volume change request we want to delay any 
refresh
+            # on the gui so we have time to perform the slide operation without
+            # the slider being reset
+            self._setDelayedRefresh()
+
+            # Now set the volume
+            sonosDevice.volume(currentSliderPosition)
+
+        elif controlID == SonosControllerWindow.SLIDER_SEEK:
+            # Get the position of the slider
+            seekSlider = self.getControl(SonosControllerWindow.SLIDER_SEEK)
+            currentSliderPosition = int(seekSlider.getPercent())
+
+            log("SonosControllerWindow: Seek Request to value: %d" % 
currentSliderPosition)
+
+            # Before we send the seek change request we want to delay any 
refresh
+            # on the gui so we have time to perform the slide operation without
+            # the slider being reset
+            self._setDelayedRefresh()
+
+            # Now set the seek location
+            self._setSeekPosition(currentSliderPosition)
+
+#        else:
+#            xbmcgui.Dialog().ok(__addon__.getLocalizedString(32001), "Control 
clicked is " + str(controlID))
+
+        # Refresh the screen to show the current state
+        self.updateDisplay()
+
+    # Set a delay time so that the screen does not automatically update
+    # and leaves time for a given operation
+    def _setDelayedRefresh(self):
+        # Convert the refresh interval into seconds
+        refreshInterval = Settings.getRefreshInterval() / 1000
+        if refreshInterval == 0:
+            # Make sure we do not divide by zero
+            refreshInterval = 1
+        self.delayedRefresh = int( 4 / float(refreshInterval) )
+        if self.delayedRefresh == 0:
+            self.delayedRefresh = 1
+
+    # Takes a time string (00:00:00) and removes the hour section if it is 0
+    def _stripHoursFromTime(self, fullTimeString):
+        if (fullTimeString == None) or (fullTimeString == ""):
+            return "00:00"
+        if fullTimeString.count(':') == 2:
+            # Check if the hours section should be stripped
+            hours = 0
+            try:
+                hours = int(fullTimeString.split(':',1)[0])
+            except:
+                # Hours section is not numbers
+                log("SonosControllerWindow: Exception Details: %s" % 
traceback.format_exc())
+                hours = 0
+
+            # Only strip the hours if there are no hours
+            if hours < 1:
+                return fullTimeString.split(':',1)[-1]
+        return fullTimeString
+
+    # Set the seek slider to the current position of the track
+    def _setSeekSlider(self, currentPosition, trackDuration):
+        currentPositionSeconds = self._getSecondsInTimeString(currentPosition)
+        trackDurationSeconds = self._getSecondsInTimeString(trackDuration)
+        
+        # work out the percentage we are through the track
+        currentPercentage = 0
+        if trackDurationSeconds > 0:
+            currentPercentage = int((float(currentPositionSeconds) / 
float(trackDurationSeconds)) * 100)
+        
+        log("SonosControllerWindow: Setting seek slider to %d" % 
currentPercentage)
+        
+        # Get the slider control
+        seekSlider = self.getControl(SonosControllerWindow.SLIDER_SEEK)
+        seekSlider.setPercent(currentPercentage)
+
+    # Converts a time string 0:00:00 to the total number of seconds
+    def _getSecondsInTimeString(self, fullTimeString):
+        # Start by splitting the time into sections
+        hours = 0
+        minutes = 0
+        seconds = 0
+        
+        try:
+            hours = int(fullTimeString.split(':',1)[0])
+            minutes = int(fullTimeString.split(':')[1])
+            seconds = int(fullTimeString.split(':')[2])
+        except:
+            # time sections are not numbers
+            log("SonosControllerWindow: Exception Details: %s" % 
traceback.format_exc())
+            hours = 0
+            minutes = 0
+            seconds = 0
+
+        totalInSeconds = (((hours * 60) + minutes) * 60) + seconds
+        log("SonosControllerWindow: Time %s, splits into hours=%d, minutes=%d, 
seconds=%d, total=%d" % (fullTimeString, hours, minutes, seconds, 
totalInSeconds))
+
+        # Return the total time in seconds
+        return totalInSeconds
+
+    # Sets the current seek time, sending it to the sonos speaker
+    def _setSeekPosition(self, percentage):
+        trackDurationSeconds = 
self._getSecondsInTimeString(self.currentTrack['duration'])
+
+        if trackDurationSeconds > 0:
+            # Get the current number of seconds into the track
+            newPositionSeconds = int((float(percentage) * 
float(trackDurationSeconds))/100)
+            
+            # Convert the seconds into a timestamp
+            newPosition = "0:00:00"
+
+            # Convert the duration into a viewable format
+            if newPositionSeconds > 0:
+                seconds = newPositionSeconds % 60
+                minutes = 0
+                hours = 0
+     
+                if newPositionSeconds > 60:
+                    minutes = ((newPositionSeconds - seconds) % 3600)/60
+
+                if newPositionSeconds > 3600:
+                    hours = (newPositionSeconds - (minutes*60) - seconds)/3600
+
+                # Build the string up    
+                newPosition = "%d:%02d:%02d" % (hours, minutes, seconds)
+
+            # Now send the seek message to the sonos speaker
+            sonosDevice.seek(newPosition)
+        
+
+
+if __name__ == '__main__':    
     
     ipAddress = Settings.getIPAddress()
 
@@ -75,52 +406,31 @@ if __name__ == '__main__':
     if ipAddress != "0.0.0.0":
         sonosDevice = SoCo(ipAddress)
 
-        # Display a simple selection dialog for now
-        menuItems = ['Play', 'Pause', 'Stop', 'Next Track', 'Previous', 'LED 
On', 'LED Off', 'Exit']
+        if Settings.useTestData():
+            sonosDevice = TestMockSonos()
 
-        select = xbmcgui.Dialog().select(__addon__.getLocalizedString(32001), 
menuItems)
 
-        try:
-            # Play was requested
-            if select == 0:
-                log("Sonos: Play Requested")
-                sonosDevice.play()
-            
-            # Pause was requested
-            elif select == 1:
-                log("Sonos: Pause Requested")
-                sonosDevice.pause()
-    
-            # Stop was requested
-            elif select == 2:
-                log("Sonos: Stop Requested")
-                sonosDevice.stop()
-    
-            # Next was requested
-            elif select == 3:
-                log("Sonos: Next Track Requested")
-                sonosDevice.next()
-    
-            # Previous was requested
-            elif select == 4:
-                log("Sonos: Previous Track Requested")
-                sonosDevice.previous()
-    
-            # Turn Status Light On
-            elif select == 5:
-                log("Sonos: LED On Requested")
-                sonosDevice.status_light(True)
-    
-            # Turn Status Light Off
-            elif select == 6:
-                log("Sonos: LED Off Requested")
-                sonosDevice.status_light(False)
+        sonosCtrl = 
SonosControllerWindow.createSonosControllerWindow(sonosDevice)
+        sonosCtrl.show()
+        
+        # Record the fact that the Sonos controller window is displayed
+        xbmcgui.Window(10000).setProperty( "SonosControllerShowing", "true" )
 
+        try:
+            while (not sonosCtrl.isClose()) and (not xbmc.abortRequested):
+                sonosCtrl.updateDisplay()
+                # Wait a second or so before updating
+                xbmc.sleep(Settings.getRefreshInterval())
         except:
             # Failed to connect to the Sonos Speaker
             xbmcgui.Dialog().ok(__addon__.getLocalizedString(32001), ("Error 
from speaker %s" % ipAddress))
             log("Sonos: Exception Details: %s" % traceback.format_exc())
 
+        sonosCtrl.close()
+        # Record the fact that the Sonos controller is no longer displayed
+        xbmcgui.Window(10000).clearProperty("SonosControllerShowing")
+        del sonosCtrl
+
     else:
         xbmcgui.Dialog().ok(__addon__.getLocalizedString(32001), "IP Address 
Not Set")
         
diff --git a/script.sonos/resources/language/English/strings.po 
b/script.sonos/resources/language/English/strings.po
index 0d90dec..f07d771 100644
--- a/script.sonos/resources/language/English/strings.po
+++ b/script.sonos/resources/language/English/strings.po
@@ -79,3 +79,16 @@ msgstr ""
 msgctxt "#32014"
 msgid "No speakers found, please enter your IP address manually"
 msgstr ""
+
+msgctxt "#32015"
+msgid "Controller"
+msgstr ""
+
+msgctxt "#32016"
+msgid "Refresh Interval (Seconds)"
+msgstr ""
+
+msgctxt "#32017"
+msgid "Use Test Data"
+msgstr ""
+
diff --git a/script.sonos/resources/settings.xml 
b/script.sonos/resources/settings.xml
index c24f68e..7b471fa 100644
--- a/script.sonos/resources/settings.xml
+++ b/script.sonos/resources/settings.xml
@@ -3,6 +3,9 @@
                <setting label="32013" type="action" 
action="RunScript($CWD/discovery.py)"/>
                <setting id="ipAddress" type="ipaddress" label="32002" 
default="0.0.0.0"/>
        </category>
+       <category label="32015">
+               <setting id="refreshInterval" label="32016" type="slider" 
default="2" range="0.5,0.5,5" option="float"/>
+       </category>
        <category label="32011">
                <setting id="notifEnabled" type="bool" label="32003" 
default="true"/>
                <setting id="notifDisplayDuration" enable="eq(-1,true)" 
label="32004" type="slider" default="3" range="0,1,60" option="int"/>
@@ -12,5 +15,6 @@
        </category>
        <category label="32012">
                <setting id="logEnabled" type="bool" label="32009" 
default="false"/>
+               <setting id="useTestData" type="bool" label="32017" 
default="false"/>
        </category>
 </settings>
diff --git 
a/script.sonos/resources/skins/Default/720p/script-sonos-notif-popup.xml 
b/script.sonos/resources/skins/Default/720p/script-sonos-notif-popup.xml
index ea7e382..2d68569 100644
--- a/script.sonos/resources/skins/Default/720p/script-sonos-notif-popup.xml
+++ b/script.sonos/resources/skins/Default/720p/script-sonos-notif-popup.xml
@@ -14,8 +14,15 @@
                                <posy>0</posy>
                                <width>420</width>
                                <height>90</height>
-                               <colordiffuse>EEFFFFFF</colordiffuse>
-                               <texture 
border="12">OverlayDialogBackground.png</texture>
+                               <colordiffuse>CCFFFFFF</colordiffuse>
+                               <texture 
border="12">[email protected]</texture>
+                       </control>
+                       <control type="image">
+                               <posx>5</posx>
+                               <posy>5</posy>
+                               <width>410</width>
+                               <height>80</height>
+                               <texture 
border="20">msNowPlayingBg_ipad.png</texture>
                        </control>
                        <control type="image" id="400">
                                <description>avatar</description>
diff --git a/script.sonos/service.py b/script.sonos/service.py
index bb615f7..3c91ae5 100644
--- a/script.sonos/service.py
+++ b/script.sonos/service.py
@@ -21,6 +21,8 @@ from soco import SoCo
 from soco import SonosDiscovery
 from soco import SoCoException
 
+# Import the Mock Sonos class for testing where there is no live Sonos system
+from mocksonos import TestMockSonos
 
 def log(txt):
     if __addon__.getSetting( "logEnabled" ) == "true":
@@ -60,6 +62,10 @@ class Settings():
     def useXbmcNotifDialog():
         return __addon__.getSetting("xbmcNotifDialog") == 'true'
 
+    @staticmethod
+    def useTestData():
+        return __addon__.getSetting("useTestData") == 'true'
+
 
 ##########################################################
 # Class to display a popup of what is currently playing
@@ -113,6 +119,7 @@ class SonosPlayingPopup(xbmcgui.WindowXMLDialog):
         self.close()
 
 
+
 ################################
 # Main of the Sonos Service
 ################################
@@ -128,11 +135,20 @@ if __name__ == '__main__':
         
         lastDisplayedTrack = None
         
+        # Need to only display the popup when the service starts if there is
+        # currently something playing
+        justStartedService = True
+
         # Loop until XBMC exits
         while (not xbmc.abortRequested):
             if timeUntilNextCheck < 1:
                 if Settings.stopNotifIfVideoPlaying() and 
xbmc.Player().isPlayingVideo():
                     log("SonosService: Video Playing, Skipping Notification 
Display")
+                elif 
xbmcgui.Window(10000).getProperty("SonosControllerShowing") == 'true':
+                    log("SonosService: Sonos Controller Showing, Skipping 
Notification Display")
+                    # Reset the "just started" flag to ensure that when we 
exit it does not
+                    # show the notification immediately
+                    justStartedService = True
                 else:
                     log("SonosService: Notification wait time expired")
                     ipAddress = Settings.getIPAddress()
@@ -142,6 +158,9 @@ if __name__ == '__main__':
                     # Make sure the IP Address has been set
                     if ipAddress != "0.0.0.0":
                         sonosDevice = SoCo(ipAddress)
+
+                        if Settings.useTestData():
+                            sonosDevice = TestMockSonos()
                       
                         # Should now have a single speaker set to "device"
                         if sonosDevice != None:
@@ -149,34 +168,47 @@ if __name__ == '__main__':
                                 # Get the current track that is being played 
at the moment
                                 track = sonosDevice.get_current_track_info()
                                 
+                                # Record if the sonos is currently playing
+                                isActive = True
+                                
                                 # Check to see if a new track is playing 
before displaying the popup
-                                if (track['uri'] == '') and (track['title'] == 
''):
+                                if (track['uri'] == '') or (track['title'] == 
''):
                                     track = None
                                     # Also make the last track value None as 
we don't want
                                     # this seen as a change
                                     lastDisplayedTrack = None
+                                elif justStartedService == True:
+                                    # Check if the sonos is currently playing
+                                    playStatus = 
sonosDevice.get_current_transport_info()
+                                    if (playStatus == None) or 
(playStatus['current_transport_state'] != 'PLAYING'):
+                                        isActive = False
             
                                 # Check to see if the playing track has changed
                                 if (track != None) and ((lastDisplayedTrack == 
None) or (track['uri'] != lastDisplayedTrack['uri'])):
                                     # Update the last displayed track to the 
current one
                                     lastDisplayedTrack = track
-                                    if Settings.useXbmcNotifDialog():
-                                        log("SonosService: Currently playing 
artist = %s, album = %s, track = %s" % (track['artist'], track['album'], 
track['title']))
-                             
-                                        # Get the album art if it is set 
(Default to the Sonos icon)
-                                        albumArt = __icon__
-                                        if track['album_art'] != "":
-                                            albumArt = track['album_art']
-                            
-                                        xbmc.executebuiltin('Notification(%s, 
%s, %d, %s)' % (track['artist'], track['title'], 
Settings.getNotificationDisplayDuration(), albumArt))
-                                    else:
-                                        sonosPopup = 
SonosPlayingPopup.createSonosPlayingPopup(track)
-                                        sonosPopup.showPopup()
-                                        del sonosPopup
+                                    # Only display the dialog if it is playing
+                                    if isActive:
+                                        if Settings.useXbmcNotifDialog():
+                                            log("SonosService: Currently 
playing artist = %s, album = %s, track = %s" % (track['artist'], 
track['album'], track['title']))
+                                 
+                                            # Get the album art if it is set 
(Default to the Sonos icon)
+                                            albumArt = __icon__
+                                            if track['album_art'] != "":
+                                                albumArt = track['album_art']
+                                
+                                            
xbmc.executebuiltin('Notification(%s, %s, %d, %s)' % (track['artist'], 
track['title'], Settings.getNotificationDisplayDuration(), albumArt))
+                                        else:
+                                            sonosPopup = 
SonosPlayingPopup.createSonosPlayingPopup(track)
+                                            sonosPopup.showPopup()
+                                            del sonosPopup
                             except:
                                 # Connection failure - may just be a network 
glitch - so don't exit
                                 log("SonosService: Error from speaker %s" % 
ipAddress)
                                 log("SonosService: %s" % 
traceback.format_exc())
+
+                            # No longer the first start
+                            justStartedService = False
     
                 # Reset the timer for the next check
                 timeUntilNextCheck = Settings.getNotificationCheckFrequency()
@@ -186,11 +218,3 @@ if __name__ == '__main__':
             timeUntilNextCheck = timeUntilNextCheck - 1
 
     log("Sonos: Stopping service")
-
-    # Test code to test the dialog without a Sonos Speaker connected
-#     track = {'title': 'Title value', 'artist': 'Artist Value', 'album': 
'AlbumValue', 'album_art': '',
-#             'position': ''}
-# 
-#     sonosPopup = SonosPlayingPopup.createSonosPlayingPopup(track)
-#     sonosPopup.showPopup()
-#     del sonosPopup

-----------------------------------------------------------------------

Summary of changes:
 script.sonos/addon.xml                             |    2 +-
 script.sonos/changelog.txt                         |    7 +
 script.sonos/default.py                            |  414 +++++++++++++++++---
 script.sonos/resources/language/English/strings.po |   13 +
 script.sonos/resources/lib/mocksonos.py            |   95 +++++
 script.sonos/resources/settings.xml                |    4 +
 .../skins/Default/720p/script-sonos-controller.xml |  297 ++++++++++++++
 .../Default/720p/script-sonos-notif-popup.xml      |   11 +-
 .../Default/media/DialogCloseButton-focus.png      |  Bin 5216 -> 5216 bytes
 .../skins/Default/media/DialogCloseButton.png      |  Bin 4522 -> 4522 bytes
 .../Default/media/control_buttons/snAutoBtn.png    |  Bin 0 -> 630 bytes
 .../skins/Default/media/control_buttons/tbMute.png |  Bin 0 -> 1751 bytes
 .../Default/media/control_buttons/tbMute_on.png    |  Bin 0 -> 1812 bytes
 .../Default/media/control_buttons/tbMute_sel.png   |  Bin 0 -> 3904 bytes
 .../Default/media/control_buttons/tbPause.png      |  Bin 0 -> 1881 bytes
 .../Default/media/control_buttons/tbPause_sel.png  |  Bin 0 -> 4518 bytes
 .../skins/Default/media/control_buttons/tbPlay.png |  Bin 0 -> 2042 bytes
 .../Default/media/control_buttons/tbPlay_sel.png   |  Bin 0 -> 4651 bytes
 .../skins/Default/media/control_buttons/tbStop.png |  Bin 0 -> 1848 bytes
 .../Default/media/control_buttons/tbStop_sel.png   |  Bin 0 -> 4465 bytes
 .../media/control_buttons/tbTransportBack.png      |  Bin 0 -> 1597 bytes
 .../media/control_buttons/tbTransportBack_sel.png  |  Bin 0 -> 3711 bytes
 .../media/control_buttons/tbTransportForward.png   |  Bin 0 -> 1598 bytes
 .../control_buttons/tbTransportForward_sel.png     |  Bin 0 -> 3709 bytes
 .../Default/media/control_buttons/tbUnMute_sel.png |  Bin 0 -> 3866 bytes
 .../media/control_buttons/tbVolumeScrubber.png     |  Bin 0 -> 1807 bytes
 .../media/control_buttons/tbVolumeScrubber_dis.png |  Bin 0 -> 1368 bytes
 .../skins/Default/media/[email protected]       |  Bin 0 -> 997 bytes
 .../skins/Default/media/msNowPlayingBg_ipad.png    |  Bin 0 -> 19126 bytes
 .../skins/Default/media/[email protected]   |  Bin 0 -> 1974 bytes
 .../skins/Default/media/pmProgressTrackBar.png     |  Bin 0 -> 310 bytes
 .../media/pmProgressTrackBarFillStretch.png        |  Bin 0 -> 168 bytes
 script.sonos/service.py                            |   68 +++-
 33 files changed, 834 insertions(+), 77 deletions(-)
 create mode 100644 script.sonos/resources/lib/mocksonos.py
 create mode 100644 
script.sonos/resources/skins/Default/720p/script-sonos-controller.xml
 copy {script.linphone => 
script.sonos}/resources/skins/Default/media/DialogCloseButton-focus.png (100%)
 copy {script.linphone => 
script.sonos}/resources/skins/Default/media/DialogCloseButton.png (100%)
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/snAutoBtn.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbMute.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbMute_on.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbMute_sel.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbPause.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbPause_sel.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbPlay.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbPlay_sel.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbStop.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbStop_sel.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbTransportBack.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbTransportBack_sel.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbTransportForward.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbTransportForward_sel.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbUnMute_sel.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbVolumeScrubber.png
 create mode 100644 
script.sonos/resources/skins/Default/media/control_buttons/tbVolumeScrubber_dis.png
 create mode 100644 
script.sonos/resources/skins/Default/media/[email protected]
 create mode 100644 
script.sonos/resources/skins/Default/media/msNowPlayingBg_ipad.png
 create mode 100644 
script.sonos/resources/skins/Default/media/[email protected]
 create mode 100644 
script.sonos/resources/skins/Default/media/pmProgressTrackBar.png
 create mode 100644 
script.sonos/resources/skins/Default/media/pmProgressTrackBarFillStretch.png


hooks/post-receive
-- 
Scripts

------------------------------------------------------------------------------
WatchGuard Dimension instantly turns raw network data into actionable 
security intelligence. It gives you real-time visual feedback on key
security issues and trends.  Skip the complicated setup - simply import
a virtual appliance and go from zero to informed in seconds.
http://pubads.g.doubleclick.net/gampad/clk?id=123612991&iu=/4140/ostg.clktrk
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to