Multiroom-Audio: WLAN-Lautsprecher selber bauen

Wie ich das Thema Multiroom-Audio bei mir umgesetzt habe, habe ich ja hier schon erklärt. In diesem Beitrag möchte ich Euch nun zeigen, wie ich meine WLAN-Lautsprecher selber gebaut habe. Im Grunde ist da auch nicht viel dabei: Wir nutzen idealerweise einen Lautsprecher, den wir noch irgendwo herumfliegen haben und bauen da zwei Netzteile, einen Raspberry Pi, Verstärker und noch ein paar Kleinigkeiten ein. Dann haben wir das Gröbste geschafft.Selbstgebauter WLAN-Lautsprecher

Im Ergebnis erhalten wir dann einen aktiven WLAN-Lautsprecher, der sich per Logitech Media Server und den zugehörigen Apps ansteuern lässt, ein AirPlay-Empfänger für Apple-Geräte und ein DLNA-Renderer für andere Geräte liefert. Außerdem können die Grundfunktionen mit einer IR-Fernbedienung gesteuert werden. Um Stromkosten zu sparen, wird der Verstärker abgeschaltet, wenn er nicht benötigt wird.

Hardware

Material für einen WLAN-Lautsprecher

Beginnen wir mit dem benötigten Material. Das Ganze ist lediglich als Vorschlag zu verstehen und kann nach belieben angepasst werden. Ich habe viel Wert auf die Balance zwischen Preis und Leistung gelegt, immerhin soll der WLAN-Lautsprecher ja auch bezahlbar bleiben. Insbesondere das Kleinmaterial findet sich bestimmt in der ein oder anderen Schublade bei Euch zuhause.

Lautsprecher auna Line 501 HifiRaspberry Pi ZeroPHAT DACSure electronics TDA7498 100W VerstärkerSanDisk Ultra 16GB
WLAN-Stick mit abnehmbarer AntenneAntennenkabel mit RP-SMA-Stecker und RP-SMA-Einbaubuchse2-Kanal-Relaismodul5V-Netzteil24V-Netzteil
C8-EinbaubuchseChinch- und KlinkensteckerPrint-Anschlussklemme RM 5,0mmApple RemoteTSOP 4838 IR-Empfänger

Verstärker

Als ich den ersten WLAN-Lautsprecher gebaut habe, habe ich als Verstärker gleich mehrere TDA7498 100W Stereo Power Amp von Sure Electronics bestellt. Dieses Angebot gibt es jedoch nicht mehr, dafür jede Menge gute Alternativen. Zur Auswahl eines passenden Verstärkers folgende Tipps:

  • Die Angegebenen Leistungen sind in der Regel Spitzenleistungen, die nur bei extremen Spitzen und Lautsprechern mit 4Ω Impedanz erreicht werden.
  • Die tatsächliche Leistung ist auch von der Höhe der Spannung abhängig, mit der der Verstärker betrieben wird. Oft sind Bereiche von 9…30V DC, oder 14…36V DC angegeben. Je höher die Spannung, desto höher die Leistung.
  • Hilfreich ist immer ein Blick ins Datenblatt. Da sind meist Diagramme drin, mit denen man den optimalen Arbeitspunkt bestimmen kann.
  • Der Arbeitspunkt sollte so gewählt werden, dass die Verzerrung (THD) nicht zu hoch ist.
  • Mit der Spannungsversorgung wird der Arbeitspunkt dann festgelegt. Für meinen Verstärker und meine Ansprüche sind 28V optimal.
  • Netzteile, die 28V liefern, gibt es kaum. Man kann jedoch die Ausgangsspannung vieler 24V-Netzteile einstellen. Bei meinem ist die Obergrenze 27,6V. Die habe ich auch eingestellt.

Nach nunmehr über einem Jahr kann ich sagen, dass ich mit den Verstärkern von Sure Electronics sehr zufrieden bin. Es gab bisher keinerlei Ausfälle, Überhitzungen oder sonstige Probleme an meinen WLAN-Lautsprechern. Den Lüfter, der auf dem Kühlkörper montiert ist, hab ich übrigens abgeklemmt. Zum einen ist der recht laut und erzielt innerhalb eines geschlossenen Gehäuses kaum einen Effekt. Zum anderen wird der Verstärker auch nicht übermäßig warm, sodass ich darauf verzichten kann.

Alternatives Material

Ich habe schon verschiedene Komponenten verbaut und manchmal musste ich recht lange nach einer passenden oder preisgünstigen Lösung suchen. Deshalb nachfolgend noch 4 Dinge, die ich im ersten WLAN-Lautsprecher verbaut hatte. Damals noch mit einem Raspberry Pi Modell A. Vielleicht könnt Ihr ja etwas davon gebrauchen.

Lautsprecher zerlegen

Fangen wir also an. Wenn das Material beschafft ist, zerlegen wir den Lautsprecher in sämtliche Einzelteile. Ich habe zudem das Anschlussterminal komplett zerlegt. Darin sollen später Stromanschluss und WLAN-Antenne montiert werden.

Lautsprecher in seine Einzelteile zerlegt

Danach muss man einen Weg finden, wie man die ganzen Einzelteile am besten im Gehäuse unterbringt. Das kann relativ langwierig sein, wenn wenig Platz vorherrscht. Alle Teile müssen so gedreht werden, dass man sie nachher auch noch anschließen kann. Ganz wichtig dabei: man sollte in der Lage sein, die SD-Karte vom Raspberry Pi auszutauschen, ohne alles komplett zerlegen zu müssen.

Bei den von mir verwendeten Teilen ist folgende Anordnung sinnvoll (Gehäuse liegt wie oben abgebildet):

  • Rückwand: Netzteile (links oben und links unten)
  • Linke Seitenwand: Raspberry Pi + PHAT DAC
  • Rechte Seitenwand: Frequenzweiche
  • Unten: Verstärker und Relais-Modul

Einzelteile vorbereiten

Audiokabel löten

Das Audiokabel stellt die Verbindung zwischen der Soundkarte und dem Verstärker her. Wir nehmen zwei Drähte und löten sie zuerst am Chinch-Stecker an. Der Draht des inneren Kontaktes wird dann mit dem innern Kontakt des Klinkensteckers verbunden. Anschließend werden die beiden äußeren miteinander verbunden. Am Klinkenstecker bleibt der Kontakt, der zwischen dem inneren und dem äußeren liegt, frei, da es sich bei diesem WLAN-Lautsprecher um ein reines Mono-Gerät handelt. Sonst müsste man ein Y-Kabel bauen (oder kaufen). Nicht vergessen, die Gehäuse der Stecker über die Drähte zu schieben, bevor der zweite Stecker angelötet wird.

Chinch- und KlinkensteckerChinchstecker lötenKlinkenstecker lötenFertiges Audiokabel

Anschlussterminal

Im Anschlussterminal werden die C8-Buchse für den Stromanschluss, sowie das Antennenkabel montiert. Mit einer RJ45-Kupplung kann man den Lautsprecher auch perfekt für ein Netzwerkkabel vorbereiten. Die Umrisse habe ich auf der Rückseite angezeichnet, mit einem Bohrer in die Ecken gebohrt und den Rest mit Nadelfeilen weggefeilt.

C8-EinbaubuchseAntennenkabel mit RP-SMA-Stecker und RP-SMA-EinbaubuchseAnschlussterminal mit C8-Buchse und Antennenbuchse
RJ45-KupplungAnschlussterminal mit C8-Buchse und RJ45-Kupplung

Wer auf eine richtige Werkstatt verzichten muss und stattdessen alles nur am heimischen Schreibtisch machen kann, dem empfehle ich diesen Mini-Schraubstock.

Frequenzweiche löten

Um Platz im Gehäuse zu schaffen, wird die Frequenzweiche an einer neuen Stelle montiert. Die angelöteten Kabel sind dafür leider etwas zu kurz, daher habe ich die alten Drähte entfernt und neue angelötet. Weiß ist hier die Masse, die farbigen Drähte jeweils das Signal. Braun = Audiosignal vom Verstärker, Grau = Signal zum Tieftöner, Orange = Signal zum Hochtöner.

Frequenzweiche mit den alten DrähtenFrequenzweiche mit neuen, längeren Drähten

Micro-USB-Kabel

Die Seite mit dem normalen USB-Stecker wird abgeschnitten (benötigen wir auch nicht mehr). Vom verbleibenden Kabelende (das mit dem Micro-USB-Stecker) entfernen wir ein Stück von der Ummantelung und schneiden den Schirm, den weißen und den gelben Draht ab. Vom roten und schwarzen Draht wird etwas Isolierung entfernt und Aderendhülsen aufgepresst.

Micro-USB-KabelMicro-USB-Kabel

Sonstiges

Die zwei Stiftleisten werden jeweils auf den Raspberry Pi Zero, sowie den PHAT DAC gelötet. Die zweipolige Anschlussklemme ist für den Verstärker gedacht, der für die Spannungsversorgung nur einen Hohlstecker besitzt. Direkt daneben befinden sich jedoch die Lötpunkte für ein Schraubterminal.

Komponenten einbauen und verkabeln

Wenn die Vorbereitungen abgeschlossen sind, machen wir uns an den Einbau und die Verdrahtung der Komponenten. Wie zu erkennen ist, habe ich die Soundkarte nicht huckepack auf den Raspberry Pi gesetzt, sondern daneben gesetzt beide mit Drähten verbunden. Dies schien mir angesichts dessen, dass noch weitere Komponenten an die GPIO angeschlossen werden müssen, die einfachste Lösung.

Verdrahtung der Komponenten im WLAN-Lautsprecher

Verdrahtung der Komponenten im WLAN-Lautsprecher

Es gilt nun, alle Komponenten im Lautsprechergehäuse einzubauen. Je nach Größe des Gehäuses kann einen das schon zur Verzweiflung bringen. Daher noch ein paar Tipps, wie es etwas einfacher geht:

  • Drähte einseitig anschließen und das jeweils andere Ende frei hängen lassen, bevor man die Komponenten einbaut. So muss man nur das jeweils andere Drahtende innerhalb des Gehäuses anschließen.
  • Komponenten, die im hinteren Teil des Gehäuses montiert werden sollen, zuerst einbauen.
  • Teilweise ist es einfacher, wenn man die Löcher ohne die Komponenten erstmal vorbohrt. Das geht auch mit den Schrauben, mit denen die Teile nachher befestigt werden sollen.
