Sonos steuern

Begonnen von Will, 05 Januar 2013, 15:51:12

Vorheriges Thema - Nächstes Thema

Elektrolurch

Hallo Reiner(lein),

danke für die Info. Ich habe mal die Kette der benötigten SW-Bestandteile nachvollzogen. Leider habe ich vor 20 Jahren mit C++ aufgehört und muss mich erst einmal wieder da aktualisieren.
Frage eines Neuanfängers: Ich brauche also dafür php. Das ist ja wohl eine Web-Server Erweiterung, z.B. bei einem Apache - Server. Ich nutze jetzt derzeit für das fhem-Projekt eine AVM FB 7390. Da läuft ja auch ein Webserver. Leider konnte ich so adoc nicht herausfinden, ob da auch schon php aktiv ist. Fehlen mir ja leider mal die Kenntnisse. Einen Apache mit php zusätzlich zu installieren, ist ja wohl nicht so ein großes Problem, ev. aber auch nicht notwendig?
Ansonsten wäre ja Dein php-Ansatz genau das, was ich bräuchte, um einen Alarm auf den AVs im Haus abzuspielen.
Ach ja: Du schriebst - Ansonsten kann ich dir nur zum Thema UPnP sagen, dass die Sonos Geräte sehr speziell in Bezug auf UPnP programmiert wurden. Mit einem normalen UPnP-Steuerprogramm wirst du die nicht vernünftig/einfach beeinflußen können, genauso wie andersherum mein Modul für andere, per UPnP
Mein dummes Nokia Handy kann zumindest über die Funktion "Eigene Geräte" Quellen und Ziele über UPnP verheiraten und bei den Sonos-Playern auch die Lautstärke einstellen. (!!!! Du schriebst ja, dassdas nicht mehr Standard bei den Sonos sei)

Gruß Elektrolurch
configDB und Windows befreite Zone!

Reinerlein

Hi Thorsten,

also, meine Import-Liste ist mittlerweile etwas länger, daher weiss ich nicht mehr ganz genau, welches Modul für den Reibungslosen Betrieb von PerlUPnP notwendig waren.

Aus den dem PerlUPnP-Modul selbst werden folgende Pakete eingebunden:
  • HTTP::Headers
  • HTTP::Daemon
  • HTTP::Response
  • HTTP::Status
  • LWP::UserAgent
  • LWP::Protocol
  • IO::Socket
  • IO::Socket::INET
  • Socket
  • IO::Select
  • SOAP::Lite
  • Scalar::Util
  • XML::Parser::Lite
  • Data::Dumper
  • HTML::Entities
  • Time::HiRes
Von mir kommt momentan noch dazu:
  • LWP::Simple
  • Net::Ping
  • Net::Telnet
  • File::Path
  • threads
  • Thread::Queue
  • threads::shared
Selber liefere ich noch mit:
  • PerlUPnP
  • MP3-Tag Library

Wobei einige davon bereits im Standard-Perl enthalten sind, und einige auch gemeinsam in einem Installations-Paket enthalten sein dürften. Ich nehme da eher wenig Rücksicht, da ich mein Modul zum Laufen bringen möchte, und halt notfalls einfach Dinge nachinstalliere. Manchmal kann man sich ja einschränken, aber ansonsten vertrete ich die Meinung, nicht das Rad nochmal erfinden zu müssen.

Zu dem Letzten Post (der gerade beim Tippen reingerauscht kam :-):
Du kannst mit dem Device-Spy alle deine UPnP-Devices im Netz sehen, und die zur Verfügung gestellten Prozeduren (inkl. deren Parameter und Auswahlmöglichkeiten) sowie die zur Verfügung gestellten Typen sehen.
Desweiteren kannst du dich für die zur Verfügung gestellten Events registrieren, und die dabei übergebenen Werte ansehen.
Die Sequenzen, die du meinst, beziehen sich dann auf den eigentlichen Inhalt der Parameter eines solchen Aufrufs.

Spiel erstmal rum, was du mit dem Spy bereits alles erreichen kannst...

Grüße Reiner

Reinerlein

Hallo Elektrolurch,

