Ankündigung

Einklappen
Keine Ankündigung bisher.

Squeezebox Client mit smarthome.py

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

    Squeezebox Client mit smarthome.py

    Hallo,

    Das Thema hat nur indirekt mit smarthome.py zu tun, sondern eher mit der Python programmierung,
    aber da smarthome.py auf Python basiert, und hier viele dieser Programmiersprache mächtig sind,
    hoffe ich dass mir hier jemand helfen kann (oder will).

    Leider hab ich von Python nicht direkt viel Ahnung, hab bisher nur kleinere Smarthome-Logiken mit Copy-and-Paste erstellt.
    Programmierung hab ich bisher nur mit Atmel Prozessoren in verbindung mit Bascom gemacht.

    Ich bin gerade dabei mir einen Squeezebox Client auf basis eines RaspberryPi zu basteln,
    nach dem vorbild dieses Projektes: http://www.emmaanuel.com/SqueezeBerr...and-Squeezebox

    Das Script auf dieser Seite nutzt den Telnet-Port des Squeezebox Servers zur kommunikation,
    dieser Telnet Port ist bei mir aber dauerhaft durch das SqueezeboxPlugin von smarthome.py belegt.
    Nun will ich die Steuerung meines Musikplayers über das Network-Plugin von smarthome.py steuern.
    Ich hab mir dazu in der items Datei einen UDP Sender definiert, der mir Lautstärke und Titelinfo an den Player sendet,
    und am Player hab ich mir ein Python Script erstellt, welches mir die Infos zerlegt, und auf einem 4x20 Zeichen Display anzeigt.

    Zusätzlich hab ich noch ein zweites Script erstellt, dass mir die Bedienung des Gerätes ermöglicht.
    Wie auf der Projektseite hab ich ebenfalls ein Endlos-Poti für die Lautstärke, und 4 Buttons, die als Favoritentasten für die wichtigsten Sender dienen sollen.

    Die beiden Scripte funktionieren unabhängig voneinander schonmal ganz gut, allerdings würde ich die beiden scripte gerne vereinen, so dass es als ein ganzes Script funktioniert.
    Allerdings fehlt mir da jetzt etwas das grundverständnis von Python, so dass ich da nicht weiterkomme.
    vor allem hab ich die class und def Bereiche noch nicht so ganz verstanden.
    Deshalb wäre ich hier für ein paar Codeverbesserungen oder anregungen sehr dankbar.

    Vor allem würde ich z.B. gerne wenn man beim Taster auf Pause schaltet das Display leeren und ausschalten,
    und bei Play wieder einschalten, aber meine Versuche die beiden Scripte zu vereinen scheiterten bisher immer.
    entweder kommen fehlermeldungen beim Starten des Scriptes, oder das Script startet, hängt dann aber in der UDP Schleife fest,
    so dass Tastenbefehle erst reagieren, wenn eine Titelinfo über UDP empfangen wurde.

    Item-Datei von Smarthome:
    Code:
    [Squeezebox_5]
      squeezebox_playerid = b8:27:eb:04:a6:55
    
      [[UDP-Sender]]
          type = str
          enforce_updates = true
          eval_trigger = Squeezebox_5.Current_Title | Squeezebox_5.Volume
          eval = sh.nw.udp('192.168.0.94',7073,'Volume: '+sh.Squeezebox_5.Volumestr()+' , '+sh.Squeezebox_5.Current_Title())
    
      [[Power]]
        type = bool
        squeezebox_send = <playerid> power {}
        squeezebox_recv = <playerid> prefset server power
        squeezebox_init = <playerid> power    
        nw = yes
        
      [[Volume]]
        type = num
        squeezebox_send = <playerid> mixer volume {}
        squeezebox_recv = <playerid> prefset server volume
        squeezebox_init = <playerid> mixer volume
      [[Volumestr]]
        type = str
        eval_trigger = Squeezebox_5.Volume
        eval = str(sh.Squeezebox_5.Volume())
        nw = yes
            
      [[Volume_Up]]
        type = bool
        enforce_updates = true
        squeezebox_send = <playerid> button volup
        nw = yes
      [[Volume_Down]]
        type = bool
        enforce_updates = true
        squeezebox_send = <playerid> button voldown
        nw = yes
        
      [[Play]]
        type = bool
        squeezebox_send = <playerid> play
        squeezebox_recv = <playerid> play
        squeezebox_init = <playerid> mode
        nw = yes
      [[Stop]]
        type = bool
        squeezebox_send = <playerid> stop
        squeezebox_recv = <playerid> stop
        squeezebox_init = <playerid> mode
        nw = yes
      [[Pause]]
        type = bool
        squeezebox_send = <playerid> pause {}
        squeezebox_recv = <playerid> pause
        squeezebox_init = <playerid> mode
        nw = yes
        
      [[Current_Title]]
        type = str
        squeezebox_recv = <playerid> playlist newsong
        squeezebox_init = <playerid> current_title
        enforce_updates = true
    
        [[AntenneBayern]]
              type = bool
              enforce_updates = true
              squeezebox_send = <playerid> playlist play http://opml.radiotime.com/Tune.ashx?id=s42824&partnerId=16
              nw = yes
        [[Rockantenne]]
              type = bool
              enforce_updates = true
              squeezebox_send = <playerid> playlist play http://opml.radiotime.com/Tune.ashx?id=s25217&partnerId=16
              nw = yes
        [[Bayern3]]
              type = bool
              enforce_updates = true
              squeezebox_send = <playerid> playlist play http://opml.radiotime.com/Tune.ashx?id=s14991&partnerId=16
              nw = yes
        [[Bayern1]]
              type = bool
              enforce_updates = true
              squeezebox_send = <playerid> playlist play http://opml.radiotime.com/Tune.ashx?id=s24854&partnerId=16
              nw = yes
    UDP Empfänger und LCD Ansteuerung:
    (LCD Ansteuerung stammt auch aus dem Internet, und ist ursprünglich für ein HD44780 Controller, ich hab es lediglich für den KS0073 Controller meines Displays angepasst.)

    Code:
    #!/usr/bin/python
     
    # The wiring for the LCD is as follows:
    # 1 : GND
    # 2 : 5V
    # 3 : Contrast (0-5V)*
    # 4 : RS (Register Select)
    # 5 : R/W (Read Write)       - GROUND THIS PIN
    # 6 : Enable or Strobe
    # 7 : Data Bit 0             - NOT USED
    # 8 : Data Bit 1             - NOT USED
    # 9 : Data Bit 2             - NOT USED
    # 10: Data Bit 3             - NOT USED
    # 11: Data Bit 4
    # 12: Data Bit 5
    # 13: Data Bit 6
    # 14: Data Bit 7
    # 15: LCD Backlight +5V**
    # 16: LCD Backlight GND
     
    #import
    import socket
    import RPi.GPIO as GPIO
    import time
    
    # UDP Adresse konfigurieren
    Quelle='192.168.0.94'
    Port=7073
     
    # Define GPIO to LCD mapping
    LCD_RS = 7
    LCD_E  = 8
    LCD_D4 = 25
    LCD_D5 = 24
    LCD_D6 = 23
    LCD_D7 = 18
    LCD_Backlight = 15
     
    # Define some device constants
    LCD_WIDTH = 20    # Maximum characters per line
    LCD_CHR = True
    LCD_CMD = False
     
    LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
    LCD_LINE_2 = 0xA0 # LCD RAM address for the 2nd line
    LCD_LINE_3 = 0xC0 # LCD RAM address for the 2nd line
    LCD_LINE_4 = 0xE0 # LCD RAM address for the 2nd line
     
    # Timing constants
    E_PULSE = 0.0005
    E_DELAY = 0.0005
     
    def main():
      # Main program block
      GPIO.setwarnings(False)
      GPIO.setmode(GPIO.BCM)       # Use BCM GPIO numbers
      GPIO.setup(LCD_E, GPIO.OUT)  # E
      GPIO.setup(LCD_Backlight, GPIO.OUT)
      GPIO.setup(LCD_RS, GPIO.OUT) # RS
      GPIO.setup(LCD_D4, GPIO.OUT) # DB4
      GPIO.setup(LCD_D5, GPIO.OUT) # DB5
      GPIO.setup(LCD_D6, GPIO.OUT) # DB6
      GPIO.setup(LCD_D7, GPIO.OUT) # DB7
     
      # UDP Socket init
      e_udp_sock = socket.socket( socket.AF_INET,  socket.SOCK_DGRAM )
      e_udp_sock.bind( (Quelle,Port) )
     
      # Initialise display
      lcd_init()
     
      while True:
        
        GPIO.output(15, True)
        
        data, addr = e_udp_sock.recvfrom( 1024 )
    #    print data[:11]
    #    print data[13:33]
    #    print data[33:]
    
        # Send some test
        lcd_string(data[13:33],LCD_LINE_1)
        lcd_string(data[33:],LCD_LINE_2)
        lcd_string("--------------------",LCD_LINE_3)
        lcd_string(data[:11],LCD_LINE_4)
        
    def lcd_init():
      # Initialise display
      time.sleep(E_DELAY)
      lcd_byte(0x33,LCD_CMD) # 110011 Initialise
      lcd_byte(0x32,LCD_CMD) # 110010 Initialise
      lcd_byte(0x2C,LCD_CMD) # 000110 Cursor move direction
      lcd_byte(0x09,LCD_CMD) # 000110 Cursor move direction
      lcd_byte(0x28,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
      lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
      lcd_byte(0x01,LCD_CMD) # 000001 Clear display
      time.sleep(E_DELAY)
      time.sleep(E_DELAY)
      time.sleep(E_DELAY)
      lcd_byte(0x06,LCD_CMD) # 101000 Data length, number of lines, font size
     
    def lcd_byte(bits, mode):
      # Send byte to data pins
      # bits = data
      # mode = True  for character
      #        False for command
     
      GPIO.output(LCD_RS, mode) # RS
     
      # High bits
      GPIO.output(LCD_D4, False)
      GPIO.output(LCD_D5, False)
      GPIO.output(LCD_D6, False)
      GPIO.output(LCD_D7, False)
      if bits&0x10==0x10:
        GPIO.output(LCD_D4, True)
      if bits&0x20==0x20:
        GPIO.output(LCD_D5, True)
      if bits&0x40==0x40:
        GPIO.output(LCD_D6, True)
      if bits&0x80==0x80:
        GPIO.output(LCD_D7, True)
     
      # Toggle 'Enable' pin
      lcd_toggle_enable()
     
      # Low bits
      GPIO.output(LCD_D4, False)
      GPIO.output(LCD_D5, False)
      GPIO.output(LCD_D6, False)
      GPIO.output(LCD_D7, False)
      if bits&0x01==0x01:
        GPIO.output(LCD_D4, True)
      if bits&0x02==0x02:
        GPIO.output(LCD_D5, True)
      if bits&0x04==0x04:
        GPIO.output(LCD_D6, True)
      if bits&0x08==0x08:
        GPIO.output(LCD_D7, True)
     
      # Toggle 'Enable' pin
      lcd_toggle_enable()
     
    def lcd_toggle_enable():
      # Toggle enable
      time.sleep(E_DELAY)
      GPIO.output(LCD_E, True)
      time.sleep(E_PULSE)
      GPIO.output(LCD_E, False)
      time.sleep(E_DELAY)
     
    def lcd_string(message,line):
      # Send string to display
     
      message = message.ljust(LCD_WIDTH," ")
     
      lcd_byte(line, LCD_CMD)
     
      for i in range(LCD_WIDTH):
        lcd_byte(ord(message[i]),LCD_CHR)
     
    if __name__ == '__main__':
     
      try:
        main()
      except KeyboardInterrupt:
        pass
      finally:
        lcd_byte(0x01, LCD_CMD)
        lcd_string("Goodbye!",LCD_LINE_1)
        GPIO.output(15, False)
        GPIO.cleanup()
    Taster und Drehpoti Auswertung:
    Code:
    #!/usr/bin/python
    
    import socket
    import gaugette.rotary_encoder
    import gaugette.switch
    import RPi.GPIO as GPIO
     
    A_PIN  = 7
    B_PIN  = 9
    SW_PIN = 0
    #GPIO.setwarnings(False)
    #GPIO.setmode(GPIO.BOARD)
    #GPIO.setup(15, GPIO.IN)
    
    Ziel='192.168.0.234'
    Port=2727
     
    #encoder = gaugette.rotary_encoder.RotaryEncoder(A_PIN, B_PIN)
    encoder = gaugette.rotary_encoder.RotaryEncoder.Worker(A_PIN, B_PIN)
    encoder.start()
    switch = gaugette.switch.Switch(SW_PIN)
    last_state = None
    last_gpio = None
    s_udp_sock = socket.socket( socket.AF_INET,  socket.SOCK_DGRAM )
     
    while True:
        delta = encoder.get_delta()
        if delta<0:
        #print "lauter"
             s_udp_sock.sendto( 'item|Squeezebox_5.Volume_Up|1', (Ziel,Port) )
        #r = requests.get('http://192.168.0.234:2727',data=('item|Squeezebox_5.Volume_Down|1)')
        elif delta>0:
        #print "leiser"
             s_udp_sock.sendto( 'item|Squeezebox_5.Volume_Down|1', (Ziel,Port) )
        #if delta!=0:
            #print "lauter %d" % delta
        #print "lauter"
     
        sw_state = switch.get_state()
        if sw_state != last_state:
            if last_state == 1:
                  #s_udp_sock.sendto( 'logic|dreamcommand|'(last_state), (Ziel,Port) )
                s_udp_sock.sendto( 'logic|dreamcommand|123', (Ziel,Port) )
        #print "switch %d" % sw_state
        last_state = sw_state
            
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(15, GPIO.IN)
        if GPIO.input(15) != last_gpio:
            if last_gpio == 0:
                s_udp_sock.sendto( 'item|Squeezebox_5.Bayern3|1', (Ziel,Port) )
        #print "switch %d" % GPIO.input(15)
        last_gpio = GPIO.input(15)
    #      # Wenn der Button gedrueckt wird
    #    else:
    #        print "1"
    
    GPIO.cleanup()
    Zuletzt geändert von Mike01; 18.08.2016, 14:23.
Lädt...
X