Einbau der Komponenten im WLAN-Lautsprecher (1/6)Einbau der Komponenten im WLAN-Lautsprecher (2/6)Einbau der Komponenten im WLAN-Lautsprecher (3/6)Einbau der Komponenten im WLAN-Lautsprecher (4/6)Einbau der Komponenten im WLAN-Lautsprecher (5/6)Einbau der Komponenten im WLAN-Lautsprecher (6/6)

Der mechanische Teil unseres WLAN-Lautsprechers ist nun weitestgehend fertig. Kommen wir also zur Software.

Software

Image aufspielen

Im Beitrag Raspberry Pi: meine Standardkonfiguration habe ich die schonmal recht ausführlich erläutert beschrieben, wie ich meine Raspberry Pi einrichte. Da der Schwerpunkt hier jedoch auf einem funktionierenden WLAN-Lautsprecher liegt, beschränken wir uns hier auf das Wesentliche und nutzen die Boardmittel.

Statt des offiziellen Images von der Raspberry Pi-Downloadseite verwenden wir hier eines, das den benötigten Player bereits beinhaltet. Es gibt da verschiedene zur Auswahl, die je nach Geschmack und Anspruch gewisse Vorteile bieten.

  • piCorePlayer: Basiert auf Tiny Core Linux und ist extrem schlank und schnell, sehr übersichtlich und Komfortabel, läuft selbst auf der schwächsten Hardware und den ältesten Speicherkarten. Einziger Nachteil für mich: keine python-lirc-Bibliothek verfügbar. Somit funktioniert mein Script mit der Fernbedienung leider nicht. Das Image ist nur 78 MB groß.
  • Max2Play: Basiert auf Raspbian und liefert entsprecht auch alles mit, was man gewöhnt ist. Für verschiedene Soundkarten gibt es auch optimierte Images. Allerdings ist die „beworbene“ Oberfläche meiner Ansicht nach viel zu unübersichtlich, schlecht erklärt, recht durcheinander und keineswegs etwas für Anfänger, die sich überhaupt nicht auskennen. Außerdem muss selbst für recht einfache Dinge eine Lizenz erworben werden.

Die PHAT DAC Soundkarte besitzt den gleichen Soundchip wie die HiFiBerry DAC/DAC+ Light, deshalb verwende ich das für HifiBerry optimierte Image von Max2Play. Da ich keine der sonst angebotenen Features benötige, komme ich auch ohne Lizenz aus.

Wenn der Download abgeschlossen ist, spielen wir das Image auf.

Netzwerk einrichten

Wer wie ich einen Raspberry Pi Zero benutzt, hat nun erstmal das Problem, dass dieser keinen LAN-Port besitzt und WLAN erst noch konfiguriert werden muss. Dafür gibt es verschieden-einfache Wege:

  1. Falls der WLAN-Stick eine WPS-Taste besitzt, kann die WPS-Funktion von Max2Play genutzt werden.
  2. Die SD-Karte in einen normalen Raspberry Pi stecken, diesen per Kabel ins Netzwerk holen, die WLAN-Einstellungen vornehmen, und die Karte dann in den Pi Zero packen.
  3. Den Pi Zero zusammen mit einem USB-Hub, sowie WLAN-Stick, Tastatur und/oder Maus an einen Bildschirm anschließen und die Daten direkt einstellen.
  4. Google bemühen.

Für mich ist Variante 2 die einfachste, und mit der geht es auch weiter.

Die Einstellungen nehmen wir per Weboberfläche vor. Diese ist in der Regel unter max2play.local zu erreichen. Alternativ findet Ihr die IP-Adresse über den Router. Anschließend navigieren wir zum Menüpunkt „WLAN & LAN“, geben SSID und Passwort des Netzwerkes ein, oder nutzen die Scan-Funktion.

Max2Play: WLAN-Einstellungen

Max2Play: WLAN-Einstellungen

Soundkarte einstellen

In dem von mir verwendeten HifiBerry-Image kann man direkt auf der Startseite den entsprechenden Typen der Soundkarte auswählen.

Max2Play: HifiBerry-Karte auswählen

Max2Play: HifiBerry-Karte auswählen

Im Standardimage wird die Soundkarte unter dem Menüpunkt „Raspberry Einstellungen“ ausgewählt, sofern man eine Lizenz besitzt. Besitzt man diese nicht, kann man unter dem Menüpunkt „Audioplayer“ lediglich zwischen den vorkonfigurierten wählen. Alternativ können Soundkarten per Kommandozeile eingestellt werden. Dafür benötigt man keine Lizenz.

$ sudo nano /boot/config.txt

Am Ende der Datei kann per dtoverlay die Soundkarte eingestellt werden. Bei meiner sähe das so aus:

dtoverlay=hifiberry-dac

Playername und Dateisystem

Als nächstes geben wir dem WLAN-Lautsprecher einen vernünftigen Namen, mit dem er dann auch im Logitech Media Server angezeigt wird. Dies geschieht im Menü „Einstellungen / Reboot“. Hier können auch Sprache und Zeitzone eingestellt werden.

Max2Play: Playernamen einstellen

Max2Play: Playernamen einstellen

Beim Benennen des Players wird gleichzeitig auch der Hostname angepasst. Mir persönlich gefällt das nicht so gut, deshalb werde ich diesen später nochmal über die Kommandozeile anpassen.

Dann noch das obligatorische Expandieren des Dateisystems. Die passende Schaltfläche befindet sich auf der gleichen Seite etwas weiter unten.

Max2Play: Dateisystem expandieren

Max2Play: Dateisystem expandieren

Erweiterte Konfiguration & LIRC

Passwort & Hostname

Für die Steuerung unseres WLAN-Lautsprechers per Apple Remote (oder einer anderen Fernbedienung) und das Abschalten des Verstärkers, wenn dieser nicht benötigt wird, müssen wir auf der Kommandozeile noch ein paar Einstellungen vornehmen. Dazu verbinden wir uns per SSH und loggen uns mit dem Benutzernamen pi und dem Passwort raspberry ein.

Optional: Bei Bedarf das Passwort ändern:

$ sudo passwd pi

Optional: Um dem Raspberry Pi einen anderen Hostname zu geben, begeben wir uns über die aktive SSH-Verbindung in die Konfigurationsoberfläche…

$ sudo raspi-config

…wählen 9 Advanced Options -> A2 Hostname und tragen hier den neuen Hostname ein. Wir verlassen die Oberfläche und starten neu.

LIRC installieren & konfigurieren

Über das Thema LIRC, und wie man Python-Scripte mittels Fernbedienung steuert, hatte ich hier schon einmal sehr ausführlich geschrieben. Daher machen wir hier einen Schnelldurchlauf. Zuerst installieren wird LIRC:

$ sudo apt-get update

$ sudo apt-get install lirc python-lirc

Nach Abschluss der Installation machen wir uns an die Konfiguration. Als erstes der „Autostart“ von LIRC.

$ sudo nano /etc/modules

Die markierten Zeilen werden einfach unten angehangen.

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
# Parameters can be specified after the module name.

lirc_dev
# GPIO in BCM-Zählweise
lirc_rpi gpio_in_pin=23

Auf Zeile 9 geben wir in BCM-Zählweise an, welchen GPIO wir mit LIRC nutzen wollen – also die GPIO-Nummer, nicht die Pin-Nummer. Danach passen wir die Hardware-Konfiguration von LIRC an.

$ sudo nano /etc/lirc/hardware.conf

Hier tragen wir für LIRCD_ARGSDRIVERDEVICE und MODULES die Werte wie abgebildet ein.

# /etc/lirc/hardware.conf
#
# Arguments which will be used when launching lircd
LIRCD_ARGS="--uinput"

#Don't start lircmd even if there seems to be a good config file
#START_LIRCMD=false

#Don't start irexec, even if a good config file seems to exist.
#START_IREXEC=false

#Try to load appropriate kernel modules
LOAD_MODULES=true

# Run "lircd --driver=help" for a list of supported drivers.
DRIVER="default"
# usually /dev/lirc0 is the correct setting for systems using udev
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"

# Default configuration files for your hardware if any
LIRCD_CONF=""
LIRCMD_CONF=""

Zuletzt müssen wir noch einen Eintrag in der Datei /boot/config.txt ergänzen.

$ sudo nano /boot/config.txt

Hier passen wir Zeile 51 wie folgt an:

# Uncomment this to enable the lirc-rpi module
dtoverlay=lirc-rpi,gpio_in_pin=23

Tasten-Mapping & Aktionen

Wer eine andere Fernbedienung als die Apple Remote nutzen möchte, startet den Raspberry Pi jetzt neu und macht an dieser Stelle weiter. Alle mit Apple Remote können mein Tasten-Mapping einfach übernehmen.

$ sudo nano /etc/lirc/lircd.conf

Die Datei befüllen wir, je nach verwendetem IR-Empfänger, mit folgendem Inhalt:

TSOP 31238

# Please make this file available to others
# by sending it to <lirc@bartelmus.de>
#
# this config file was automatically generated
# using lirc-0.9.0-pre1(default) on Tue Aug 18 19:23:09 2015
#
# contributed by
#
# brand:                       /home/pi/lircd.conf
# model no. of remote control:
# devices being controlled by this remote:

begin remote

  name  appleremote
  bits            8
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  header       9058  4422
  one           624  1595
  zero          624   497
  ptrail        623
  repeat       9058  2194
  pre_data_bits   16
  pre_data       0x77E1
  post_data_bits  8
  post_data      0x4E
  gap          107798
  toggle_bit_mask 0x0

      begin codes
          KEY_UP                   0xD0
          KEY_DOWN                 0xB0
          KEY_LEFT                 0x10
          KEY_RIGHT                0xE0
          KEY_OK                   0xBA 0x20
          KEY_MENU                 0x40
          KEY_PLAYPAUSE            0x7A 0x20
      end codes

end remote
TSOP 4838

# Please make this file available to others
# by sending it to <lirc@bartelmus.de>
#
# this config file was automatically generated
# using lirc-0.9.0-pre1(default) on Sun Oct 16 17:40:15 2016
#
# contributed by
#
# brand:                       /home/pi/lircd.conf
# model no. of remote control:
# devices being controlled by this remote:

begin remote

  name  appleremote
  bits            8
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  header       9057  4419
  one           600  1616
  zero          600   525
  ptrail        600
  repeat       9058  2190
  pre_data_bits   16
  pre_data       0x77E1
  post_data_bits  8
  post_data      0x4E
  gap          107804
  toggle_bit_mask 0x0

      begin codes
          KEY_UP                   0xD0
          KEY_DOWN                 0xB0
          KEY_LEFT                 0x10
          KEY_RIGHT                0xE0
          KEY_OK                   0xBA 0x20
          KEY_MENU                 0x40
          KEY_PLAYPAUSE            0x7A 0x20
      end codes