für den Betrieb der reinen PHP-Konsolenanwendung brauchst du natürlich keinen Apache. Da reicht die eigentliche PHP-Installation.
Etwas trickreich war da die Installation der UPnP-Erweiterung für PHP, das habe ich aber ein bißchen im Post beschrieben, das hat bei mir auch etwas gehakt. Da musst du vielleicht ein bißchen Googlen...

Ob PHP installiert und ausführbar ist, kannst du einfach auf der Konsole durch Eingabe von "php --version" herausfinden:
pi@raspberrypi ~ $ php --version
PHP 5.4.4-12 (cli) (built: Feb  1 2013 08:58:27)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
Dies mal die Ausgabe auf meinem Raspberry Pi.

Mit php -r "phpinfo();"z.B. kannst du schauen, ob dein UPnP dann geladen wurde.
Die Ausgabe ist sehr lang, da alles interne von PHP ausgegeben wird. Am Besten per grep durchsuchen:pi@raspberrypi ~ $ php -r "phpinfo();" | grep upnp
gupnp
gupnp support => enabled


Zu deinem Nokia-Handy:
Es werden im Standard zwei Methoden für die Lautstärkenanpassung vorgeschrieben ("SetVolume" und "SetVolumeDB") und nur die SetVolume funktioniert bei meinem Sonos. Das bedeutet, dass dein Handy instinktiv (und so würde das ja auch jeder Mensch im Normalfall machen) das richtige gemacht hat. Meine UPnP Teststeuersoftware konnte das nicht.
Ich wollte auch hauptsächlich darauf hindeuten, dass man immer schauen muss, ob es funktioniert. Man kann sich leider nicht einfach drauf verlassen. Natürlich wird einiges intuitiv klappen, allerdings auch einiges nicht.
Hat denn bei den Sonos-Playern das Starten eines Titels (besser gesagt: das Ablegen eines Titels in der Abspielliste mit anschließendem Start der Wiedergabe) funktioniert? Das hatte bei mir nämlich auch nicht geklappt.
Aber egal... das sind nur Beispiele... es soll am Ende ja alles funktionieren :-)

Grüße Reiner

crazystone

Also ich habe mal ein bisschen mit dem Intel Device Spy und den anderen Tools herumgespielt. Ist wirklich ernüchternd...

Also auch wenn es nicht hierher gehört (weil ja kein Sonos sondern Philips Streamium und nicht FHEM, noch nicht ;-)) mein NP290 versteht, Play, Stop, Pause, Balance, laut/leise. Ich kann gezielt ein einzelnes Media File abspielen. Das wars dann auch. Ich habe etliche Male Fehlermeldungen bekommen ("Server nicht verfügbar"), beim Versuch mehrere Files hintereinander abzuspielen, Radio zu starten (Play und Stop im Radio Mode). Es gab natürlich etliche Funktionen (Mute, PresetList, SelectPreset, Seek) die ich mit den Standard Tools nicht testen konnte.

Eine Erfahrung war auch, was da sonst noch alles abläuft. Eine Fritz Powerline PL546 die da reinspuckt, eine FB die DSL und WAN Status herumposaunt, Kathrein Receiver, die sich nur als rootdevice melden, aber sonst nix anzeigt, und natürlich etliche PCs mit verschiedenen Services, Content Container etc.

Am meisten hat mich gewundert, dass ich bei einem Internet-Radio wie dem NP290 keinen aktuell abgespielte Radiostream gefunden habe. Bin gespannt, was das PresetList oder Seek dann mal liefert.

Es ist mir jetzt durchaus klar, dass das Abfangen des Urwalds eine ganz schöne Herausforderung wird. Ich habe es mit dem ControlPoint auch nicht wirklich geschafft, ein Abspielen zu starten. Das klappte dann wirklich nur mit der Beispielanwendung (Auswahl eines Files per FileBrowser). Da wäre ich auch nochmal dankbar für die Erläuterung der Einzelschritte. Gewundert hat mich auch, das der Status (STOPPED) immer angezeigt wurde, auch während des Abspielens. Ideen?

Viele Grüße


Reinerlein

Hi Thorsten,

willkommen in der wunderbaren Welt von UPnP :-)
Nee, mal Spaß beiseite, hauptsächlich will der nur spielen.

