Ankündigung

Einklappen
Keine Ankündigung bisher.

- √ - Neues Plugin: Logitech Squeezebox - Anregungen?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #16
    Zitat von macflei Beitrag anzeigen
    Geile Arbeit..... Geiles Plugin.
    Habs zwar noch nicht zu 100% eigebaut. Aber Lauter, Leiser, Play, Vor, Zurück und Mute gehen bei mir schonmal perfekt.
    Außer...... das "bekannte Problem" mit Umlauten in Künstler- oder Songnamen bringt das Plugin bei der Bedienung ins Stocken.

    Hinterlegte Playlists (z.B. Radiosender) könnte man ja "vorläufig" via multimedia.station aufrufen.
    Hi!

    Danke dir!

    Songnamen sind schon gefixt - nimm bitte die angehängte Version. Da fehlte die Konvertierung von UTF-8.

    Was die Playlist angeht komm ich grad nicht mit - wie du richtig sagst geht vor/zurück. Aber eine neue Playlists geht momentan nur per fixem Boolean-Item (siehe Playlist_Load_Internetradio), da ich keine Möglichkeit kenne einen String auszuwählen?

    Achtung: Statt * wird nun für <playerid> die ID der jeweiligen Squeezebox gesetzt - wurde benötigt da manchmal die ID nicht nur an erster Stelle steht und mir * dann einfach zu gefährlich war.

    Code:
    #!/usr/bin/env python
    # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
    #########################################################################
    # Copyright 2013 Robert Budde                        [EMAIL="robert@projekt131.de"]robert@projekt131.de[/EMAIL]
    #########################################################################
    #  Squeezebox-Plugin for SmartHome.py.  [url=http://mknx.github.com/smarthome/]SmartHome.py - Overview[/url]
    #
    #  This plugin is free software: you can redistribute it and/or modify
    #  it under the terms of the GNU General Public License as published by
    #  the Free Software Foundation, either version 3 of the License, or
    #  (at your option) any later version.
    #
    #  This plugin is distributed in the hope that it will be useful,
    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    #  GNU General Public License for more details.
    #
    #  You should have received a copy of the GNU General Public License
    #  along with this plugin. If not, see <[url=http://www.gnu.org/licenses/]Licenses - GNU Project - Free Software Foundation (FSF)[/url]>.
    #########################################################################
    import logging
    import struct
    import time
    import urllib2
    import lib.my_asynchat
    import re
    logger = logging.getLogger('Squeezebox')
    class Squeezebox(lib.my_asynchat.AsynChat):
        def __init__(self, smarthome, host='127.0.0.1', port=9090):
            lib.my_asynchat.AsynChat.__init__(self, smarthome, host, port)
            self._sh = smarthome
            self._val = {}
            self._obj = {}
            self._init_cmds = []
            smarthome.monitor_connection(self)
        def _check_mac(self, mac):
            return re.match("[0-9a-f]{2}([:])[0-9a-f]{2}([URL="file://\\1"]\\1[/URL][0-9a-f]{2}){4}$", mac.lower())
        
        def _resolv_full_cmd(self, item, attr):
            # check if PlayerID wildcard is used
            if '<playerid>' in item.conf[attr]:
                # try to get from parent object
                parent_item = item.return_parent()
                if (parent_item != None) and ('squeezebox_playerid' in parent_item.conf) and self._check_mac(parent_item.conf['squeezebox_playerid']):
                    item.conf[attr] = item.conf[attr].replace('<playerid>', parent_item.conf['squeezebox_playerid'])
                else:
                    logger.warning("squeezebox: could not resolve playerid for {0} from parent item {1}".format(item, parent_item))
                    return None
            return item.conf[attr] 
        def parse_item(self, item):
            
            if 'squeezebox_recv' in item.conf:         
                cmd = self._resolv_full_cmd(item,'squeezebox_recv')
                if (cmd == None):
                    return None 
                
                logger.debug("squeezebox: {0} receives updates by \"{1}\"".format(item, cmd))
                if not cmd in self._val:
                    self._val[cmd] = {'items': [item], 'logics': []}
                else:
                    if not item in self._val[cmd]['items']:
                        self._val[cmd]['items'].append(item)
                if ('squeezebox_init' in item.conf):
                    cmd = self._resolv_full_cmd(item,'squeezebox_init')
                    if (cmd == None):
                        return None 
                    
                    logger.debug("squeezebox: {0} is initialized by \"{1}\"".format(item, cmd))
                    if not cmd in self._val:
                        self._val[cmd] = {'items': [item], 'logics': []}
                    else:
                        if not item in self._val[cmd]['items']:
                            self._val[cmd]['items'].append(item)
                            
                if not cmd in self._init_cmds:
                    self._init_cmds.append(cmd)
                
            if 'squeezebox_send' in item.conf:         
                cmd = self._resolv_full_cmd(item,'squeezebox_send')
                if (cmd == None):
                    return None 
                
                logger.debug("squeezebox: {0} is send to \"{1}\"".format(item, cmd))
                return self.update_item
            else:        
                return None
        def parse_logic(self, logic):
            pass
        def update_item(self, item, caller=None, source=None, dest=None):
            # be careful: as the server echoes ALL comands not using this will result in a loop
            if caller != 'LMS':
                cmd = self._resolv_full_cmd(item, 'squeezebox_send').split()
                if self._check_mac(cmd[0]):
                    cmd[0] = urllib2.quote(cmd[0]) 
                if isinstance(item(), str):
                    value = urllib2.quote(item().encode('utf-8'))
                elif (item._type == 'bool'):
                    # convert to get '0'/'1' instead of 'True'/'False'
                    value = int(item()) 
                else:
                    value = item()
                    
                # special handling
                if (len(cmd) >= 2):
                    if (cmd[1] == 'play') and not item():
                        # if 'play' was set to false, send 'stop' to allow single-item-operation
                        cmd[1] = 'stop'
                        value = '1'
                    elif (cmd[1] == 'pause') and not item():
                        # squeezebox un-mutes when un-pausing but does not update the state itself - unmute manually to reflect actual state correctly
                        self._send(cmd[0] + ' mixer muting 0')
                        
                self._send(' '.join(cmd_str for cmd_str in cmd).format(value))
                  
        def _send(self, cmd):
            logger.debug("Sending request: {0}".format(cmd))
            self.push(cmd+'\r\n')
        def _parse_response(self, response):
            data = [urllib2.unquote(data_str) for data_str in response.split()]
            logger.debug("Got: {0}".format(data))
            
    #        if (data[0].lower() == 'player'):
    #            if (data[1].lower() == 'count'):
    #                num_players = int(data[2])
    #                logger.info("Found {0} player".format(num_players))
    #                for i in range(0,num_players):
    #                    self._send("player name {0} ?".format(i))
    #                    self._send("player id {0} ?".format(i))                    
    #            elif (data[1].lower() == 'name'):
    #                logger.info("Players {0} name is: {1}".format(data[2], data[3]))
    #            elif (data[1].lower() == 'id'):
    #                logger.info("Players {0} id is: {1}".format(data[2], data[3]))
            if (data[0].lower() == 'listen'):
                value = int(data[1]) 
                if (value == 1):
                    logger.info("Listen-mode enabled")
                else:
                    logger.info("Listen-mode disabled")
            if self._check_mac(data[0]):
                if (data[1] == 'play'):
                    self._update_items_with_data([data[0], 'play', 1])
                    self._update_items_with_data([data[0], 'stop', 0])
                    self._update_items_with_data([data[0], 'pause', 0])
                    # play also overrules mute
                    self._update_items_with_data([data[0], 'prefset server mute', 0])
                    return
                elif (data[1] == 'stop'):
                    self._update_items_with_data([data[0], 'play', 0])
                    self._update_items_with_data([data[0], 'stop', 1])
                    self._update_items_with_data([data[0], 'pause', 0])
                    return
                elif (data[1] == 'pause'):
                    self._send(data[0] + ' mode ?')
                    self._send(data[0] + ' mixer muting ?')
                    return
                elif (data[1] == 'mode'):
                    self._update_items_with_data([data[0], 'play', data[2] == 'play'])
                    self._update_items_with_data([data[0], 'stop', data[2] == 'stop'])
                    self._update_items_with_data([data[0], 'pause', data[2] == 'pause'])
                    # play also overrules mute
                    return
                elif (data[1] == 'prefset'):
                    if (data[2] == 'server'):
                        if (data[3] == 'volume'):
                            # make sure value is always positive - also if muted!
                            data[4] = abs(int(data[4]))
                elif (data[1] == 'playlist'):
                    if (data[2] == 'newsong'):
                        # trigger reading of other song fields
                        for field in ['genre', 'artist', 'album', 'title', 'duration']:
                            self._send(data[0] + ' ' + field + ' ?')
                elif (data[1] in ['genre', 'artist', 'album', 'title', 'duration']) and (len(data) == 2):
                    # these fields are returned empty so no update takes plase - append '' to trigger update
                    data.append('')           
                    
            self._update_items_with_data(data)
                                    
        def _update_items_with_data(self, data):        
            cmd = ' '.join(data_str for data_str in data[:-1])
            if (cmd in self._val):
                for item in self._val[cmd]['items']:
                    if isinstance(item(), str):
                        data[-1] = data[-1].decode('utf-8')            
                    item(data[-1], 'LMS', "{}:{}".format(self.addr[0],self.addr[1]))
                     
        def found_terminator(self):
            response = self.buffer
            self.buffer = ''
            self._parse_response(response)
        def handle_connect(self):
            self.discard_buffers()
            # start discovering players and their respective IDs and names        
    #        self._send('players 0')
            self._send('listen 1')
            if self._init_cmds != []:
                if self.is_connected:
                    logger.debug('squeezebox: init read')
                    for cmd in self._init_cmds:
                        self._send(cmd+' ?')
            
        def run(self):
            self.alive = True
        def stop(self):
            self.alive = False
            self.handle_close()
    Code:
    # Hobbyraum/Experimental
    [Squeezebox_1]
      squeezebox_playerid = 00:04:20:xx:xx:xx
      [[Name]]
        type = str
        visu = yes
        squeezebox_send = <playerid> name {}   
        squeezebox_recv = <playerid> name    
      [[IP]]
        type = str
        visu = yes
        squeezebox_recv = player ip <playerid>   
      [[Signal_Strength]]
        type = num
        visu = yes
        squeezebox_recv = <playerid> signalstrength    
      [[Power]]
        type = bool
        visu = yes
        squeezebox_send = <playerid> power {}
        squeezebox_recv = <playerid> prefset server power
        squeezebox_init = <playerid> power    
        
      [[Mute]]
        type = bool
        visu = yes
        squeezebox_send = <playerid> mixer muting {}
        squeezebox_recv = <playerid> prefset server mute
        squeezebox_init = <playerid> mixer muting
      [[Volume]]
        type = num
        visu = yes
        squeezebox_send = <playerid> mixer volume {}
        squeezebox_recv = <playerid> prefset server volume
        squeezebox_init = <playerid> mixer volume    
      [[Volume_Up]]
        type = bool
        enforce_updates = true
        visu = yes
        squeezebox_send = <playerid> button volup
      [[Volume_Down]]
        type = bool
        enforce_updates = true
        visu = yes
        squeezebox_send = <playerid> button voldown
        
      [[Play]]
        type = bool
        visu = yes
        squeezebox_send = <playerid> play
        squeezebox_recv = <playerid> play
        squeezebox_init = <playerid> mode
      [[Stop]]
        type = bool
        visu = yes
        squeezebox_send = <playerid> stop
        squeezebox_recv = <playerid> stop
        squeezebox_init = <playerid> mode
      [[Pause]]
        type = bool
        visu = yes
        squeezebox_send = <playerid> pause {}
        squeezebox_recv = <playerid> pause
        squeezebox_init = <playerid> mode
     
      [[Current_Title]]
        type = str
        visu = yes
        squeezebox_recv = <playerid> playlist newsong
        squeezebox_init = <playerid> current_title
      [[Genre]]
        type = str
        visu = yes
        squeezebox_recv = <playerid> genre
      [[Artist]]
        type = str
        visu = yes
        squeezebox_recv = <playerid> artist
      [[Album]]
        type = str
        visu = yes
        squeezebox_recv = <playerid> album
      [[Title]]
        type = str
        visu = yes
        squeezebox_recv = <playerid> title
      [[Duration]]
        type = num
        visu = yes
        squeezebox_recv = <playerid> duration
      [[Playlist_Index]]
        type = num
        visu = yes
        squeezebox_send = <playerid> playlist index {}
        squeezebox_recv = <playerid> playlist index
      [[Playlist_Forward]]
        type = bool
        enforce_updates = true
        visu = yes
        squeezebox_send = <playerid> playlist index +1
      [[Playlist_Backward]]
        type = bool
        enforce_updates = true
        visu = yes
        squeezebox_send = <playerid> playlist index -1
        
      [[Playlist_Name]]
        type = str
        visu = yes
        squeezebox_send = <playerid> playlist name {}
        squeezebox_recv = <playerid> playlist name
      [[Playlist_Save]]
        type = str
        visu = yes
        squeezebox_send = <playerid> playlist save {}   
      [[Playlist_Load]]
        type = str
        enforce_updates = true
        visu = yes
        squeezebox_send = <playerid> playlist play {}
      [[Playlist_Load_Internetradio]]
        type = bool
        enforce_updates = true
        visu = yes
        squeezebox_send = <playerid> playlist play [URL]file:///home/robert/playlists/Internetradio.m3u[/URL]

    Kommentar


      #17
      Hallo Robert,
      hab heute Vormittag noch 2 weitere Player mit Deinem Plugin eingebaut.
      Beim Radio ist es in der Tat scheinbar "nur" ein UTF-8 Problem gewesen.
      Hast Du auch mal ne Playlist von nem Album abgespielet oder "durchlaufen" lassen? Hier "hängt" sich die Bedienung bei mir bei jedem Song mit Umlauten noch auf.

      Kommentar


        #18
        Hi!

        Nein, hab ich noch nicht versucht. Bin (bisher) nicht so der Musikfan der zu Hause Alben hört.

        Kannst du den Fehler genauer beschreiben? Hört der Player auf zu spielen? Oder wird nur der Titel/Interpret falsch angezeigt?

        Versuche das noch zu fixen - dann geht es dieses Wochenende ins GIT.

        Grüße
        Robert

        Kommentar


          #19
          Zitat von Robert Beitrag anzeigen
          Kannst du den Fehler genauer beschreiben? Hört der Player auf zu spielen? Oder wird nur der Titel/Interpret falsch angezeigt?
          In der Anzeige steht dann gar nichts oder der vorherige Titel (ohne Umlaute).Ist unterschiedlich.Der Player spielt dabei weiter.
          Sämtliche Funktionen (Lauter, Leiser, vor, Zurück etc.) werden dann bei Betätigen nicht mehr ausgeführt.
          F5 bleibt erfolglos.
          Springt man dann (z.B. über das Webinterface oder "manuell") zu einem Titel ohne Umlaute muß man die Seite der Visu neu laden oder f5 drücken und es passt läuft wie gewohnt....bis zum nächsten Titel mit Umlaut

          Kommentar


            #20
            Kurze Zwischenfrage, wo geb ich die IP des Servers ein ?

            Hier mal der Anfang meiner item.conf

            Code:
            [squeeze]
              squeezebox_playerid = 00:04:20:1f:92:c4
              [[Name]]
                type = str
                visu = yes
                squeezebox_send = <playerid> Bad {}   
                squeezebox_recv = <playerid> Bad    
              [[IP]]
                type = str
                visu = yes
                squeezebox_recv = player ip <playerid>   
              [[Signal_Strength]]
                type = num
                visu = yes
                squeezebox_recv = <playerid> signalstrength    
              [[Power]]
                type = bool
                visu = yes
                squeezebox_send = <playerid> power {}
                squeezebox_recv = <playerid> prefset server power
                squeezebox_init = <playerid> power    
                
              [[Mute]]
                type = bool
                visu = yes
                squeezebox_send = <playerid> mixer muting {}
                squeezebox_recv = <playerid> prefset server mute
                squeezebox_init = <playerid> mixer muting
              [[Volume]]
                type = num
                visu = yes
                squeezebox_send = <playerid> mixer volume {}
                squeezebox_recv = <playerid> prefset server volume
                squeezebox_init = <playerid> mixer volume    
              [[Volume_Up]]
                type = bool
                enforce_updates = true
                visu = yes
                squeezebox_send = <playerid> button volup
              [[Volume_Down]]
                type = bool
                enforce_updates = true
                visu = yes
                squeezebox_send = <playerid> button voldown
            Grüße
            Umgezogen? Ja! ... Fertig? Nein!
            Baustelle 2.0 !

            Kommentar


              #21
              Zitat von JuMi2006 Beitrag anzeigen
              Kurze Zwischenfrage, wo geb ich die IP des Servers ein ?
              plugin/squeezebox/__init__.py

              dort in der Zeile:
              Code:
              def __init__(self, smarthome, host='127.0.0.1', port=9090):

              Kommentar


                #22
                o.k. ... das muss dann aber noch in die plugin.conf
                Also Robert ... tztztz

                Dank und Gruß!
                Umgezogen? Ja! ... Fertig? Nein!
                Baustelle 2.0 !

                Kommentar


                  #23
                  hat er ja geschrieben ..... zu Beginn

                  [squeezebox]
                  class_name = Squeezebox
                  class_path = plugins.squeezebox

                  Kommentar


                    #24
                    Nein, also der Server gehört doch mit in die Plugin-Konfiguration:

                    [squeezebox]
                    class_name = Squeezebox
                    class_path = plugins.squeezebox
                    server_ip = 192.168.2.222
                    server_port = 9090
                    Localhost kann ja default sein und wird, wenn gesetzt überschrieben. Man sollte als user nicht in der __init__.py rumwühlen müssen. Das bringt am Ende nur unnötigen Supportaufwand.

                    Ansonsten ... was soll ich sagen ... läuft !!!

                    Edit:Hat jemand den lms auf dem Pi am rennen? Hier mag er irgendwie nicht.
                    Umgezogen? Ja! ... Fertig? Nein!
                    Baustelle 2.0 !

                    Kommentar


                      #25
                      Zitat von JuMi2006 Beitrag anzeigen
                      Localhost kann ja default sein und wird, wenn gesetzt überschrieben. Man sollte als user nicht in der __init__.py rumwühlen müssen. Das bringt am Ende nur unnötigen Supportaufwand.
                      Achso ...ja, ok. Da ist was dran

                      Zitat von JuMi2006 Beitrag anzeigen
                      Edit:Hat jemand den lms auf dem Pi am rennen? Hier mag er irgendwie nicht.
                      Ja aber auf einem 2ten Pi. Also nicht auf dem wo sV+Sh.py läuft.
                      Es gibt dafür auch fertige Images. Auch genial einfach.Google mal nach squeezeplug

                      Kommentar


                        #26
                        Danke dann muss ich da mal schnüffeln, nen dritten Pi stell ich mir jetzt nicht noch hin . Wie soll ich das der Gattin vermitteln
                        Umgezogen? Ja! ... Fertig? Nein!
                        Baustelle 2.0 !

                        Kommentar


                          #27
                          Zitat von JuMi2006 Beitrag anzeigen
                          Wie soll ich das der Gattin vermitteln
                          Der fällt im Rack doch gar nicht auf und ist über Flaschenpfand zu finanzieren

                          Kommentar


                            #28
                            Hi!

                            Ja, sorry - ihr habt euch ja schon geholfen. *g*

                            Klar, in der plugin.conf gehören noch optional
                            Code:
                                host = xxx.xxx.xxx.xxx
                                port = xxxx
                            Ich bin dabei den Bug den macflei gemeldet hat zu fixen...

                            Kommentar


                              #29
                              (ab morgen gibt es das Plugin mit Doku im GIT-Repo)

                              Fix für das Problem mit den Umlauten und fix dass die Spielzeit nicht auf 0 gesetzt wurde:

                              Code:
                              #!/usr/bin/env python
                              # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                              #########################################################################
                              # Copyright 2013 Robert Budde                        robert@projekt131.de
                              #########################################################################
                              #  Squeezebox-Plugin for SmartHome.py.  http://mknx.github.com/smarthome/
                              #
                              #  This plugin is free software: you can redistribute it and/or modify
                              #  it under the terms of the GNU General Public License as published by
                              #  the Free Software Foundation, either version 3 of the License, or
                              #  (at your option) any later version.
                              #
                              #  This plugin is distributed in the hope that it will be useful,
                              #  but WITHOUT ANY WARRANTY; without even the implied warranty of
                              #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                              #  GNU General Public License for more details.
                              #
                              #  You should have received a copy of the GNU General Public License
                              #  along with this plugin. If not, see <http://www.gnu.org/licenses/>.
                              #########################################################################
                              
                              import logging
                              import struct
                              import time
                              import urllib2
                              import lib.my_asynchat
                              import re
                              
                              logger = logging.getLogger('Squeezebox')
                              
                              class Squeezebox(lib.my_asynchat.AsynChat):
                              
                                  def __init__(self, smarthome, host='127.0.0.1', port=9090):
                                      lib.my_asynchat.AsynChat.__init__(self, smarthome, host, port)
                                      self._sh = smarthome
                                      self._val = {}
                                      self._obj = {}
                                      self._init_cmds = []
                                      smarthome.monitor_connection(self)
                              
                                  def _check_mac(self, mac):
                                      return re.match("[0-9a-f]{2}([:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", mac.lower())
                                  
                                  def _resolv_full_cmd(self, item, attr):
                                      # check if PlayerID wildcard is used
                                      if '<playerid>' in item.conf[attr]:
                                          # try to get from parent object
                                          parent_item = item.return_parent()
                                          if (parent_item != None) and ('squeezebox_playerid' in parent_item.conf) and self._check_mac(parent_item.conf['squeezebox_playerid']):
                                              item.conf[attr] = item.conf[attr].replace('<playerid>', parent_item.conf['squeezebox_playerid'])
                                          else:
                                              logger.warning("squeezebox: could not resolve playerid for {0} from parent item {1}".format(item, parent_item))
                                              return None
                                      return item.conf[attr] 
                              
                                  def parse_item(self, item):
                                      
                                      if 'squeezebox_recv' in item.conf:         
                                          cmd = self._resolv_full_cmd(item,'squeezebox_recv')
                                          if (cmd == None):
                                              return None 
                                          
                                          logger.debug("squeezebox: {0} receives updates by \"{1}\"".format(item, cmd))
                                          if not cmd in self._val:
                                              self._val[cmd] = {'items': [item], 'logics': []}
                                          else:
                                              if not item in self._val[cmd]['items']:
                                                  self._val[cmd]['items'].append(item)
                              
                                          if ('squeezebox_init' in item.conf):
                                              cmd = self._resolv_full_cmd(item,'squeezebox_init')
                                              if (cmd == None):
                                                  return None 
                                              
                                              logger.debug("squeezebox: {0} is initialized by \"{1}\"".format(item, cmd))
                                              if not cmd in self._val:
                                                  self._val[cmd] = {'items': [item], 'logics': []}
                                              else:
                                                  if not item in self._val[cmd]['items']:
                                                      self._val[cmd]['items'].append(item)
                                                      
                                          if not cmd in self._init_cmds:
                                              self._init_cmds.append(cmd)
                                          
                                      if 'squeezebox_send' in item.conf:         
                                          cmd = self._resolv_full_cmd(item,'squeezebox_send')
                                          if (cmd == None):
                                              return None 
                                          
                                          logger.debug("squeezebox: {0} is send to \"{1}\"".format(item, cmd))
                                          return self.update_item
                                      else:        
                                          return None
                              
                                  def parse_logic(self, logic):
                                      pass
                              
                                  def update_item(self, item, caller=None, source=None, dest=None):
                                      # be careful: as the server echoes ALL comands not using this will result in a loop
                                      if caller != 'LMS':
                                          cmd = self._resolv_full_cmd(item, 'squeezebox_send').split()
                                          if self._check_mac(cmd[0]):
                                              cmd[0] = urllib2.quote(cmd[0]) 
                                          if isinstance(item(), str):
                                              value = urllib2.quote(item().encode('utf-8'))
                                          elif (item._type == 'bool'):
                                              # convert to get '0'/'1' instead of 'True'/'False'
                                              value = int(item()) 
                                          else:
                                              value = item()
                                              
                                          # special handling
                                          if (len(cmd) >= 2):
                                              if (cmd[1] == 'play') and not item():
                                                  # if 'play' was set to false, send 'stop' to allow single-item-operation
                                                  cmd[1] = 'stop'
                                                  value = '1'
                                              elif (cmd[1] == 'pause') and not item():
                                                  # squeezebox un-mutes when un-pausing but does not update the state itself - unmute manually to reflect actual state correctly
                                                  self._send(cmd[0] + ' mixer muting 0')
                                                  
                                          self._send(' '.join(cmd_str for cmd_str in cmd).format(value))
                                            
                              
                                  def _send(self, cmd):
                                      logger.debug("Sending request: {0}".format(cmd))
                                      self.push(cmd+'\r\n')
                              
                                  def _parse_response(self, response):
                                      data = [urllib2.unquote(data_str) for data_str in response.split()]
                                      logger.debug("Got: {0}".format(data))
                                      
                                      if (data[0].lower() == 'listen'):
                                          value = int(data[1]) 
                                          if (value == 1):
                                              logger.info("Listen-mode enabled")
                                          else:
                                              logger.info("Listen-mode disabled")
                              
                                      if self._check_mac(data[0]):
                                          if (data[1] == 'play'):
                                              self._update_items_with_data([data[0], 'play', 1])
                                              self._update_items_with_data([data[0], 'stop', 0])
                                              self._update_items_with_data([data[0], 'pause', 0])
                                              # play also overrules mute
                                              self._update_items_with_data([data[0], 'prefset server mute', 0])
                                              return
                                          elif (data[1] == 'stop'):
                                              self._update_items_with_data([data[0], 'play', 0])
                                              self._update_items_with_data([data[0], 'stop', 1])
                                              self._update_items_with_data([data[0], 'pause', 0])
                                              return
                                          elif (data[1] == 'pause'):
                                              self._send(data[0] + ' mode ?')
                                              self._send(data[0] + ' mixer muting ?')
                                              return
                                          elif (data[1] == 'mode'):
                                              self._update_items_with_data([data[0], 'play', data[2] == 'play'])
                                              self._update_items_with_data([data[0], 'stop', data[2] == 'stop'])
                                              self._update_items_with_data([data[0], 'pause', data[2] == 'pause'])
                                              # play also overrules mute
                                              return
                                          elif (data[1] == 'prefset'):
                                              if (data[2] == 'server'):
                                                  if (data[3] == 'volume'):
                                                      # make sure value is always positive - also if muted!
                                                      data[4] = abs(int(data[4]))
                                          elif (data[1] == 'playlist'):
                                              if (data[2] == 'newsong'):
                                                  # trigger reading of other song fields
                                                  for field in ['genre', 'artist', 'album', 'title', 'duration']:
                                                      self._send(data[0] + ' ' + field + ' ?')
                                          elif (data[1] in ['genre', 'artist', 'album', 'title']) and (len(data) == 2):
                                              # these fields are returned empty so no update takes plase - append '' to trigger update
                                              data.append('')           
                                          elif (data[1] in ['duration']) and (len(data) == 2):
                                              # these fields are returned empty so no update takes plase - append '0' to trigger update
                                              data.append('0')           
                                              
                                      self._update_items_with_data(data)
                                                              
                                  def _update_items_with_data(self, data):        
                                      cmd = ' '.join(data_str for data_str in data[:-1])
                                      if (cmd in self._val):
                                          for item in self._val[cmd]['items']:
                                              if isinstance(item(), str) or isinstance(item(), unicode):
                                                  data[-1] = data[-1].decode('utf-8')            
                                              item(data[-1], 'LMS', "{}:{}".format(self.addr[0],self.addr[1]))
                                               
                                  def found_terminator(self):
                                      response = self.buffer
                                      self.buffer = ''
                                      self._parse_response(response)
                              
                                  def handle_connect(self):
                                      self.discard_buffers()
                                      # enable listen-mode to get notified of changes        
                                      self._send('listen 1')
                                      if self._init_cmds != []:
                                          if self.is_connected:
                                              logger.debug('squeezebox: init read')
                                              for cmd in self._init_cmds:
                                                  self._send(cmd + ' ?')
                                      
                                  def run(self):
                                      self.alive = True
                              
                                  def stop(self):
                                      self.alive = False
                                      self.handle_close()

                              Kommentar


                                #30
                                Anleitung für den LMS auf dem Pi:

                                All Things Pi
                                Umgezogen? Ja! ... Fertig? Nein!
                                Baustelle 2.0 !

                                Kommentar

                                Lädt...
                                X