end remote


Damit beim Tastendruck auch etwas passiert, werden Aktionen definiert. In unserem Fall wollen wir lediglich die Information, welche Taste gedrückt wurde, per String an unser Steuer-Script übergeben. Dazu erzeugen wir uns die Datei lircrc

$ sudo nano /etc/lirc/lircrc

…und packen folgenden Inhalt rein:

# ~/.lircrc
#
# button: Name der Taster (wie angelernt)
# prog:   Ziel, wohin die Information übergeben werden soll (Socket oder Programm)
# config: Übergebener String

# Apple Remote
# KEY_UP
# KEY_DOWN
# KEY_LEFT
# KEY_RIGHT
# KEY_OK
# KEY_MENU
# KEY_PLAYPAUSE

begin
    button = KEY_UP
    prog = appleremote
    config = KEY_UP
end

begin
    button = KEY_DOWN
    prog = appleremote
    config = KEY_DOWN
end

begin
    button = KEY_LEFT
    prog = appleremote
    config = KEY_LEFT
end

begin
    button = KEY_RIGHT
    prog = appleremote
    config = KEY_RIGHT
end

begin
    button = KEY_OK
    prog = appleremote
    config = KEY_OK
end

begin
    button = KEY_MENU
    prog = appleremote
    config = KEY_MENU
end

begin
    button = KEY_PLAYPAUSE
    prog = appleremote
    config = KEY_PLAYPAUSE
end

Damit ist LIRC fertig eingerichtet und der WLAN-Lautsprecher soweit vorbereitet. Sollte es später irgendwelche Probleme mit LIRC geben, findet Ihr in oben genanntem Beitrag auch Möglichkeiten, die Teilschritte einzeln zu testen.

Zum Abschluss starten wir den Raspberry Pi neu.

Steuerscript für den WLAN-Lautsprecher

Damit die Fernbedienung den WLAN-Lautsprecher steuern kann und der Verstärker beim Abspielen von Musik auch eingeschaltet wird, benötigen wir noch ein Script, das mit dem Server kommuniziert und die entsprechenden Informationen besorgt, bzw. weiterleitet. Eins auf diesen Lautsprecher zugeschnittenes findet Ihr unten. Vom Grunde her könnt Ihr das Script auch 1:1 übernehmen.

Wir erzeugen also die Script-Datei…

$ nano ~/squeezebox-control.py

…und packen folgenden Inhalt hinein:

#!/usr/bin/env python
#coding: utf-8 

####################################################################
# squeezebox-control.py
# Script zur Steuerung eines WLAN-Lautsprechers
# von Sebastian Köhler - https://indibit.de
#
# LETZTE ÄNDERUNG:	17.04.2016
####################################################################

import fcntl, socket, struct	# für MAC-Adresse
import lirc
import RPi.GPIO as GPIO
import sys
import telnetlib
import thread
import time

# ----------------------------------------------------------------------------
#  Konfiguration
# ----------------------------------------------------------------------------
HOST            = "192.168.243.5"   # IP-Adresse des LMS
PORT            = "9090"            # CLI-Port des LMS
OFF_DELAY       = 180               # Verstärker-Abschalt-Verzögerung (in Sekunden)
VOL_NORM        = 50                # Lautstärke, die nach beim Einschalten eingestellt werden soll

# ----------------------------------------------------------------------------
#  sonstige Variablen
# ----------------------------------------------------------------------------
mac = ''       # MAC-Adresse
status = ''    # Status des Players
tn = ''        # Telnet-Verbindung
lastPlay = 0   # Zeit, wann der Player das letzte Mal gespielt hat

# ----------------------------------------------------------------------------
#  MAC-Adresse auslesen
# ----------------------------------------------------------------------------
def getMAC(ifname):
	s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', ifname[:15]))
	return '%3A'.join(['%02x' % ord(char) for char in info[18:24]])

# ----------------------------------------------------------------------------
#  Telnet-Verbindung herstellen
# ----------------------------------------------------------------------------
def tn_connect():
	global tn
	try:
		tn = telnetlib.Telnet(HOST,PORT)
		player("startup")
	except:
		time.sleep(10)

# ----------------------------------------------------------------------------
#  WLAN-Lautsprecher bei Start initialisieren
# ----------------------------------------------------------------------------
def startup():
	setGPIO("startup","")
	tn_connect()

# ----------------------------------------------------------------------------
#  Fernbedienung/LIRC abfragen
# ----------------------------------------------------------------------------
def remote():
	while True:
		try:
			codeIR = lirc.nextcode()
			if codeIR != []:
				if codeIR[0] == 'KEY_UP':
					player('vol_up')			
				elif codeIR[0] == 'KEY_DOWN':
					player('vol_down')
				elif codeIR[0] == 'KEY_LEFT':
					player('back')
				elif codeIR[0] == 'KEY_RIGHT':
					player('next')
				elif codeIR[0] == 'KEY_OK':
					pass
				elif codeIR[0] == 'KEY_MENU':
					player('playlist')
				elif codeIR[0] == 'KEY_PLAYPAUSE':
					if status == "play":
						player('pause')
					else:
						player('play')
			time.sleep(0.05)
		except:
			time.sleep(0.1)
	
# ----------------------------------------------------------------------------
#  Befehle senden, Status abfragen
# ----------------------------------------------------------------------------
def player(cmd):
	p0 = ""
	p1 = ""
	p2 = ""
	if cmd == "startup":
		try:
			player("stop")
			#tn.write("subscribe play,pause,stop,playlist\r")
			tn.write(mac + " mode ?\r")
			resetVol()
		except (EOFError, socket.error):
			tn_connect()
			
	else:
		if cmd == "play":               # Wiedergabe
			p0 = "play"
		elif cmd == "pause":            # Pause
			p0 = "pause"
		elif cmd == "stop":             # Stop
			p0 = "stop"
		elif cmd == "back":             # Titel zurück
			p0 = "playlist"
			p1 = "index"
			p2 = "-1"
		elif cmd == "next":             # Titel überspringen
			p0 = "playlist"
			p1 = "index"
			p2 = "%2B1"
		elif cmd == "vol_up":           # Lauter
			p0 = "mixer"
			p1 = "volume"
			p2 = "%2B5"
		elif cmd == "vol_down":         # Leiser
			p0 = "mixer"
			p1 = "volume"
			p2 = "-5"
		elif cmd == "playlist":         # Playlist abspielen
			p0 = "playlist"
			p1 = "play"
			p2 = "smooth_jazz.m3u"
		else:
			p0 = ""
			p1 = ""
			p2 = ""

		if p0 != "":
			try:
				tn.write(mac + " " + p0 + " " + p1 + " " + p2 + "\r")
			except (EOFError, socket.error):
				tn_connect()
	
	p0 = ""
	p1 = ""
	p2 = ""

def getStatus():
	while True:
		global status
		try:
			tn.write(mac + " mode ?\r")
			q = tn.read_until('\r')
			s = q.split('\r')[0].split(' ')
			if s:
				if s[0] == mac:

					if s[1] == "mode":
						status = s[2]

		except (EOFError, socket.error):
			tn_connect()
		except KeyboardInterrupt:
			getOut()
		time.sleep(0.1)

# ----------------------------------------------------------------------------
#  Verstärker am WLAN-Lautsprecher ein-/ausschalten
# ----------------------------------------------------------------------------
def ampOnOff():
	global lastPlay
	if status == "play":
		setGPIO("amp","on")
		lastPlay = time.time()
	else:
		if time.time() - lastPlay >= OFF_DELAY:
			if status == "pause":
				resetVol()
				player("stop")
			setGPIO("amp","off")

def setGPIO(channel,state):
	amp = 22
	on  = GPIO.LOW
	off = GPIO.HIGH

	if channel == "startup":
		GPIO.output(22, GPIO.HIGH)
		#GPIO.output(24, GPIO.HIGH)
	else:
		if (channel in locals()) and (state in locals()):
			GPIO.output(locals()[channel], locals()[state])

# ----------------------------------------------------------------------------
#  Standard-Lautstärke setzen
# ----------------------------------------------------------------------------
def resetVol():
	try:
		tn.write(mac + " mixer volume " + str(VOL_NORM) + " \r")
	except (EOFError, socket.error):
		tn_connect()
	
# ----------------------------------------------------------------------------
#  Script beenden
# ----------------------------------------------------------------------------
def getOut():
	GPIO.cleanup()
	sys.exit(0)

# ----------------------------------------------------------------------------
#  Hauptprogramm
# ----------------------------------------------------------------------------
if __name__ == '__main__':
	#GPIO.setwarnings(False)
	GPIO.setmode(GPIO.BOARD)                            # Zählweise der Pins festlegen
	GPIO.setup(22, GPIO.OUT)                            # Pin 22 (GPIO 25) = Verstärker-Relais 1
	#GPIO.setup(24, GPIO.OUT)                           # Pin 24 (GPIO  8) = Verstärker-Relais 2
	sockid=lirc.init("appleremote", blocking = False)   # Fernbedienung einbinden

	mac = getMAC('wlan0')
	startup()

	thread.start_new_thread(getStatus,())
	thread.start_new_thread(remote,())

	while True:
		try:
			ampOnOff()
			n = True
			time.sleep(0.1)
		except KeyboardInterrupt:
			getOut()

Auf den Zeilen 23 bis 26, und 133 müsst Ihr die für Euch zutreffenden Daten eintragen.

  • Zeile 23 (HOST): Die IP-Adresse des Computers/NAS ein, auf dem der Logitech Media Server läuft.
  • Zeile 24 (PORT): Der Port für die Steuerung per Telnet. Den Findet Ihr so heraus: Im LMS -> Einstellungen -> Erweitert -> Befehlszeilenschnittstelle (CLI) [oben links im Dropdown-Menü auswählen].
  • Zeile 25 (OFF_DELAY): Zeit, die verstreichen muss, bis der Verstärker abgeschaltet wird, wenn die Wiedergabe pausiert wird.
  • Zeile 26 (VOL_NORM): Lautstärke die automatisch eingestellt wird, wenn der Verstärker sich ausschaltet (STOP) oder bei Neustart des Raspberry Pi, bzw. LMS
  • Zeile 133: Hier könnt Ihr eine Playlist festlegen, die beim Drücken auf die Menü-Taste an der Apple-Remote abgespielt wird.