Für das von mir verwendete Modul sieht die ControlPoint-Definition so aus:$SONOS_Controlpoint = UPnP::ControlPoint->new(SearchPort => 8008, SubscriptionPort => 9009, SubscriptionURL => '/eventSub', MaxWait => 10);
$SONOS_Search = $SONOS_Controlpoint->searchByType('urn:schemas-upnp-org:device:ZonePlayer:1', \&SONOS_Discover_Callback);
$SONOS_Controlpoint->handle;
Wie man erkennen kann, kann man beim Controlpoint bereits die Suche einschränken.
Bei mir melden sich die Zoneplayer eben wie oben definiert.
Das sieht bei anderen UPnP-Modulen zwar anders aber im Kern doch ähnlich aus...

Im ersten Schritt solltest du also mal schauen, ob du durch eine vernünftige Einschränkung dort etwas erreichst.

Aber für ein allgemeingültiges Modul müsste das natürlich frei definierbar sein. Desweiteren müsste irgendwie in einem Attribut definiert werden, was beim Discovern (sprich beim Erkennungsvorgang der gefundenen, bzw. sich meldenden Geräte) passiert.
Wie gesagt, ich bezweifel, dass da wirklich viel geht, was dann am Ende noch als Vereinfachung gegenüber einer normalen Modulentwicklung durchgehen könnte...

Aber natürlich gilt trotzdem (zumindest für mich): Was man mit dem Spy nicht simulieren/steuern kann, wirst du auch nicht mit deinem eigenen Modul hinbekommen. Zumindest nicht über den Standard-UPnP-Aufruf.
Man sollte UPnP als das betrachten, was es ist: Eine Erweiterung zu einem Netzwerkprotokoll wie TCP/IP, mit der man den Zugriff auf Geräte Standardisieren kann. Das bedeutet leider noch längst nicht, dass man auch alles steuern kann.
Bei Sonos z.B. gibt es auch einige Aufrufe, deren Inhalte verschlüsselt sind. Das betrifft zwar hauptsächlich so Dinge wie Benutzerzugänge o.ä. aber ärgerlich ist natürlich, dass man das dann gar nicht mehr rausbekommt (zumindest nicht ohne SONOS-Quellcode :-).

Grüße Reiner

betateilchen

Zitat von: Reinerlein schrieb am Mi, 21 August 2013 22:56Das sieht bei anderen UPnP-Modulen zwar anders aber im Kern doch ähnlich aus...
Im ersten Schritt solltest du also mal schauen, ob du durch eine vernünftige Einschränkung dort etwas erreichst.
Aber für ein allgemeingültiges Modul müsste das natürlich frei definierbar sein.

ja, und für ein "allgemeingültiges" Modul muss man im Vorfeld noch über völlig andere Dinge nachdenken. Zum Beispiel muss ich mindestens zwei Gerätetypen immer implementieren: ein Geräte das die Mediadaten liefert (z.B. Typ Mediaserver) und einen Gerätetypen, der die Mediadaten wiedergeben kann (z.B. Typ Mediarenderer)

Und dann gibt es noch Geräte, die beide Funktionen bereitstellen und dabei auch noch dummerweise die gleiche UUID verwenden...

usw. usw.

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Reinerlein

Hi Betateilchen,

genau, soweit ich das aber überblicke, sind Geräte, die beides können, aufgetrennt in verschiedene Devices, die die jeweilige Arbeit Erledigen.
Bei Sonos z.B. gibt es zwei Sub-Devices: Eines, welches "Media Renderer" heißt, und eines das "Media Server" heißt.
Das bedeutet bei der Suche viel mehr Arbeit, da man ja auch alle Sub-Devices durchsuchen muss, die melden sich, zumindest bei Sonos, nicht einzeln, sondern nur über ihr Hauptdevice (also dem physikalischen Gerät entsprechend).

Allerdings unterscheiden sich bei Sonos wenigstens die UUIDs. Dort wird immer die des Hauptdevices verwendet und etwas angehangen:
_MR -> Für den Media Renderer
_MS -> Für den Media Server

Hast du Geräte, die beides können, aber das nicht durch virtuelle Trennungen deutlich machen?
Das wäre ja dann richtig blöd... Dann könnte man die noch nichtmal nach der Erkennung auseinanderhalten...

Grüße Reiner

Reinerlein

