SONOS mit GIRA Homeserver steuern

Ich steuere meine Sonos Player mittlerweile recht erfolgreich mithilfe eines kleinen PHP Skriptes, daß ich mal auf die schnelle geschrieben habe, über den Gira Homeserver. Damit kann man feine Dinge anstellen wie z.B. Radio An/Aus oder die Lautstärke auf einzelne Taster legen. Oder alle Radios beim Abschließen der Haustüre mittels eines Riegelschaltkontaktes ausgehen lassen.

Ich habe mich hauptsächlich der PHP – Sonos Klasse bedient, welche hier zu finden ist. Diese wurde von mehreren Leuten schon erweitert und mit allerhand Funktionen bestückt. Darum habe ich mir einen Wrapper gebaut, der die für mich relevanten Funktionen zur Verfügung stellt (die index.php). Dort müssen auch die einzelnen Player inkl. deren IP-Adresse eingefügt werden. Die Player verwenden normalerweise DHCP und müssen mittels DHCP Reservierungen auf feste IP Adressen gebracht werden.

Das Interessante ist, das mit diesem Script die Player auch ausgelesen werden und damit Funktionen wie Toggle Play / Pause oder Volume Up unabhängig deren letzten Status realisiert werden können (man muss nicht 2 x auf die Taste drücken weil der Player zwischenzeitlich mit einem anderen Gerät gesteuert wurde). Es können auch Ansagen abgespielt werden. Dabei wird das laufende Programm unterbrochen, die Ansage abgespielt und anschließend das Programm an der unterbrochenen Stelle wieder fortgesetzt.

Zur Installation einfach die beiden Dateien index.php und PHPSonos.inc.php auf einen PHP-fähigen Webserver kopieren. In der index.php die Player zusammen mit Ihrer IP-Adresse in das $zones Array (Zeile 13) eintragen. Zum Testen kann das Script einfach im Browser aufgerufen werden:

http://deinWebserver/Pfad/zum/Script/index.php?zone=NameDerZone&do=TogglePlayStop

Dieser Aufruf ist an die Gegebenheiten anzupassen.

Die zur Verfügung stehenden Funktionen findet man in der index.php im $_GET['do'] switch ab Zeile 24. Die Interessantesten dürften sein:

index.php?zone=MeineZone&do=TogglePlayStop: schaltet um zwischen Play und Pause
index.php?zone=MeineZone&do=VolumeUp: Lautstärke wird pro Aufruf um 1 erhöht
index.php?zone=MeineZone&do=VolumeDown: Lautstärke wird pro Aufruf um 1 vermindert
index.php?zone=MeineZone&do=sendMessage&MesageId=1&Volume=30: Programm wird unterbrochen und Nachricht mit der ID 1 wird abgespielt. Die gewünschte Lautstärke wird über den Parameter Volume übergeben. Der Pfad zu den Nachrichten ist in Zeile 222 in der index.php anzupassen. Der Ordner muss vom Sonos aus erreichbar sein. Die Datei muss in folgendem Format dort gespeichert sein: MessageId.mp3 macht dann z.B. 1.mp3

Im Homeserver eine Webseitenabfrage wie auf den Screenshots dargestellt erstellen:

Download: Sonos.zip