Die Tasten auf der Fernbedienung sind in diesem Script wie folgt belegt:

  • hoch/runter: lauter/leiser
  • links/rechts: nächster/vorheriger Titel
  • Mitte: nicht belegt
  • Menü: spielt voreingestellte Playlist ab
  • Play/Pause: befindet sich der Player im Ruhezustand, wird das abgespielt, was zuletzt wiedergegeben wurde. Pause pausiert, anschließend Play setzt die Wiedergabe fort

Das Script muss noch ausführbar gemacht werden:

$ chmod +x ~/squeezebox-control.py

Autostart nach Reboot

Damit alles auch nach einem Stromausfall oder Neustart wie gewünscht von alleine läuft, muss das Script noch automatisch gestartet werden. Im Blog von Stephen C. Phillips habe ich eine tolle Möglichkeit gefunden, das Script als Dienst laufen zu lassen.

Dazu legen wir zuerst das Start-/Stopp-Script an…

$ sudo nano /etc/init.d/squeezebox-control

… und befüllen es mit folgendem Inhalt:

#!/bin/sh

### BEGIN INIT INFO
# Provides:          myservice
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Squeezebox-control
# Description:       Reads IR input and controls GPIO for switching the AMP
### END INIT INFO

# Change the next 3 lines to suit where you install your script and what you want to call it
DIR=/home/pi
DAEMON=$DIR/squeezebox-control.py
DAEMON_NAME=squeezebox-control

# Add any command line options for your daemon here
DAEMON_OPTS=""

# This next line determines what user the script runs as.
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
DAEMON_USER=root

# The process ID of the script when it runs is stored here:
PIDFILE=/var/run/$DAEMON_NAME.pid

. /lib/lsb/init-functions

do_start () {
    log_daemon_msg "Starting system $DAEMON_NAME daemon"
    start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
    log_end_msg $?
}
do_stop () {
    log_daemon_msg "Stopping system $DAEMON_NAME daemon"
    start-stop-daemon --stop --pidfile $PIDFILE --retry 10
    log_end_msg $?
}

case "$1" in

    start|stop)
        do_${1}
        ;;

    restart|reload|force-reload)
        do_stop
        do_start
        ;;

    status)
        status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
        ;;

    *)
        echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
        exit 1
        ;;

esac
exit 0

Auf den Zeilen 14 und 15 könnt Ihr Pfad und Dateinamen anpassen, falls Ihr die anders gewählt habt, als ich vorgeschlagen habe.

Jetzt muss das Script noch ausführbar gemacht werden…

$ sudo chmod +x /etc/init.d/squeezebox-control

… und dem System bekannt gemacht werden, dass das neue Start-/Stopp-Script existiert und verarbeitet werden soll:

$ sudo update-rc.d squeezebox-control defaults

Das Ganze kann nun wie folgt gesteuert werden:

Status abfragen$ /etc/init.d/squeezebox-control status
Script starten$ sudo /etc/init.d/squeezebox-control start
Script stoppen$ sudo /etc/init.d/squeezebox-control stop
Script neustarten$ sudo /etc/init.d/squeezebox-control restart

Automatischer Neustart

Von Zeit zur Zeit kann es vorkommen, dass nach ein paar Tagen Laufzeit der Lautsprecher nur noch sehr träge oder garnicht mehr reagiert. Das passiert bei mir bei einem Lautsprecher, der von einem Raspberry Pi 1 Modell B gesteuert wird. Offensichtlich gibt es dort ein Problem mit dem wenigen Speicher, den dieses Modell besitzt. Abhilfe schaft es bei mir, das Steuerscript regelmäßig neu zu starten. Dazu legen wir einen passenden Cronjob an, der als root ausgeführt wird (weitere Informationen über Cron hier).

$ sudo crontab -e

Am Ende der Datei fügen wir folgenden Inhalt ein:

0 4 * * * /etc/init.d/squeezebox-control restart

Damit wird jede Nacht 4:00 Uhr das Script neu gestartet und eventuell vollgelaufener Speicher geleert.
Hinweis: Es wird nur das Steuerscript neu gestartet, nicht der gesamte Raspberry Pi.

Nach einem letzten Neustart ist der WLAN-Lautsprecher nun vollständig betriebsbereit. Viel Spaß  😎

Sebastian

Sebastian

...ist staatlich geprüfter Techniker für Elektrotechnik, Schwerpunkt Prozessautomatisierung und Energietechnik. Die Themen Automatisierung und Programmierung haben es ihm besonders angetan.
Außerdem ist er für jede technische Spielerei zu haben 😉
Sebastian