Hi zusammen,

zwischendurch auch mal wieder eine Statusaktualisierung zur eigentlichen Sache: Dem Sonos-Modul.

Ich habe nun mein neues Konzept eingebaut, und ich muss sagen, dass es deutlich stabiler als vorher läuft. Ich habe auch schon die Unterstützung für Gruppenbildungen und den daranhängenden Themen eingebaut:
  • Man kann zentral eine Konstellation ausgeben lassen und diese auch in einem Rutsch einstellen lassen.
      Das Format ist dann z.B. "[Sonos_Kueche], [Sonos_Wohnzimmer, Sonos_Schlafzimmer]", wobei die Reihenfolge innerhalb einer Gruppe wichtig ist. Der erste Eintrag ist der sogenannte Gruppenkoordinator, beim Einstellen der Gruppe also der, wo die Musik herkommen wird.
  • Man kann am Player-Device selbst ein "AddMember <DevName>" oder "RemoveMember <DevName>" ausführen. Dann wird zu dem Player-Device das angegebene Device "Dazugruppiert", und die Wiedergabe dahin mit übergeben.
  • Man kann die Steuerbefehle (Play, Pause, Next usw.) an einem beliebigen Player einer Gruppe ausführen. Die Anweisungen werden automatisch an den Koordinator weitergeleitet und dort ausgeführt. Dadurch kann es einem persönlich eigentlich egal sein, wer der Koordinator ist (ausser das beim Einrichten der Gruppe die Playliste des Koordinators zählt)
  • Man kann Gruppenlautstärke und GruppenMute setzen. Das funktioniert dann wie am Original-Controller so, dass der relative Abstand der Lautstärken beibehalten wird, und die Gesamt-Gruppenlautstärke angepasst wird. Natürlich kann man immer noch die Lautstärke an einem Device selber einstellen; diese Änderung hat dann auch nur Auswirkungen auf den einzelnen Player.
  • "PlayURI" kann nun als Parameter einen Devicenamen erhalten, und spielt dann den AV-Eingang des über diesen Parameter definierten Players am gewählten Device ab. Das muss auch nicht der Player sein, an dem der Eingang physikalisch dran ist...
Allerdings gibt es noch etwas zu basteln:
Als Folge der Konzeptumstellung bleibt noch eine kleine Baustelle offen, die ich noch schließen muss. Dann geht es hier weiter...

Für diejenigen, die es Interessiert (zum leichteren Überspringen als Zitat):
ZitatDas Konzept sieht vor, dass für den ganzen UPnP-Kram aus dem Modul heraus ein eigener Prozess gestartet wird, der dann nicht mehr die "Altlast" FHEM mit sich rumträgt, und wieder sauber threaden kann.
Für den Anwender ändert sich nur die Konfiguration des zentralen Sonos-Devices, da dort nun ein "Host:Port" mit angegeben werden muss, also z.B. "localhost:4712".
An dieser Stelle wird ein laufender Host gesucht, und wenn dieser nicht gefunden wird, wird versucht lokal selber durch einen Neuprozess einen zu starten. Dieser Prozess lauscht dann auf dem Port auf eingehende Verbindungen von FHEM. Dazu wird das FHEM-Standardverfahren für Netzverbindungen verwendet.
Wenn eine Verbindung zustande kam, werden die ganzen UPnP-Sachen gestartet und die entsprechenden Meldungen an FHEM weitergeleitet.

Das hat zu Folge, dass FHEM bzgl. der Befehle "rereadcfg" und "shutdown" auch wieder normal benutzt werden kann, also man auch wieder die fhem.cfg Datei über die Oberfläche editieren und speichern kann.

Viel passiert also, und bald wird es in die Runde gestreut, damit sich hoffentlich jeder dran erfreuen kann.

Grüße Reiner

der-Lolo

Hallo Reinerlein,
Sag mal ist eigentlich absehbar wann das "bald" ist? Kannst du sagen wann das Sonos Modul eingecheckt wird..?
Ich überlege gerade ob ich als nächstes meine Sonos Komponenten integriere oder aber mich um optische Belange kümmer und einen Floorplan erstelle...
Gibt es das Sonos Modul nach deiner Einschätzung noch im September - Oktober?

Reinerlein