47 thoughts on “SONOS mit GIRA Homeserver steuern

  1. Hallo,
    bisher habe ich auch mit Scripten und Sonos gearbeitet. Was hier beschrieben ist, ist aber um längen besser als meine Installation…
    Radio hören und die Sendung wir unterbrochen von “Es klingelt jemand an der Tür.mp3″ ;-)
    Das habe ich immer gesucht, vielen Dank. Werde heute abend mal ein bisschen installieren….
    Gruß Marc

  2. Hi,
    alles installiert, und klappt super. Ich hatte vorher verschiedene Skripte gebastelt, jetzt brauche ich nur noch die 2. Laut&Leiser ist super…

    Nur ein Problem;-)
    Ich bekomme die Klingel nicht an Laufen. Es wurde ein 1.mp3 erstellt und es dem Script zugewiesen.
    Leider funktioniert es nicht…

    Mir sind verschieden Strings aufgefallen MessageId und MesageId. Ist richtig?

    Ich habe alle Mesage nach dem Test in Message geändert, bring auch nix.
    $sonos->AddToQueue(“x-file-cifs://srv01/Music/Sprachmeldungen/$MessageId.mp3″);

    Kann mir jemand helfen.

    Vielen Dank und Gruß aus Halver
    Marc

    • Hi Marc,

      freut mich, dass es bei dir funktioniert. Zu deinem Problem: Das mit dem String (MesageId) habe ich gesehen, stellt aber keinb Problem dar, da ich das s durchgängig vergessen habe. Wenn du die Variable geändert hast, musst du auch den Aufruf nach MessageID ändern: index.php?zone=MeineZone&do=sendMessage&MessageId=1. Deine Nachricht muss unter dem Namen der aufgerufenen MessageID abgespeichert sein, z.B.: 1.mp3. Des weiteren musst du in der von dir beschriebenen Zeile den Pfad zu deiner Nachricht anpassen. Dieser muss auch zwingend von deinem Sonos aus erreichbar sein. Dies kannst du am besten testen, in dem du versuchst diese Nachricht direkt mit Sonos abzuspielen. Dann ist sichergestellt, das dein Sonos darauf Zugriff hat. Wenn das alles passt, kannst du das Script zum Testen auch direkt im Browser aufrufen: index.php?zone=MeineZone&do=sendMessage&MesageId=1.

        • Hi Marc,

          ich habe den Fehler gefunden *schäm*. Der Aufruf war nicht vollständig. Der korrekte Aufruf der Funktion lautet:

          index.php?zone=Kueche&do=sendMessage&MessageId=1&Volume=30

          Du musst noch die gewünschte Lautstärke (Wert zwischen 0 und 100) mitgeben. Ich werde es oben im Beitrag auch gleich noch ändern.

  3. Auch nicht schlecht. So eine Art High-End Multiroom-Klingel :) Meine melden aktuell “Die Waschmaschine ist fertig”. Mit dem Trockner klappt es noch nicht so ganz :(

  4. Toll. Das sind ja super Features. Kann man vielleicht auch im Sonos-System gespeicherte Playlisten auslesen und (vielleicht als m3u) abspeichern?

  5. Hi, komplette Playlisten habe ich bisher nicht als Kommando, ich meine aber das es schon mit anderen Tools wie z.B. sonosweb ausgelesen wurde, sollte also möglich sein.

  6. Hallo

    Funktioniert einwandfrei und stabil.Habe auf einem IIS PHP installiert und die Scripts kopiert.
    Bisher hatte ich Barix im Einsatz. Eine Audioeinblendung musste ich über VB6 auf einem separaten System ausführen.

    Habt Ihr für Playlisten oder Radio Favoritenanwahl schon was ausgebaut?

    Vielen Dank und Gruss
    Thomas

    • Hi Thomas,

      freut mich, dass es bei dir läuft.

      >Habt Ihr für Playlisten oder Radio Favoritenanwahl schon was ausgebaut?
      Was schwebt dir hier vor?

      Viele Grüße

      Thomas

  7. Hi Thomas

    Habe unerwartet doch noch ein Problem mit dem Aufruf MessageID bekommen. Hat alles perfekt funtioniert.
    Seit gestern bekomme ich immer eine Fehlermeldung nach Aufruf mit Messageid. (500 Serverresourcen nicht gefunden.)
    Dies tritt nur auf wenn eine Radioquelle beim ZP aktiviert ist. Wenn in der Liste ein MP3 Song aktiviert ist funktioniert alles perfekt.
    Hast du noch einen Tip was da passiert ist?

    Vielen Dank und Gruss
    Thomas

    • Ich habe vor einer Weile an dem Script gebaut, da es bei mir mit den Messages auch Probleme gab (weiß aber leider nicht mehr genau warum, ist schon eine Weile her). Ich schaue, dass ich die neue Version hier die Tage online stelle. Dann kannst du es damit mal probieren.

  8. Hallo Thomas
    Vielen Dank im voraus.
    Habe im Script noch gelesen, das bei Radio Stream die Mac-Adresse noch eine Rolle spielt. Habe nicht ganz verstanden wo ich diese mitgeben sollte.

    Hoffen wir auf einen neuen Release.

    Gruss Thomas

    • Hi Thomas,

      du meinst, wenn du einen Radio Stream einstellen willst? Die brauchst du nicht, bzw. kannst du mit der Funktion $sonos->SetRadio einen Radiosender ohne Angabe der Mac-Adresse einstellen.

      In meinem Script gibt es auch noch die Funktion nextRadio(); Damit kannst du deine Radiosender in einer Datenbank speichern und bequem durchzappen (nutze ich auf einem Taster im Bad und in der Küche).

  9. Hallo Thomas
    Zuerst einmal vielen Dank für den neuen Script. Kämpfe noch mit den Details
    DB habe ich angelegt und die 4 Radiostationen erfasst. Bekomme aber mit der Funktion nextRadio immer folgende Fehlermeldung

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\sonos.php on line 230

    Warning: mysql_free_result(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\sonos.php on line 247

    Fatal error: Uncaught exception ‘Exception’ with message ‘Error sending command: HTTP/1.1 500 Internal Server Error CONTENT-LENGTH: 347 CONTENT-TYPE: text/xml; charset=”utf-8″ EXT: SERVER: Linux UPnP/1.0 Sonos/14.4-33290 (ZP90) Connection: close s:ClientUPnPError’ in C:\xampp\htdocs\PHPSonos.inc.php:502 Stack trace: #0 C:\xampp\htdocs\PHPSonos.inc.php(56): PHPSonos->sendPacket(‘POST /MediaRend…’) #1 C:\xampp\htdocs\sonos.php(250): PHPSonos->Play() #2 C:\xampp\htdocs\sonos.php(87): nextRadio() #3 {main} thrown in C:\xampp\htdocs\PHPSonos.inc.php on line 502

    Hast du eine Idee was hier falsch läuft ?

    Gruss Thomas

  10. Huhu, jetzt kämpfe ich auch ein bisschen mit dem Radiosendern. Habe auf meiner Qnap mysql installiert.
    Tabelle und Radiosender angelegt lt. index.php. Nun erhalte ich den Fehler:

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /share/MD0_DATA/Qweb/index.php on line 216

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /share/MD0_DATA/Qweb/index.php on line 224

    Fatal error: Call to undefined function l_query() in /share/MD0_DATA/Qweb/index.php on line 239

    Hier meine Tabelle:

    radiostation Anzeigen Struktur Suche Einfügen Leeren Löschen 4 MyISAM latin1_swedish_ci 2,2 KiB -
    settings Anzeigen Struktur Suche Einfügen Leeren Löschen 0 MyISAM latin1_swedish_ci 1,0 KiB -
    2 Tabellen Gesamt 4 MyISAM hp8_bin 3,2 KiB 0 Bytes
    markierte: Alle auswählen / Auswahl entfernen

    vollständige Textfelder id radio url
    Bearbeiten Löschen 1 Radio7 players.creacast.com/creacast/radio7/playlist.m3u
    Bearbeiten Löschen 2 SWR3 mp3-live.swr3.de/swr3_m.m3u
    Bearbeiten Löschen 3 Donau3FM server1.webradiostreaming.de:2640
    Bearbeiten Löschen 4 Bayern3 http://streams.br-online.de/bayern3_2.asx

    Hat jemand eine Ahnung wo der Fehler liegt. Vielen Dank und ein schönes Wochenende. Marc

    • Hi Marc,

      das liegt vermutl. daran, dass bei dir in der Tabelle settings noch nichts drin steht. Dort wird der zuletzt gehörte Radiosender gespeichert. Schreib da z.B. mal eine 1 rein, dann müsste es gehen:


      INSERT INTO `settings` (`act_id`) VALUES (1);

  11. Vielen Dank für die Info, habe eine 1 in die Tabelle gepackt. Jetzt folgt der Fehler:

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /share/MD0_DATA/Qweb/index.php on line 217

    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /share/MD0_DATA/Qweb/index.php on line 225

    Warning: mysql_free_result(): supplied argument is not a valid MySQL result resource in /share/MD0_DATA/Qweb/index.php on line 242

    Fatal error: Uncaught exception ‘Exception’ with message ‘Error sending command: HTTP/1.1 500 Internal Server Error CONTENT-LENGTH: 347 CONTENT-TYPE: text/xml; charset=”utf-8″ EXT: SERVER: Linux UPnP/1.0 Sonos/14.4-33290 (ZPS5) Connection: close s:ClientUPnPError’ in /share/MD0_DATA/Qweb/PHPSonos.inc.php:502 Stack trace: #0 /share/MD0_DATA/Qweb/PHPSonos.inc.php(56): PHPSonos->sendPacket(‘POST /MediaRend…’) #1 /share/MD0_DATA/Qweb/index.php(245): PHPSonos->Play() #2 /share/MD0_DATA/Qweb/index.php(82): nextRadio() #3 {main} thrown in /share/MD0_DATA/Qweb/PHPSonos.inc.php on line 502

    Hast Du noch eine Idee?

    • Hi Marc,

      verdammt schwierig ohne aussagekräftige Fehlermeldung zu debuggen. Hast du ein PHPmyadmin am laufen? Dann den Query am besten dort mal testen und schauen was du für eine Fehlermeldung bekommst:

      SELECT s.act_id, MAX(r.id) AS max_id FROM settings s, radiostation r

  12. Moinmoin,
    vielen Dank für die Info. Ich habe Phpmyadmin auf der Qnap installiert. Ich habe diesen Befehl: #1140 – Mixing of GROUP columns (MIN(),MAX(),COUNT(),…) with no GROUP columns is illegal if there is no GROUP BY clause
    auf der Datenbank “sonos” ausgeführt, die Antowrt war:

    #1140 – Mixing of GROUP columns (MIN(),MAX(),COUNT(),…) with no GROUP columns is illegal if there is no GROUP BY clause

    Gruß Marc

    • Hi,

      dann scheint dein MySQL Server wohl etwas strikter eingestellt zu sein und schon bei leichteren vergehen zu maulen. Ersetze mal den Query im Script damit:

      SELECT s.act_id, MAX(r.id) AS max_id FROM settings s, radiostation r GROUP BY s.act_id

      Dann sollte es eigentlich gehen.

  13. Vielen Dank, bin jetzt einen Schritt weiter:
    Zeige Datensätze 0 – 0 (1 insgesamt, die Abfrage dauerte 0.0030 sek.)

    Jetzt habe ich die Fehlermeldung:

    Fatal error: Uncaught exception ‘Exception’ with message ‘Error sending command: HTTP/1.1 500 Internal Server Error CONTENT-LENGTH: 347 CONTENT-TYPE: text/xml; charset=”utf-8″ EXT: SERVER: Linux UPnP/1.0 Sonos/14.4-33290 (ZPS5) Connection: close s:ClientUPnPError’ in /share/MD0_DATA/Qweb/PHPSonos.inc.php:502 Stack trace: #0 /share/MD0_DATA/Qweb/PHPSonos.inc.php(410): PHPSonos->sendPacket(‘POST /MediaRend…’) #1 /share/MD0_DATA/Qweb/index.php(244): PHPSonos->SetRadio(‘Bayern3′, ‘x-rincon-mp3rad…’) #2 /share/MD0_DATA/Qweb/index.php(82): nextRadio() #3 {main} thrown in /share/MD0_DATA/Qweb/PHPSonos.inc.php on line 502

    Hast Du evtl. noch ein Idee,

    vielen Dank
    Marc

    • Hi Marc,

      sorry für die späte Antwort, bin momentan gerade viel unterwegs:

      Die Funktion an sich funktioniert jetzt aber? Dann würde ich die Fehlermeldung gerne auf später aufschieben, ich denke es ist nur eine Unschönheit (falsche Content Länge).

  14. Servus Thomas, tolle Sache!!
    Hab jedoch noch ein paar kleine Fragen:
    Im Script gibt es auch den Befehl Volume, um direkt einen Wert an den Player zu senden. Leider krieg ich das nicht hin, wenn ich:
    http://192.168.120.100:9050/Sonos/index.php?zone=Wohnzimmer&do=Volume=10 eintrage kommt die Meldung “Wrong Command” schreibe ich
    http://192.168.120.100:9050/Sonos/index.php?zone=Wohnzimmer&do=Volume dann meldet das Script “Wrong Volume”.
    Ich hab auch noch ca. 10 andere Varianten probiert, leider ohne Erfolg. Ich hab auch schon alle Arten von Klammern probiert, da im Script auch Klammern angegeben sind.

    Weiters: Kann man eine im Sonos Controller gespeicherte Playliste per Befehl aufrufen? In der Squeezeboxwelt geht das mit Playlist Play. Dann kann man diese per Bustaster dynamisch aufrufenlassen. Z.B. um Oldies zu Spielen wenn der Papa Duschen geht, der Sohnemann zieht sich die Liste Techno rein. Die Playlisten kann man bequem im Controller erstellem.

  15. Vielen Dank, Lautstärke setzen funktioniert.

    So, nun kämpfe ich mit dem Radioaufruf:
    case ‘Test’:
    $sonos->ClearQueue();;
    break;
    zum Testen, wenn ich einen case “TEST” anlege funktioniert.
    wenn ich das nun ändere um einen Radiosender anzuwählen z.B.:
    case ‘Test’:
    $sonos->SetRadio(Martin, “x-rincon-mp3radio://http://streams.br-online.de/bayern3_2.asx”);
    $sonos->Play();
    break;

    oder
    case ‘Test’:
    $sonos->SetRadio(‘Martin’, “x-rincon-mp3radio://’http://streams.br-online.de/bayern3_2.asx'“);
    $sonos->Play();
    break;
    und noch etliche andere Varianten (samt php Server Absturz) durchteste, ich komm leider nicht dahinter!

    Weiters hab ich gesehen, dass es auch eine “$sonos->SetQueue” gibt. Kann man nicht damit eine Playlist aufrufen?

    Wäre dir einerseits für deine Hilfe bei meiner Erarbeitung der Probleme (ich will ja auch was lernen)dankbar , andererseits stelle ich die Frage, ob du mir gegen Aufwandsentschädigung folgende Funktionen realisieren könntest: Aufruf einer gespeicherten Playlist, Aufruf eines gespeicherten Radiosenders. Mit “gespeichert” meine ich die Einträge im Sonos Controller. Den Rest könnte ich ja im Script dann selber erstellen.
    lg. Martin

    • Hi Martin,

      ich habe dich nicht vergessen, bin jedoch im Moment sehr beschäftigt und komme leider nicht dazu dir zu helfen.

    • Weiters hab ich gesehen, dass es auch eine “$sonos->SetQueue” gibt. Kann man nicht damit eine Playlist aufrufen?

      Sieht so aus:

      //$sonos->SetQueue("x-rincon-queue:RINCON_"."HIER DIE MAC DES PLAYERS ZB: FFEEDDCCBBAA"."01400#0"); //Playlist auswählen (Nötig, wenn Radio vorher ausgewählt war)

    • So, nun kämpfe ich mit dem Radioaufruf:

      Radioaufruf ist doch mitsamt DB-Anbindung schon im Script enthalten. Einfach eine MySQL Datenbank mit den Radiosendern anlegen.

      Wenn du direkt einen Radiosender aufrufen willst, lautet die Syntax wie in Zeile 242:

      $sonos->SetRadio($radio, "x-rincon-mp3radio://$url");

      $url must du mit der Url deines Radiosenders ersetzen

  16. Danke, aber wie muss denn die komplette Befehlszeile dann ausschauen?
    so z.B:
    $sonos->SetRadio(x-rincon-mp3radio://streams.br-online.de/bayern3_2.asx);
    oder gehört da noch was dazu? wie ‘ oder ”
    ich kann das leider erst morgen am abend testen
    lg. Martin

  17. So, nun hab ich das getestet. Der Befehl lautet korrekt:
    $sonos->SetRadio(“x-rincon-mp3radio://URL_DES_SENDERS”, “ANGEZEIGTER_NAME”);
    z.B.:
    $sonos->SetRadio(“x-rincon-mp3radio://www.antenne.de/webradio/channels/das-schlager-karussell.m3u”, “Schlager”);

    ohne den Eintrag “ANGEZEIGTER_NAME” gibts nämlich eine Fehlermeldung.

    Ein $sonos->Play();
    hab ich auch noch drangesetzt.

    Ich hoffe irgendjemand kann das irgendwann mal brauchen!

    So nun zu “$sonos->SetQueue” , wie oben beschrieben braucht man das um die aktuelle Playliste nach dem Radiobetrieb wieder anzusteuern. Jedoch habe ich das nicht gemeint, Ich möchte einfach eine benannte Playliste aus dem Bereich “Sonos-Playlisten” per Befehl aufrufen. Damit könnte man dann seine Playlisten im Sonoscontroller ganz einfach anlegen und dann per Tastendruck z.B.: Oldies aufrufen.
    Vielleicht hat da mal jemand eine Idee.
    lg. Martin

    • Mit der aktuellen Klasse:

      $sonoslists=$sonos->GetSONOSPlaylists();
      print_r($sonoslists); // DEBUG
      foreach($sonoslists as $sonoslist)
      {
      if ($sonoslist['title']==’Testlist’) {
      echo (“Starting: “.urldecode($sonoslist['file']).”…\n\r”);
      $sonos->SetQueue(urldecode($sonoslist['file']));
      }
      }

      $sonos->Play();

      Grüße, Benjamin

  18. Hi, schonmal vielen Dank für das Skript, läuft super! bräuchte allerdings noch folgende Funktion: gerät soll auf den audioeingang schalten. Ist so ein Befehl irgendwie möglich?

  19. Hallo!
    Versuche mich nun schon seit geraumer Zeit an dem Script leider läuft es bei mir aber alles andere als rund. Die Mute Funktion bringt mir nur die Fehlermeldung “undefined Index Mute” beim Rest sieht es zwar so aus als ob es durchläuft, meine Sonos Komponenten reagieren aber nur ab und an darauf. Kennt jemand diese Phänomen?

    Grüße René

  20. Hallo
    Erstmal Danke für das Script!
    Frage: ist ein Aufruf der Radiosender auch ohne DB möglich? Ist die DB zwingend?
    Danke
    Pat

    • Hi Pat,

      zwingend erforderlich ist die DB keineswegs. Du musst das Script dann halt umschreiben und die Sender z.B. in einem Array oder einer Textdatei ablegen.

  21. Hallo.
    Aber ist es denn nicht möglich die Radiosender im Sonos direkt aufzurufen? Warum muss eine zus. Quelle (DB) vorhanden sein? Die Radio Quellen sind ja alle bereits im Sonos hinterlegt.
    Oder verstehe ich hier was falsch?

    Danke
    Pat

    • Hi Pat,ich kenne keine Möglichkeit, SONOS mitzuteilen einen bestimmten Radiosender von den hinterlegten abzuspielen.

      Viele Grüße

      Thomas

      • Thomas,
        ich habe noch das Problem bei den Messages. Einfügen und abspielen geht, jedoch wird die MP3 nicht mehr aus der Liste gelöscht. Beim erneuten aufrufen des Skriptes wird die MP3 dann nochmals und abermals in die Liste eingefügt (und natürlich alle abgespielt).
        any ideas?

        pat

    • Hallo,
      die Radio Favoriten kann man mit der aktuellsten PHPSonos Klasse über die Funktion Browse abfragen.

      So kann man beispielsweise den ersten Favoriten aufrufen:
      $browselist = $sonos->Browse(“R:0/0″,”c”);
      print_r($browselist); // DEBUG
      $sonos->SetRadio(urldecode($browselist[0]['res']));
      $sonos->Play();

      Viele Grüße, Benjamin

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>