106 Comments

  1. Antworten Sebastian

    Hi Sebastian,

    Prima Anleitung! Mich würde der energieverbrauch interessieren wenn gerade kein stream übertragen wird, also nur das Netzteil den raspizero + phatdac im wartemodus betreibt.

    Gruß Basti

    • Sebastian
      Antworten Sebastian

      Hi,
      wirklich interessante Frage. Hab direkt mal nachgemessen: mit der Kombination Pi Zero, Phat Dac, WLAN-Stick und Netzteil (also wie hier beschrieben) sind das ca. 2,5W. Macht im Jahr 21,9kWh.

      • Antworten Sebastian

        Ah, das geht ja. Hatte überlegt das ganze per wifi Relais schaltbar zu machen, aber viel mehr holt man damit auch nicht mehr raus. Danke fürs nachmessen!

  2. Antworten Sebastian

    Nochmal ne Frage zum 24v Netzteil. Das von dir verwendete hat nur ca. 25 Watt wenn ich das richtig auf dem Bild sehe. Der Lautsprecher bei vollast aber 50watt. Wie bist du jetzt auf die Leistung beim Netzteil gekommen? Hängt eher vom verstärker ab, oder? Hab mir einen verstärker mit 2×50 Watt ausgesucht, da ich gerne den zweiten Lautsprecher mit nutzen möchte für echtes stereo. Allerdings bin ich mir nicht sicher wie ich das Netzteil dafür dimensionieren sollte. Irgendwelche tipps? Bei nem 100 Watt Netzteil ist das dann auch ein ganz schönes Trumm.

    Grüße
    P.S. Gibt’s einen besonderen Grund für das doppel Relais Modul?

    • Sebastian
      Antworten Sebastian

      Im Grunde richtet sich die Größe des Netzteils nach dem eingesetzten Verstärker. Und hier liegt die Krux: Viele Hersteller, insbesondere die von günstigen Komponenten, geben als Leistung irgendwelche Spitzenwerte an niederohmigen Lautsprechern an. Und selbst diese Werte sind immer noch ein ganzes Stück vom „normalen Musikhören“ entfernt. Sure electronics bildet hier keine Ausnahme.

      Als Faustformel, und das hat vor Jahren schon im Car-Hifi-Bereich funktioniert, nehme ich einfach die Hälfte des angegebenen Wertes und liege selbst damit noch über der Realität. Für meinen Verstärker sieht das so aus: Angegeben ist 2x100W @4Ohm = 200W
      Ich betreibe den Lautsprecher mono = 100W
      Mein Lautsprecher hat nicht 4Ohm, sondern 8Ohm = 50W
      Davon dann die Hälfte = 25W

      Fachlich ist das natürlich nicht besonders genau, aber deutlich näher an der Realität. In Wirklichkeit liegt die Leistung noch ein Stück darunter, denn die ist auch vom Arbeitspunkt des Verstärkers abhängig. Der wird entsprechend Datenblatt mit der Höhe der Spannungsversorgung festgelegt. Dazu gibt es unter der Überschrift „Verstärker“ noch ein paar Hinweise.

      Zum Relaismodul: dass das ein 2er-Modul ist liegt einfach daran, dass ich kein 1er finden konnte 😉

      • Antworten Sebastian

        Ah, ok, das ist schon mal ein Guter Ratschlag. Vielleicht teste ich den Verstärker erstmal mit nem labornetzteil und prüfe die maximalen Leistungspeaks. Wobei ich noch nicht genau weiß wie ich das messen soll. Digital Multimeter müsste da nen Spitzenwert merken. Sowas kann meins nur nicht.
        Ich denke es macht sicher auch Sinn einen Elko mit 35V und 1000uF am Netzteil Ausgang parallel zu schließen um das Netzteil bei Spitzen zu entlasten. Oder nicht so viel überlegen und einfach über den Daumen peilen 🙂

  3. Antworten Jens

    Hallo,
    das ist ja eine super Anleitung. Da ich mich mit dem Thema schon länger beschäftige, leider aber ein ziemlich Unerfahren in dem Thema bin, hat mir vor allem die Ausführlichkeit besonders gut gefallen.
    Ich habe ein Frage zu den Boxen. Gab es für die verwendeten Boxen einen bestimmten Grund. Ich habe bei mir noch 2 ältere 2 Wege Boxen, für die ich derzeit keine Verwendung habe. Könnte ich diese auch nehmen?
    Danke für die Hilfe

    Jens

    • Sebastian
      Antworten Sebastian

      Hallo Jens,
      für die Lautsprecher hab ich mich entschieden, weil sie mir optisch gut gefallen haben.
      Im Prinzip funktioniert auch jeder andere, der groß genug ist, dass die ganzen Komponenten ins Gehäuse passen.

      • Antworten Jens

        Hallo Sebastian,
        vielen Dank für die schnelle Antwort. Hast du schon Erfahrungen mit dem Betreiben der Boxen im Bad? Muß man da wegen der manchmal auftretenden Feuchtigkeit mehr Vorsichtsmaßnahmen treffen?

        • Sebastian
          Antworten Sebastian

          Im Prinzip sollte man schon darauf achten, dass der Lautsprecher für den jeweiligen Standort geeignet ist. Das kann ich jetzt nicht an Fakten oder Vorschriften darlegen, sondern muss da einfach mit gesundem Menschenverstand an die Sache heran gehen.

          Ich glaube, der verständlichste Punkt ist folgender:
          Wenn man mal richtig heiß duscht, entsteht eine hohe Luftfeuchtigkeit. Die Feuchtigkeit schlägt sich an Wänden und Gegenständen nieder. Besteht jetzt das Gehäuse aus gepresstem Holz und ist nicht besonders behandelt, dann nimmt das Holz vielleicht die Feuchtigkeit auf und quillt auf.
          Aus diesem Standpunkt heraus würde ich also Lautsprecher aus Kunststoff empfehlen und ich hab da auch schon eine Idee, die ich jedoch noch nicht ausprobiert habe:
          Es gibt bei Amazon Bluetooth Lautsprecher, die ziemlich gut bewertet sind. Da sind naturgemäß Spannungsversorgung und Verstärker bereits eingebaut. Heißt, man müsste eigentlich nur noch einen Weg finden, einen Pi Zero und die Soundkarte da zu integrieren und die interne Elektronik geschickt zu nutzen oder abzuklemmen.
          Ich will das auf alle Fälle mal probieren und werde dann sicher auch darüber berichten. Nur wann das wird, kann ich heute noch nicht sagen.

  4. Antworten Jens

    Hallo Sebastian,
    vielen Dank für die schnellen Antworten. Ich bin gerade dabei meine Einkaufsliste zusammen zu stellen. Habe aber ein bisschen Probleme mit dem Verstärker und dem Sound Modul.Das Phat Dac habe ich nicht gefunden. Ich denke, ich kann da auch auf die HifiBerry Dac+ um switchen, wobei die preislich sicher deutlich höher liegt. Das Bundle von Pimoroni gibt es zu mindestens bei Amazon gerade nicht. Beim Verstärker weis ich gar nicht so recht. Da gibt es so viele. Und an Hand von Parameter – keine Ahnung. Ich habe jetzt einmal den „TDA7498 Leistungsverstaerkermodul – SODIAL(R)TDA7498 Binaural Stereo 2x100W High Power digital“ oder den „Sure Electronics 2×100 Watt TRIPATH Digitalverstärker Amplifier Board – STA508 „, jeweils bei Amazon in die engere Wahl gezogen. Wobei ich nicht weis ob sich der teurere lohnt. Hast Du einen Tipp wo man den Raspberry Zero gut bekommen kann?

    • Sebastian
      Antworten Sebastian

      Hi Jens,
      das Bundle gibts tatsächlich derzeit nicht bei Amazon. Aber einzeln ist der PHAT DAC noch verfügbar: http://amzn.to/2iqT6RP. Sonst würde ich Dir Pimoroni direkt empfehlen. Der Versand dauert etwas, aber Du bekommst beides für einen guten Preis.
      Pi Zero: https://shop.pimoroni.com/products/raspberry-pi-zero
      PHAT DAC: https://shop.pimoroni.com/products/phat-dac
      Man muss übrigens keinen Pi Zero verwenden und auch nicht unbedingt diese Soundkarte. Meinen ersten Lautsprecher hatte ich mit einem Raspberry Pi A und der USB-Soundkarte http://amzn.to/2jjb3pu gebaut. Funktioniert genauso gut. Und der PHAT DAC würde auch an einem normalen RPi funktionieren.

      Bei den Verstärkern wird es etwas schwieriger. Zu dem von SODIAL hab ich überhaupt keine hilfreichen Informationen, geschweige denn ein Datenblatt/Anleitung des Herstellers finden können. Insofern geht hier Probieren über Studieren. Da ich mit Sure Electronics aber bereits gute Erfahrungen gemacht habe und die auch eine vernünftige Dokumentation liefern, kann ich deren Verstärker auch empfehlen. Auf deren Webseite gibts eine ziemlich große Auswahl und auch der, den ich nutze, ist noch verfügbar: http://store3.sure-electronics.com/2-x-100-watt-class-d-audio-amplifier-board-tda7498

      • Antworten Jens

        Hallo Sebastian,
        vielen Dank für Deine Hilfe. Dann werde ich jetzt mal shoppen gehen und dann mal schauen wie es klappt. Wenn es passt würde ich zur gegebenen Zeit Dioch weiter als Informationsquelle anzapfen. 😉

          • Antworten Jens

            Hallo Sebastian,
            noch mal eine Frage zu dem Verstärker. Reicht an sich nicht auch der
            2 x 25 Watt Klasse D Audioverstärkerplatine – TDA7492
            für einen kleineren Raum. 100W klingt immer so viel. 😉

            • Sebastian
              Antworten Sebastian

              Die Frage kannst nur Du allein beantworten, dafür kennen wir uns einfach zu wenig.
              Probier‘ den einfach aus, beurteile das selber und berichte dann von Deinen Erfahrungen 😉

              • Antworten Jens

                Hallo Sebastian,
                ich war in den letzten Tagen zeimlich viel shoppen. Leider ist aber noch nicht alles angekommen. Trotzdem habe ich ein bissel experimentiert.Und da sind doch glatt neue Fragen und Probleme aufgetreten. Mein NAS ist eine Buffalo LS-WXL. Auf der ist schon der Squeezebox-Server. Leider aber nicht in der aktuellen Variante. Laut Auskunft der Hotline geht es auch nicht diesen selbst zu aktualisieren. Keine Ahnung ob das was ausmacht. Ich habe Version 7.5.1. Nur schlecht ist, daß mir immer angezeigt wird, daß er im abgesicherten Modus läuft. Hast Du damit Erfahrungen?
                Das andere Frage ist. Ich möchte auch meine Musik vom NAS auf meine etwas ältere Anlage bringen. Wo, oder besser an welchen Parametern kann ich sehen ob die Eingänge das überhaupt hergeben. Mein receiver ist von Technics. Ein: SA -DX930. Man kann, zu mindestens laut Bedienungsanleitung, analoge und digitale Geräte anschließen. Dann sollte das doch eigentlich gehen oder?

                • Sebastian
                  Antworten Sebastian

                  Hi Jens,
                  Deinen NAS kenne ich nicht, aber andere von Buffalo. Bei denen, die ich kenne, konnte man sich Zugriff per SSH verschaffen und hatte so die Möglichkeit, Software nach zu installieren. Aber eigentlich sollte es auch mit einer älteren Version funktionieren.
                  Alternativ installierst Du LMS auf dem Raspberry Pi und bindest die Dateifreigabe des NAS (mit der Musik) einfach dort ein.
                  Soweit ich das erkennen konnte besitzt Dein Technics-Receiver normale Chinch-Eingänge. Die kannst Du einfach verwenden. Da der Receiver ja einen integrierten Verstärker besitzt, benötigst Du für den Raspberry Pi keinen weiteren. Du musst also nur den RPi mit Spannung versorgen, Soundkarte dran und die mit dem Receiver verbinden.

                  • Antworten Jens

                    Hi Sebastian,
                    Zugriff per SSH bedeutet doch aber, daß man die Zugangsdaten weiß. Ich komme zwar per putty hin, scheiter dann aber an diesen Daten. (die ich nicht kenne)
                    Ja er hat Chinch Eingänge. Ich habe gestern mal versucht. Leider aber kam noch kein Ton raus. Meine Kombi:Raspberry 3 plus Hifiberry + zero plus Volumio.

                    • Jens

                      Hallo Sebastian,
                      nochmal wegen dem LMS auf den Raspberry. Ich habe das mal versucht und noch nicht ganz hinbekommen. Falls das aber mal klappen sollte und der Pi dann mein LMS ist mit den entsprechenden Freigaben zu meinem NAS, muß dieser dann auch immer an sein. ist das richtig?

                    • Jens

                      Habe jetzt den LMS auf dem PI installiert.Wie mache ich das mit dem Einbinden der Dateifreigabe des NAS? NAS und PI sind im gleichen Netz.
                      Leider wird auch meine Hifiberry DAC+ zero nicht erkannt. Ich habe sie auf die Steckleiste gesteckt. Aber irgendwie wird sie nicht erkannt. Muss ich da noch etwas tun?

                    • Jens

                      Hallo Sebastian,
                      noch eine dumme Frage. Von wo genau gehen die Kabel zum Lautsprecher weg?

                    • Sebastian
                      Sebastian

                      Vom Verstärker-Ausgang zur Frequenzweiche (falls vorhanden), und von da zu den Lautsprechern.

                    • Jens

                      Hallo Sebastian,
                      dank Deiner guten Anleitung habe ich heute meinen ersten Wlan-Lautsprecher fertig bekommen. Es sind aber doch ein paar kleine Fragen offen.
                      Die Einbindung der Apple Remote hat noch nicht richtig geklappt. Das Komische dabei. Ich habe es vorher entsprechend Deiner Extra Anleitung getestet und da hat es meiner Meinung auch geklappt.Also zumindestens habe ich bei dem Test im Terminal die „Tastensignale“ gesehen.
                      Ich werde einfach noch mal alles von vorne eingeben. Vlleicht klappt es ja dann. Aber zu den Einstellungen noch ein Frage. Gibt es die Möglichkeit mit der Remote sowas wie ein richtiges „aus“ oder „an“ zu erreichen? Oder ist das schon und ich habe es nur übersehen.
                      Ach und wegen dem Lüfter vom Verstärker. Wenn ich das richtig in Erinnerung habe, hattest Du den abgeklemmt. Hast Du damit schon Erfahrungen gemacht ob das so passt?

                    • Sebastian
                      Sebastian

                      Bei meinem Verstärker ist der Lüfter definitiv nicht nötig. Läuft ohne ihn absolut problemlos.
                      Was meinst Du mit an und aus bei der Fernbedienung?

                    • Jens

                      Okay, das ist gut zu wissen. Naja und wegen der Fernbedienung. Ich hatte so gedacht, daß mit der auch den Lautsprecher aus oder anschalten kann.

                    • Sebastian
                      Sebastian

                      Der Lautsprecher schaltet sich doch selber ein, sobald etwas abgespielt wird. Und er schaltet sich auch automatisch wieder aus. Was willst du da noch ein- und ausschalten?
                      Du kannst Dir ja sonst auch das Script anpassen, wie du es gerne hättest.

                    • Jens

                      Ja hast recht. Ich hatte da einen falschen Gedankengang. Aber leider bekomme ich die Apple Remote nicht zum Laufen. Ich habe jetzt auch deine Extra Anleitung mal ausprobiert, dort auch die Tasten angelernt und auch die Dateien aus der Anleitung hier, noch mal geprüft. Mit dem Ipad kann ich den Lautsprecher prima bedienen, aber mit der Fernbedienung geht gar nichts. Wo ist da mein Fehler?

                    • Sebastian
                      Sebastian

                      Schwierig, mit so wenig Informationen. Läuft denn das Script? Bau doch mal ein paar Prints ein und schaue, was das Script überhaupt macht.
                      Hast du das Script auch richtig konfiguriert? Man muss ja noch ein paar Sachen anpassen, damit es richtig läuft.

                    • Jens

                      Ich habe es. Sorry…ein Kabel war um eine Stelle falsch gesteckt.
                      Danke noch mal für die prima Anleitung.

                    • Jens

                      Hallo Sebastian,
                      noch mal eine Frage zu den Boxen. Würde es auch gehen das an und ausschalten über einen Bewegungs Melder zu steuern?

                    • Sebastian
                      Sebastian

                      Hallo Jens,
                      grundsätzlich spricht da nichts dagegen. Ich vermute, Du willst den Bewegungsmelder über die GPIO abfragen. Dann müsstest Da das Script entsprechend um die Abfrage erweitern und einfach den gewünschten Befehl auslösen, wie es in remote() getan wird.
                      Wenn Du also beispielsweise die Playlist abspielen willst, die Du auch von der Fernbedienung aus startest, müsstest Du den Befehl player('playlist') bei erkannter Bewegung auslösen.
                      Als nächstes müsstest Du Dir dann überlegen, wie lange die Playlist laufen soll. Soll sie solange laufen, bis man Stop drückt, war es das dann schon. Soll jedoch die Musik nach einer gewissen Zeit von alleine wieder anhalten, muss das natürlich im Script entsprechend berücksichtigt werden.

                    • Jens

                      Hallo Sebastian,
                      okay, ich glaube dann frage ich noch mal wenn ich das Teil zusammengebaut habe. Eine Frage habe ich gleich noch. Und zwar wegen der „Playliste“ welche abgespielt wenn ich Menü drücke. Aber irgendwie fehlt mir da noch das Verständnis. Ich habe gesehen, daß Du eine Playliste in die „squeezebox-control.py – Datei“ eingetragen hast. Aber wo muß die liegen? und womit hast Du die erstellt? Ich habe versucht eine Playlist im LMS zu erstellen und auch abzuspeichern. as hat auch geklappt. Kann die auch abspielen wenn ich Sie direkt in der Android-App unter „Wiedergabelisten“ anwähle. Aber wahrscheinlich sind das 2 verschiedene Dinge die „Wiedergabelisten“ in der APP und die Playlist in der squeezebox-control. Aber kanns Du mir sagen wie ich die zusammenbringen kann?

                    • Sebastian
                      Sebastian

                      Du bist auf dem richtigen Weg. Eine beliebige Playlist, die auf den Server existiert, kannst Du dort eintragen. Es wird dann einfach der Befehl „spiele Playlist xxx ab“ gesendet. Der Inhalt wird auf dem Server festgelegt.

                    • Jens

                      Und muß ich dann in die „control“ den genauen Pfad angeben? Weil nur mit dem Namen, welchen ich beim erstellen der playlist im LMS vergeben habe, konnte mein Player nix anfangen.

                    • Sebastian
                      Sebastian

                      Normalerweise nicht. Die Playlist muss auf dem Server in der Rubrik „Wiedergabelisten“ auffindbar sein.
                      Der Befehl, der da abgesetzt wird, lautet bei meinem Player zusammengesetzt tn.write("00:13:ef:40:2f:1d playlist play smooth_jazz.m3u \r").
                      Du könntest auch von Deinem Rechner aus per Telnet eine Verbindung zum Server herstellen und 00:13:ef:40:2f:1d playlist play smooth_jazz.m3u absetzen. Das sollte dann auch funktionieren. Das ist auch ganz gut in der Hilfe vom LMS beschrieben.
                      Hast Du vielleicht Leerzeichen im Playlist-Namen? Ob es damit Probleme gibt, habe ich nie probiert.

                    • Jens

                      Sorry, ich muß noch mal fragen.Ich erstelle im LMS eine Wiedergabeliste in dem ich Lieder aussuche und dann im rechten Fenster des LMS unten auf „Speichern“ drücke.Den vergebenen Namen(ohne Freizeichen) gebe ich auch noch squeezebox-control unter dem Punkt „Befehle senden…“ „p2“ den Namen an. Ich kann die Wiedergabeliste über meinen PC im Webbrowser und auch über die App auswählen und abspielen. Wenn ich aber die Menütaste auf der Remote drücke kommt immer „unbekannstes Lied“. Hast Du eine Idee?
                      Mit dem Telnet – habe ich leider keine Ahnung und mit der englischen Hilfe im LMS bin ich etwas überfordert.

                    • Jens

                      Hallo Sebastian,
                      ich beobachte bei meinem laufenden WlanLautsprecher zur Zeit das Problem, daß er, wenn er etwas länger nicht in Betrieb war (über Nacht zum Beispiel), Probleme macht wieder aktiv zu sein. Auf der App sehe ich zwar das der Player läuft aber es kommt kein Ton. So nehme ich an, daß der Verstärker nicht aktiviert wird. Hast Du auch solcher Erfahrungen gemacht? Woran kann das liegen?

                    • Sebastian
                      Sebastian

                      Solche Probleme hatte ich ganz zum Anfang. Damals hat das Script noch HTML-Daten abgefragt. Nachdem ich dann auf Telnet umgestellt hatte, was das Problem weg.
                      Läuft denn das Script in dem Moment noch, wenn der Verstärker nicht mehr reagiert?
                      Startest Du das Script wie im Beitrag beschrieben? Dann müsste ja ein Textfile erzeugt worden sein, in dem die Terminalausgabe landet. Was steht in dem File?

                    • Jens

                      Okay, jetzt bin ich überfordert. Ich habe das Script 1 zu 1 von Dir übernommen. Außer natürlich meine pers. Daten. Also gehe ich mal davon aus, daß ich es auch so wie im Beitrag starte.Wo und wie müsste ich da nachschauen?

                    • Jens

                      Hallo Sebastian,
                      ich habe noch mal geschaut. Ich habe den Script so übernommen wie du ihn in dieser Anleitung hier geschrieben hast. Die Probleme treten nur auf wenn der Verstärker aus war, also nach den 180 Sekunden (was bei mir nur 120 sind).(Die kleine Lampe am Relais ist dann auch aus.) Ich gehe dann mal davon aus, daß zu diesen Zeitpunkt das Script nicht mehr läuft.
                      Dann verzögert sich das anschalten erheblich. Teilweise können das sogar Minuten sein. Wenn er dann einmal an ist, reagiert er fast immer sofort auf den Tastendruck an der Remote oder der Handy APP.
                      Ich würde mich freuen wenn mir da weiter helfen könntest.
                      Gruß Jens

                    • Sebastian
                      Sebastian

                      Das Script dient ja im wesentlichen 2 Funktionen. Zum einen sollen die Befehle der Fernbedienung verarbeitet werden, und zum anderen soll bei Nichtbenutzung des Lautsprechers der Verstärker abgeschaltet werden, um Energie zu sparen.
                      Das Script sollte automatisch erkennen, wenn Musik gespielt wird, und dann den Verstärker von selbst wieder einschalten. Das funktioniert bei auch ziemlich gut.
                      Wenn das bei dir nicht richtig funktioniert, dann hast du zwei Möglichkeiten. Entweder du klemmst das Relais ab und lässt den Verstärker immer am Strom, oder du versuchst, die Ursache zu finden, warum das vielleicht nicht richtig läuft.
                      Das ist natürlich etwas mühselig, die Ursache zu finden, aber auf Dauer ist das aus meiner Sicht die bessere Alternative. Dazu musst du dich aber selber etwas mit der Materie beschäftigen. Eine Diagnose von der Ferne ist da recht schwer.

                    • Jens

                      Ich finde, die von dir geplante Variante auch richtig gut so.Der Verstärker muß ja wirklich nicht immer an sein. Ich finde aber einfach nicht den Fehler. Liegt sicher auch an den nicht vorhandenen Programierkenntnissen. (Auch wenn ich mich damit beschäftige – Aber Doityurself dauert halt länger)
                      Es ist bei mir so, daß, so bald der Verstärker durch das Script ausgeschaltet wurde, das Anschalten sehr lange (teilweise 5 Minuten und länger) dauert. Wie gesagt, mir fehlen leider die Kenntnisse das in der Software zu finden. Und Ferndiagnosen sind immer schwierig. Ist mir klar. Aber vielleicht kann ich Dir irgendetwas zusenden (Protokoll, Logdatei oder…) und du kannst das auswerten.
                      Vielleicht geht es aber auch anders. Was ich mir noch gedacht habe.
                      Die „OK“ Taste ist ja derzeit nicht in Benutzung. Kann diese nicht für das reine Anschalten des Verstärkers genutzt werden? Ausschalten tut er sich ja zeitgesteuert – wie eingestellt. Ich habe mal versucht Teile des Script aus deinem anderen Tutorial –
                      Raspberry Pi: Mit Apple Remote+LIRC Python-Scripte steuern – zu verwenden. War da aber nicht erfolgreich.
                      Gruß Jens

                    • Sebastian
                      Sebastian

                      Klar könnte man den Ausgang einfach mit der Fernbedienung einschalten, ganz am Server vorbei. Aber dann hättest Du ja immernoch das gleiche Problem, wenn Du die Musik per App startest.
                      Ist es denn reproduzierbar, dass das Einschalten immer so lange dauert oder tritt das nur manchmal auf?

                    • Jens

                      Der Fehler tritt auf wenn der Lautsprecher längere Zeit nicht in Betrieb war. Ich habe mal versucht Zeiten zu stoppen. Also bei 4 – 6 Minuten aus, ging er wieder recht flott an.Bei um die 10 Minuten aus , hat er etwas mehr 7 Minuten gebraucht.
                      Mit dem „Extra-Anschalten“ würde mich in der Situation erst mal gar nicht so stören. Aber geht das mit nur einer Taste? Obwohl das Ausschalten wäre ja über das vorhandene Script geregelt.Man müßte dafür ein eigenes Script schreiben oder?

  5. Antworten Walter

    Habe einige Beiträge hier verfolgt. Super dokumentiert, vielen Dank.

    Eine generelle Frage habe ich noch: was ist der Unterschied zw Eingang und Ausgang bei den GPIOs?

    • Sebastian
      Antworten Sebastian

      Ähm, ich muss zugeben – ich glaube ich verstehe die Frage nicht so ganz.

      Bei einem Eingang wird eine Information in das Programm eingelesen, bei einem Ausgang eine Information/Befehl ausgegeben. Wenn diese Informationen mittels Hardware erzeugt/weiterverarbeitet werden sollen, nutzt man am Raspberry Pi meist die GPIO. Jeder GPIO kann dabei sowohl Eingang, als auch Ausgang sein, jedoch nicht gleichzeitig. Wie ein GPIO genutzt werden soll, kann individuell im Script konfiguriert werden.

      Siehe auch Wikipedia: https://de.wikipedia.org/wiki/Allzweckeingabe/-ausgabe

      Beantwortet das die Frage? Wenn nicht, musst Du sie nochmal etwas genauer formulieren.

  6. Antworten Herbert

    Hallo Sebastian,
    tolle Anleitung. Ich möchte das gerne auf meine Stereo- Standboxen übertragen, also das ganze zweimal aufbauen. Wie bekomme ich dann beim Streamen die Kanaltrennung hin?

    • Sebastian
      Antworten Sebastian

      Hallo Herbert,
      dafür gibt es zwei recht einfache Wege, da die (meisten) Soundkarten ohnehin für Stereo ausgelegt sind:

      1. Die günstige Variante: Du baust in einen der Lautsprecher einen Stereo-Verstärker ein, verdrahtest einen Kanal (vielleicht den linken) intern und legst die Anschlüsse für den zweiten Kanal (rechts) nach außen. Vielleicht kannst Du dafür direkt das originale Terminal verwenden. Beide Lautsprecher verbindest Du dann mit einem Kabel.

      2. Die etwas teuere Variante: Du baust zwei gleiche Lautsprecher. Hier ist es dann egal, ob Du Mono- oder Stereo-Verstärker verwendest. Bei der internen Verkabelung musst Du dann nur darauf achten, dass Du bei der Verbindung zwischen Soundkarte und Verstärker bei einem Lautsprecher den linken Kanal auf den Verstärker legst und bei dem anderen den rechten.

      • Antworten Herbert

        Klasse,ddas hört sich richtig gut an. Die zweite Variante käme mir dann entgegen, damit ich keine Kabel legen muss. Ich habe zwei hochwertige Boxen, die ich gerne umrüsten möchte. Wenn ich das Ganze richtig verstanden habe, benötige ich die von Dir aufgeführte Hardware dann zweimal. Geht das ganze auch mit eine PI 3, der schon ein wlan-Modul eingebaut hat?
        Danke für Deinen Einsatz
        Herbert

        • Sebastian
          Antworten Sebastian

          Genau, in diesem Fall müsstest Du alles zwei mal bauen.
          RPi 3 funktioniert auch, allerdings solltest Du nicht all zu viel von dem integrierten WLAN-Modul erwarten. Da sich dann die Antenne im Inneren des Gehäuses befindet, wird der Empfang relativ schwach sein. Besser ist es, die Antenne nach Außen zu verlegen. Das wird mit einem RPi 3 jedoch schwierig und ist auch der Grund, warum ich auf einen WLAN-Stick mit abnehmbarer Antenne setze.

  7. Antworten Markus

    Hallo Sebastian,

    als erstes, DIY Projekt!

    Du hast mir tolle Informationen zum Selbstbau gegeben.
    Ich würde gerne wissen ob es keine Probleme gibt, den Verstärker nur mit einem Kanal zu benutzen.
    Ich möchte das Prinzip gerne für ein Radio am Arbeitsplatz (keine Netzwerkverbindung möglich) zu benutzen
    Als Empfänger dachte ich an einen DVB-T-Stick. Damit ist es möglich UKW-Sender zu empfangen.
    Hast Du eine Idee wie es möglich ist, diesen Sender im Raspberry Pi über Verstärker auszugeben?

    Wäre schön wenn du mir weiterhelfen könntest.

    P.S. Ach ja, mit welcher Software hast du das Bild 29 erstellt. Würde mich mal interessieren…

    Gruß Markus

    • Sebastian
      Antworten Sebastian

      Hallo Markus,
      den Verstärker mit nur einem Kanal zu betreiben ist eigentlich kein Problem.
      Aber bei Deinem Vorhaben mit dem DVB-T-Stick kann ich Dir erstmal nicht weiterhelfen. Soetwas habe ich selber bisher noch nicht probiert.

  8. Antworten Tim

    Morgen Sebastian,
    Hab mich auch mal an ein ähnliches Projekt begeben. Wollte allerdings anstatt der Fernbedienung Taster an der GPIO Port anschließen. Hab dein Script soweit geändert wie ich denke das es richtig ist. Habe allerdings folgenden Fehler beim Mac-Adresse auslesen.

    File „/home/pi/squeezebox-control.py“, line 42
    return ‚%3A‘.join([‚%02x‘ % ord(char) for char in info[18:24]])
    ^
    IndentationError: unindent does not match any outer indentation level
    File „/home/pi/squeezebox-control.py“, line 42
    return ‚%3A‘.join([‚%02x‘ % ord(char) for char in info[18:24]])
    ^
    IndentationError: unindent does not match any outer indentation level

    Hab im Moment kein Wlan Adapter angeschlossen (benutze Pi2). Liegt das dadran? Hab aber Zeile 221 von wlan0 auf eth0 geändert.
    Hast du eine Idee woran das liegen könnte?

    • Sebastian
      Antworten Sebastian

      Hi Tim,
      IndentationError steht bei Python dafür, dass die Code-Einrückung, die bei Python ja Pflicht ist, nicht stimmt. Manchmal kommt das auch daher, dass einmal Leerzeichen und einmal die Tabulator-Taste zum Einrücken genutzt wurde.

      • Antworten Tim

        Hi Sebastian,
        Danke für den Tip. Läuft jetzt ohne Fehler durch. Habe auch eine Verbindung per Telnet. Standard Lautstärke wird gesetzt. Allerdings klappt das noch nicht mit den Gpio Tastern. Die Taster funktionieren und kommen am Pi an, werden aber nicht an den LMS weitergeleitet. Hast du da vielleicht auch noch einen Tip für?
        Code sieht so aus:

        def setGPIO(channel,state):
                #GPIO.setwarnings(False)
                GPIO.setmode(GPIO.BOARD)                            # Zählweise der Pins festlegen
                #GPIO.setup(22, GPIO.OUT)                            # Pin 22 (GPIO 25) = Verstärker-Relais 1
                #GPIO.setup(24, GPIO.OUT)                           # Pin 24 (GPIO  8) = Verstärker-Relais 2
                GPIO.setup(32, GPIO.IN)
                GPIO.setup(33, GPIO.IN)
                GPIO.setup(35, GPIO.IN)
                GPIO.setup(36, GPIO.IN)
                GPIO.setup(38, GPIO.IN)
                GPIO.setup(40, GPIO.IN)
        
                if GPIO.input(32) == GPIO.HIGH:
                        player('playlist')
                if GPIO.input(33) == GPIO.HIGH:
                        if status == "play":
                                player('pause')
                        else:
                                player('play')
                if GPIO.input(35) == GPIO.HIGH:
                        player('next')
               if GPIO.input(36) == GPIO.HIGH:
                        player('back')
                if GPIO.input(38) == GPIO.HIGH:
                        player('vol_up')
                if GPIO.input(40) == GPIO.HIGH:
                        player('vol_down')
        

        Der Programm Teil der die Befehle sendet sieht genauso aus wie deiner.
        Muss dazu sagen das ich mich erst seit ein paar Tagen mit python und dem GPIO-Port am Pi beschäftige und deshalb bestimmt noch etwas auf dem Schlauch stehe 🙂
        Gruß Tim

        • Sebastian
          Antworten Sebastian

          Wenn Du Dich weitestgehend an meinem Script orientiert hast, müsstest Du die Abfrage der GPIO-Eingänge dorthin verschieben, wo ich den IR-Empfänger abfrage: in die Funktion remote(). In einem parallelen Thread, der (bei mir) auf Zeile 225 gestartet wird, werden die GPIO dann immer abgefragt. Das while True: innerhalb er Funktion sorgt dafür, dass das als Dauerschleife ausgeführt wird und dieser Thread sich nie beendet.
          Die Definition der GPIO sollte nur einmal im Script erfolgen. Du definierst die GPIO ja bei jedem Aufruf der Funktion erneut – das könnte vielleicht zu Problem führen. Schieb die lieber ganz an den Anfang des Scripts, oder dahin, wo sie bei mir stehen, also direkt unter if __name__ == '__main__':.
          Um jetzt das Debugging etwas zu erleichtern, kannst Du Dir ja an prägnanten Stellen ein print "hier passiert das und das..." einbauen. Dann kannst Du ganz einfach mitlesen, was das Script gerade macht. Wenn Du das bei Dir vor jeden player(..)-Befehl einbaust, dann wirst Du höchstwahrscheinlich sehen, dass die GPIO garnicht abgefragt werden und deshalb nichts reagiert.

          • Antworten Tim

            Besten dank. Werd ich morgen mal ausprobieren.
            Hab aber noch eine Frage zu der Print funktion. Wo wird das dann ausgegeben? Wenn ich im terminal sudo ./squeezebox-control.py ausführe oder in der Log-Datei?

            • Sebastian
              Antworten Sebastian

              Wenn Du das Script händisch im Terminal startest, erscheint auch die Ausgabe im Terminal. Bei „Autostart“ in der Log-Datei.

              • Antworten Tim

                Ich habs hingekriegt 🙂
                besten dank für deine Hilfe. Das Start-Script sieht jetzt so aus:

                #!/usr/bin/env python
                #coding: utf-8 
                 
                ####################################################################
                # squeezebox-control.py
                # Script zur Steuerung eines WLAN-Lautsprechers
                # von Sebastian Köhler - http://indibit.de
                #
                # LETZTE ÄNDERUNG:    17.04.2016
                ####################################################################
                 
                import fcntl, socket, struct    # für MAC-Adresse
                #import lirc
                import RPi.GPIO as GPIO
                import sys
                import telnetlib
                import thread
                import time
                 
                # ----------------------------------------------------------------------------
                #  Konfiguration
                # ----------------------------------------------------------------------------
                HOST            = "192.168.178.58"   # IP-Adresse des LMS
                PORT            = "9090"            # CLI-Port des LMS
                OFF_DELAY       = 180               # Verstärker-Abschalt-Verzögerung (in Sekunden)
                VOL_NORM        = 100                # Lautstärke, die nach beim Einschalten eingestellt werden soll
                 
                # ----------------------------------------------------------------------------
                #  sonstige Variablen
                # ----------------------------------------------------------------------------
                mac = ''       # MAC-Adresse
                status = ''    # Status des Players
                tn = ''        # Telnet-Verbindung
                lastPlay = 0   # Zeit, wann der Player das letzte Mal gespielt hat
                 
                # ----------------------------------------------------------------------------
                #  MAC-Adresse auslesen
                # ----------------------------------------------------------------------------
                def getMAC(ifname):
                    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                    info = fcntl.ioctl(s.fileno(), 0x8927,  struct.pack('256s', ifname[:15]))
                    return '%3A'.join(['%02x' % ord(char) for char in info[18:24]])
                 
                # ----------------------------------------------------------------------------
                #  Telnet-Verbindung herstellen
                # ----------------------------------------------------------------------------
                def tn_connect():
                    global tn
                    try:
                        tn = telnetlib.Telnet(HOST,PORT)
                        player("startup")
                    except:
                        time.sleep(10)
                 
                # ----------------------------------------------------------------------------
                #  WLAN-Lautsprecher bei Start initialisieren
                # ----------------------------------------------------------------------------
                def startup():
                    setGPIO("startup","")
                    tn_connect()
                 
                # ----------------------------------------------------------------------------
                #  Fernbedienung/LIRC abfragen
                # ----------------------------------------------------------------------------
                def remote():
                    while True:
                        try:
                            #codeIR = lirc.nextcode()
                            #if codeIR != []:
                            #    if codeIR[0] == 'KEY_UP':
                                if GPIO.input(40):
                		    print 'lauter'
                     		    player('vol_up')            
                            #    elif codeIR[0] == 'KEY_DOWN':
                		elif GPIO.input(38):
                		    print 'leiser'
                                    player('vol_down')
                            #    elif codeIR[0] == 'KEY_LEFT':
                		elif GPIO.input(35):
                		    print 'zurück'
                                    player('back')
                            #    elif codeIR[0] == 'KEY_RIGHT':
                		elif GPIO.input(36):
                		    print 'next'
                                    player('next')
                            #    elif codeIR[0] == 'KEY_OK':
                	    #       pass
                            #    elif codeIR[0] == 'KEY_MENU':
                		elif GPIO.input(33):
                                    print 'playlist'
                		    player('playlist')
                            #    elif codeIR[0] == 'KEY_PLAYPAUSE':
                		elif GPIO.input(32):
                                    if status == "play":
                			print 'pause'
                                        player('pause')
                                    else:
                			print 'play'
                                        player('play')
                                time.sleep(0.50)
                        except:
                                time.sleep(0.10)
                     
                # ----------------------------------------------------------------------------
                #  Befehle senden, Status abfragen
                # ----------------------------------------------------------------------------
                def player(cmd):
                    p0 = ""
                    p1 = ""
                    p2 = ""
                    if cmd == "startup":
                        try:
                            player("stop")
                            #tn.write("subscribe play,pause,stop,playlistr")
                            tn.write(mac + " mode ?r")
                            resetVol()
                        except (EOFError, socket.error):
                            tn_connect()
                             
                    else:
                        if cmd == "play":               # Wiedergabe
                            p0 = "play"
                        elif cmd == "pause":            # Pause
                            p0 = "pause"
                        elif cmd == "stop":             # Stop
                            p0 = "stop"
                        elif cmd == "back":             # Titel zurück
                            p0 = "playlist"
                            p1 = "index"
                            p2 = "-1"
                        elif cmd == "next":             # Titel überspringen
                            p0 = "playlist"
                            p1 = "index"
                            p2 = "%2B1"
                        elif cmd == "vol_up":           # Lauter
                            p0 = "mixer"
                            p1 = "volume"
                            p2 = "%2B5"
                        elif cmd == "vol_down":         # Leiser
                            p0 = "mixer"
                            p1 = "volume"
                            p2 = "-5"
                        elif cmd == "playlist":         # Playlist abspielen
                            p0 = "playlist"
                            p1 = "play"
                            p2 = "test.m3u"
                        else:
                            p0 = ""
                            p1 = ""
                            p2 = ""
                 
                        if p0 != "":
                            try:
                                tn.write(mac + " " + p0 + " " + p1 + " " + p2 + "r")
                            except (EOFError, socket.error):
                                tn_connect()
                     
                    p0 = ""
                    p1 = ""
                    p2 = ""
                 
                def getStatus():
                    while True:
                        global status
                        try:
                            tn.write(mac + " mode ?r")
                            q = tn.read_until('r')
                            s = q.split('r')[0].split(' ')
                            if s:
                                if s[0] == mac:
                 
                                    if s[1] == "mode":
                                        status = s[2]
                 
                        except (EOFError, socket.error):
                            tn_connect()
                        except KeyboardInterrupt:
                            getOut()
                        time.sleep(0.1)
                 
                # ----------------------------------------------------------------------------
                #  Verstärker am WLAN-Lautsprecher ein-/ausschalten
                # ----------------------------------------------------------------------------
                def ampOnOff():
                    global lastPlay
                    if status == "play":
                        setGPIO("amp","on")
                        lastPlay = time.time()
                    else:
                        if time.time() - lastPlay &gt;= OFF_DELAY:
                            if status == "pause":
                                resetVol()
                                player("stop")
                            setGPIO("amp","off")
                 
                def setGPIO(channel,state):
                    amp = 22
                    on  = GPIO.LOW
                    off = GPIO.HIGH
                
                    if channel == "startup":
                        GPIO.output(22, GPIO.HIGH)
                        #GPIO.output(24, GPIO.HIGH)
                    else:
                        if (channel in locals()) and (state in locals()):
                            GPIO.output(locals()[channel], locals()[state])
                 
                # ----------------------------------------------------------------------------
                #  Standard-Lautstärke setzen
                # ----------------------------------------------------------------------------
                def resetVol():
                    try:
                        tn.write(mac + " mixer volume " + str(VOL_NORM) + " r")
                    except (EOFError, socket.error):
                        tn_connect()
                     
                # ----------------------------------------------------------------------------
                #  Script beenden
                # ----------------------------------------------------------------------------
                def getOut():
                    GPIO.cleanup()
                    sys.exit(0)
                 
                # ----------------------------------------------------------------------------
                #  Hauptprogramm
                # ----------------------------------------------------------------------------
                if __name__ == '__main__':
                    #GPIO.setwarnings(False)
                    GPIO.setmode(GPIO.BOARD)                            # Zählweise der Pins festlegen
                    GPIO.setup(22, GPIO.OUT)                            # Pin 22 (GPIO 25) = Verstärker-Relais 1
                
                    #GPIO.setup(24, GPIO.OUT)                           # Pin 24 (GPIO  8) = Verstärker-Relais 2
                    GPIO.setup(32, GPIO.IN)
                    GPIO.setup(33, GPIO.IN)
                    GPIO.setup(35, GPIO.IN)
                    GPIO.setup(36, GPIO.IN)
                    GPIO.setup(38, GPIO.IN)
                    GPIO.setup(40, GPIO.IN)
                #   sockid=lirc.init("appleremote", blocking = False)   # Fernbedienung einbinden
                 
                    mac = getMAC('eth0')
                    startup()
                 
                    thread.start_new_thread(getStatus,())
                    thread.start_new_thread(remote,())
                 
                    while True:
                        try:
                            ampOnOff()
                            n = True
                            time.sleep(0.1)
                        except KeyboardInterrupt:
                            getOut()
                

                Vielleicht steht ja einer vor dem gleichem Problem 😉
                Hab mich eigentlich an deine Anleitung gehalten und nur die Lirc installation übersprungen.

                mfg Tim

                    • Sebastian
                      Sebastian

                      Weiß ich garnicht so genau. Kommt ja darauf an, welche Komponenten Du verwendest, was die kosten und was du vielleicht noch herum liegen hast. Wenn Du alles hier aufgeführte selbst kaufen musst, kommst Du vielleicht auf 80€ (oder mehr?). Wobei der größte Anteil bei dem Lautsprecher liegt. Wenn Du aber noch einen hast, den Du verwenden kannst, wird es deutlich günstiger.

                      Beim letzten hab ich dann auch die Fernbedienung weggelassen, weil ich die dort nicht benötige. Nochmal ein paar Euro weniger. Und so geht das weiter. Mal hier ein Schnäppchen, mal dort ein Angebot… Ist alles sehr individuell.

                    • Jens

                      Hallo Sebastian,
                      dank Deiner Anleitung habe ich ja schon seit einiger Zeit bei mir 2 WLan Lautsprecher am Laufen. Die an sich auch ganz prima funktionieren. Nur ein Problem tritt immer mal wieder auf. Die Dauer vom Anschalten bis zum Angehen ist manchmal recht lang. Ich kann auch nicht nachvollziehen ob es irgendeinen Auslöser dafür gibt. Wenn der Fall eingetreten ist, hilft dann immer nur ein komplettes runter / hoch fahren. Danach geht es wieder. Ist sowas bei Dir auch schon mal aufgetreten?

                    • Sebastian
                      Sebastian

                      Hi Jens,
                      Bei mir ist es tatsächlich auch so, dass es manchmal etwas dauert, bis sich der Lautsprecher zuschaltet. Da fehlen dann die ersten Sekunden vom Lied, bzw. sind einfach nicht zu hören.
                      Allerdings kommt das extrem selten vor und sind dann maximal 5 Sekunden, was mich bisher einfach noch nicht dazu veranlasst hat, mich auf die Suche nach der Ursache zu machen.

                    • Jens

                      Hallo Sebastian,
                      ja bei 5 Sekunden würde mich das auch nicht weiter beschäftigen. Bei mir dauert es leider manchmal mehrere Minuten.

  9. Sebastian
    Antworten Sebastian

    Aus irgendeinem Grund hatte ich jetzt mehrfach Probleme mit dem Autostart des Scripts. Nach einem Stromausfall lief zwar der Player selbst, aber der Verstärker wurde nicht eingeschaltet.
    Deswegen habe ich mich nach einer neuen Variante umgesehen und diese oben eingefügt. Damit wird das Script jetzt als Dienst gestartet.

  10. Antworten Tim

    Moin moin Sebastian,
    ich möchte zu Hause auch ein Multiroom Audio Projekt starten. Allerdings möchte ich nur aktive Lautsprecher verwenden, die bereits einen Klinke-Input besitzen.
    Ist es also möglich in Max2Play einfach den bereits verbauten Klinke-Output des Pi zu benutzen und von einem Aufbau-Modul abzusehen? Das spart bei vier zu speisenden Räumen letztendlich ein paar Euro..

    Freue mich auf Deine Antwort!
    LG, Tim

    • Sebastian
      Antworten Sebastian

      Moin Tim,
      Aktive Lautsprecher halte ich für eine gute Idee. Wollte ich auch schon immer mal ausprobieren, habe jedoch bisher keine Zeit dafür gefunden.
      Um eine Soundkarte wirst du jedoch bestimmt nicht herum kommen, denn der Ausgang auf dem RPi ist total verrauscht, da er keinen eigenen Soundchip besitzt sondern die Signale über PWM ohne Filter erzeugt.
      Aber probiere gerne dein Glück. Die Karte (zur Not tut es auch eine USB-Soundkarte für 5€) kannst Du ja jederzeit nachkaufen.