Hallo Der-Lolo,

ich bin eigentlich soweit durch, und seit heute im Produktivtest auf meinem Raspberry Pi. Dort taucht aber Erfahrungsgemäß immer noch die eine oder andere Unstimmigkeit auf (ist bei mir ja ein Wechsel von Windows, als Entwicklungsumgebung, auf Linux), die es zu beheben gilt :-)
Vor allem nach einer solchen Änderung...

Ich habe auch schon den Thirdparty-Update Mechanismus/Server dafür eingerichtet, sodass die Installation auf eurer Seite mittels eines FHEM-Befehls erfolgen kann. Anschließend ist es natürlich genauso einfach eine neuere Version zu bekommen.

Also, ich gehe davon aus, dass es Anfang der nächsten Woche soweit sein könnte, wenn nichts gravierendes mehr im Test auftaucht.

Grüße Reinerlein

Reinerlein

Hallo zusammen,

ich muss hier noch ein bißchen verlängern. Ich habe beim Testen in meinem Produktivsystem noch ein paar kleine Phänomene entdeckt, die ich erst untersuchen muss.
Es bringt ja nix, wenn ihr das auch mühsam ausprobiert...

Es wird aber...

Grüße Reiner

Reinerlein

Hallo zusammen,

es ist soweit. Ich habe das Produkt nun in meinem System einige Zeit stabil am Laufen. Ich würde sagen, es ist soweit, dass ihr mit an dem Stand teilhaben solltet.

Ich habe den Wiki-Entrag dazu bereits angepasst.
Hier nur in Kürze etwas dazu:
  • Installation wird nun über den Update-Thirdparty-Mechanismus von Fhem erledigt. Dazu müsst ihr in das Eingabefeld
update thirdparty http://fhem.lmsoft.de/sonos sonos eingeben. Damit wird alles aktualisiert und/oder installiert. Die Vorbedingungen bzgl. Perl-eigener Module müssen natürlich trotzdem erfüllt sein. Hier werden nur die Dateien geliefert, die in dem Fhem-Pfad abgelegt werden (und vorher von mir hier immer veröffentlicht wurden).
  • Grundlegende Änderungen:
    • Es sind einige Get-Kommandos rausgeflogen. Alle Kommandos, deren Werte auch geliefert werden (können) haben nun keinen Getter mehr, sondern können nur noch aus dem entsprechenden Reading ausgelesen werden.
    • Alle Get- und Set-Kommandos laufen jetzt asynchron. Das bedeutet, dass ein Aufruf sofort zurückkehrt, und das Ergebnis des Aufrufs nach der Beendigung dann in dem entsprechenden Result abgelesen werden kann.
    • Für die Kommandos gibt es eine Queue, damit die eigentlichen Aufrufe an den Player nicht kollidieren.
    • Die Alarminformationen sind nicht mehr als Hash im Reading abgelegt, sondern als String, der per "eval" wieder in einen "echten" Perl-Hash umgewandelt werden kann.
  • Neues:
    • Man kann nun Button-Events definieren. Damit kann man z.B. einen Play5 einigermaßen autark betreiben, ohne immer einen Controller zur Hand zu haben. Näheres dazu im Wiki
    • Man kann (wie bereits woanders mal geschrieben) Gruppen bilden, auflösen und den Gesamtzustand ermitteln und festlegen
    • Durch die neue Thread- und Prozessstruktur läuft das Speak auch wieder stabil
    • Dadurch, dass der UPnP-Teil in einem eigenen Prozess läuft, ist auch dessen Log-Ausgabe nicht mehr im Fhem-Kontext und kommt direkt auf dem Standard-Out raus. Im Normalfall hat man diesen Stdout in seinem Start-Skript auf eine Datei umgelenkt, sodass man auch zur Laufzeit dort reinschauen kann. Der Loglevel wird aus dem globalen Verbose-Tag mit übernommen
    [/list]
    Ich hoffe, dass der Stand soweit stabil ist, dass auch bei euch alles läuft.
    Also etwas Nachsicht, wenn noch das eine oder andere Auftritt. Bei mir (Fhem auf Windows, Fhem auf Rapsberry Pi, 2x Play5, 1x Connect, 1x Bridge) läuft es momentan stabil.

    Viel Spass beim Verwenden und Basteln...

    Grüße Reiner

    der-Lolo

    Danke Reinerlein,
    Ich bin gerade die Umgebung am vorbereiten - es scheitert leider bei der SOAP::Lite Installation...
    Mal schauen ob ich das hinbekomme...

    Bei der von dir beschriebenen Hand Installation bleibt er auch hängen beim make Test


    Test Summary Report
    -------------------
    t/SOAP/Transport/HTTP/CGI.t                (Wstat: 512 Tests: 2 Failed: 2)
      Failed tests:  1-2
      Non-zero exit status: 2
    Files=33, Tests=854, 56 wallclock secs ( 4.08 usr  0.33 sys + 44.79 cusr  1.90 csys = 51.10 CPU)
    Result: FAIL
    Failed 1/33 test programs. 2/854 subtests failed.
    make: *** [test_dynamic] Error 255
    root@raspberrypi:~/soaplite/SOAP-Lite-0.715#



    Wenn ich es richtig verstehe steckt der Fehler irgendwo bei einem Ü


    01-core.t .................................. ok
    t/010-serializer.t ........................... ok
    t/012-cloneable.t ............................ ok
    t/013-array-deserialization.t ................ ok
    t/014_UNIVERSAL_use.t ........................ ok
    t/015_UNIVERSAL_can.t ........................ ok
    t/02-payload.t ............................... ok
    t/03-server.t ................................ ok
    t/04-attach.t ................................ skipped: Could not find MIME::Parser - is MIME::Tools installed? Aborting.
    t/05-customxml.t ............................. ok
    t/06-modules.t ............................... ok
    t/07-xmlrpc_payload.t ........................ ok
    t/08-schema.t ................................ ok
    t/096_characters.t ........................... skipped: (no reason given)
    t/097_kwalitee.t ............................. skipped: (no reason given)
    t/098_pod.t .................................. skipped: (no reason given)
    t/099_pod_coverage.t ......................... skipped: (no reason given)
    t/SOAP/Data.t ................................ ok
    t/SOAP/Lite/Deserializer/XMLSchema1999.t ..... ok
    t/SOAP/Lite/Deserializer/XMLSchema2001.t ..... ok
    t/SOAP/Lite/Deserializer/XMLSchemaSOAP1_1.t .. ok
    t/SOAP/Lite/Deserializer/XMLSchemaSOAP1_2.t .. ok
    t/SOAP/Lite/Packager.t ....................... ok
    t/SOAP/Schema/WSDL.t ......................... ok
    t/SOAP/Serializer.t .......................... ok
    t/SOAP/Transport/HTTP.t ...................... ok
    t/SOAP/Transport/HTTP/CGI.t .................. 1/?
    #   Failed test 'return utf8 string'
    #   at t/SOAP/Transport/HTTP/CGI.t line 57.

    #   Failed test 'utf8 content: Ã�berall'
    #   at t/SOAP/Transport/HTTP/CGI.t line 59.
    #          got: 'Ã�berall'
    #     expected: 'Überall'
    # Looks like you failed 2 tests of 2.

    Reinerlein

    Hi Der-Lolo,

    versuch doch mal die andere Installationsvariante mittelssudo apt-get install libsoap-lite-perlIch hatte da manchmal auch so meine Probleme, weswegen ich diese Variante auch beschrieben hatte...

    Grüße Reiner

    der-Lolo

    Interessant, das apt-get wählt ein Paket

    libsoap-lite-perl (0.714-1)

    Weil ich nicht viel weiter wusste bin ich in das Soaplite 0.715 Verzeichnis und habe dort das make Test abgesetzt...

    Test Summary Report
    -------------------
    t/SOAP/Transport/HTTP/CGI.t                (Wstat: 1024 Tests: 0 Failed: 0)
      Non-zero exit status: 4
      Parse errors: No plan found in TAP output
    Files=33, Tests=868, 67 wallclock secs ( 4.13 usr  0.38 sys + 54.12 cusr  2.35 csys = 60.98 CPU)
    Result: FAIL
    Failed 1/33 test programs. 0/868 subtests failed.
    make: *** [test_dynamic] Error 255


    Es funktioniert zwar immer noch nicht, aber es sieht besser aus als vorher...