SONOS PHP Class

Ah, jetzt sehe ich es. Ich hatte im IPS Skript Editor über „In Skripten suchen…“ gesucht, aber die Funktion hat nichts gefunden, da die Scriptdatei nicht eingebunden war. Vielleicht könnte der Installer das übernehmen:

$ScriptId=@IPSSonos_CreateScript ('Sonos Class', 'sonos\sonos.ips.class.php', $ScriptCategoryId);

Ich habe das bei mir mal nachgeholt.

Nun habe ich mich mal test halber für die Events eines Players registriert:

include('sonos\Sonos.IPS.class.php');

$player = new IPSSonosPlayer( 49173 /*[Scripts\SONOS Xaver\SONOS\Geräte\Bad]*/ );

$player -> RegisterEvents();

Das Script läuft fehlerfrei durch, aber sonst passiert nichts. Erwartet hätte ich, dass wenn ich über den Sonos Player nun eine Aktion durchführe (z.B. einen Titel abspiele), diese Notification über den Server Socket hereinkommt und man das über das Debug Fenster beobachten kann. Leider kommt da aber nichts.

Vielleicht klappt bei mir die Registrierung noch nicht richtig. Kann man das über http://192.168.178.xx:1400/status/topology oder ähnliches herausfinden?

Mein Ziel ist zunächst, Lautstärkeänderungen der Player mitzubekommen. Ich denke, ich bin schon kurz davor:)

Vielen Dank nochmal für deine Geduld!

Burkhard

Habe mal so einiges Überarbeitet:


<?
include ('sonos\sonos.ips.install.php');
/* Parameter
/*   SonosRootCategoryId (int) Start Kategorie ID fürs erstellen der Structur
/*   WFC_ID (int) WefrontKonfiguratorId  Wenn Angegeben wird das WebFront erstellt
/*   WebFrontRootItem (string) Start Item unterhalb der Position werden die Einträge erstellt
/*
/*   Bei neu Installation 2 x durchlaufen lassen.
/*
/*   Keine Garantie oder Gewährleistung auf schäden, vorher immer besser dir Konfiguration
/*   von IPS zu sichern oder am besten natürlich auf einem Test System ;-)
/*
/*   Zum besseren Testen würde ich ein eigenes Web Front nehmen ;-) sonst nicht getesten
*/
$ParentKategorie=0;
$WFC_ID=0  /*[Test]*/;
$WFC_Parent='roottp';

IPSSonos_Install($ParentKategorie,$WFC_ID,$WFC_Parent);
?>

Zu den Gravierenden Änderungen !!!

  • sonos.ips.install.php

    • Überarbeitet
  • sonos.class.php

    • fix : fehler beim ansteuern des players (‚Master‘) behoben
    • fix : Variablen Parameter mit Vorgabe werten bei Funktion nach hinten gestellt
      wie es sich eigentlich auch gehört.
      vorher zb. SetMute(InstanceID=0,$mute)
      jetzt SetMute($mute,InstanceID=0) :wink:
  • sonos.ips.splitter.class.php

    • fix : Richtige SIDS werden nun erkannt und die Geräte aktuallisiert
  • sonos.ips.class.php

    • Add: Steuerung => State, Mute, Volume, GroupMute, GroupMute, CrossfadeMode, LEDMode, PlayMode
  • sonos.ips.commands.php

    • Add: Steuerung => State, Mute, Volume, GroupMute, GroupMute, CrossfadeMode, LEDMode, Repeat, Shuffle
      Add: Steuerung SelectZone
  • diverses

    • Splitter Instance
      add: Parameter DEBUG_PATH (string) Wenn gesetzt werden dort die Empfangenen NOTIFY Events protokolliert bp. d:\ oder d: emp\

    • die komische sonos.ips.translations.php hab ich nun umbenannt zu sonos.ips.variables.php
      function der datei:
      Definition der Variablen die aus den Events zurück geliefert werden
      Steuert welche Variable wo angezeigt wird
      Legt fest welche Variable fest angelegt wird und welche dynamisch. (dynamisch ist noch im aufbau)
      Übersetzt Werte vom Gerät in Werte für IPS und umgekehrt

    und und und… Fortsetzung folgt.

Probleme:

  • Im Moment werden die Events von den Geräten nur sehr verzögert übertragen,
    dauert manchmal bis zu 1 minute oder länger…

  • Wer öfters mit den Events testet und …
    nicht jedes mal im Webfrontend unter den Jeweiligen Playern das UnRegisterEvent Script ausführt
    oder ein Event mit dem RegisterEvent Script acktiviert hat
    und O H N E vor das UnRegisterEvent Script zu starten
    mehrfach deinstalliert (löscht) und wieder installiert
    oder das install script öfters startet … uffff

     kann Probleme mit dem EventManagement der Geräte bekommen. In diesem Fall wird immer eine
     alte SID in den NOTIFYS zurückgeliefert und der Splitter kann damit nichts mehr anfangen.
     
     Abhilfe: Ganz einfach die betroffenen Player/Geräte kurz vom Strom trennen. Damit werden
     die internen Zähler der Geräte wieder auf 0 gesetzt.
    

@ToDo: UnInstall Function
@ToDo: Register All Events for Devices , at this time only AVTransport are watched
@ToDo: Register All Events from all Devices at the same time
@ToDo: Description of any unit :frowning:
@ToDo: Splitter Instance Puffer überlauf abfangen (maximale größe der Events ermitteln)
@ToDo: Standard Befehlsumfang der commands Erweitern

Man verzeihe mir Rechtschreibfehler :wink:

Wer es schon installiert hat am besten vorher löschen.
Wer es noch nicht kennt … alle Dateien aus dem Archiv nach /script/sonos/ kopieren.

Rückmeldungen wären toll… allerdings hab ich nicht immer die Zeit was zu ändern. Ergänzungen und Vorschläge kann ich ab jetzt aber versuchen einzubauen,

cu Xaver

Mal wieder früh geworden;)

sonos.ips,v4.zip (33.7 KB)

Hallo Xaver,

ich habe meine Testumgebung nun auf deine Scripte V4 umgestellt. Die Installation klappte soweit (es wurde alles angelegt und die Geräte wurden nach Angabe des ‚Master Device Host‘ in Schritt 2 gefunden).

Nur mit den Events komm ich nicht weiter. Ich habe die ‚Adresse für Event Callback‘ eingetragen und auch den Port 9999 in der Firewall des IPS Servers freigegeben.

Mein Testscript

include('sonos\Sonos.IPS.class.php');

$player = new IPSSonosPlayer( 32927);

$player -> RegisterEvents();

läuft auf einen Fehler:

Fatal error:  Uncaught exception 'Exception' with message 'Error sending command: HTTP/1.1 412 Precondition Failed
Server: Linux UPnP/1.0 Sonos/28.1-83040 (ZP120)
Connection: close

' in C:\IP-Symcon\scripts\Sonos\sonos.class.php:282
Stack trace:
#0 C:\IP-Symcon\scripts\Sonos\sonos.class.php(347): SonosUpnpDevice->sendPacket('SUBSCRIBE /Medi...')
#1 C:\IP-Symcon\scripts\Sonos\sonos.class.php(220): SonosUpnpClass->RegisterEventCallback('http:\\192.168....', 300)
#2 C:\IP-Symcon\scripts\Sonos\sonos.ips.class.php(182): SonosUpnpDevice->CallService('AVTransport', 'RegisterEventCa...', Array)
#3 C:\IP-Symcon\scripts\38506.ips.php(7): IPSSonosPlayer->RegisterEvents()
#4 {main}
  thrown in C:\IP-Symcon\scripts\Sonos\sonos.class.php on line 282
Abort Processing during Fatal-Error: Uncaught exception 'Exception' with message 'Error sending command: HTTP/1.1 412 Precondition Failed
Server: Linux UPnP/1.0 Sonos/28.1-83040 (ZP120)
Connection: close

' in C:\IP-Symcon\scripts\Sonos\sonos.class.php:282
Stack trace:
#0 C:\IP-Symcon\scripts\Sonos\sonos.class.php(347): SonosUpnpDevice->sendPacket('SUBSCRIBE /Medi...')
#1 C:\IP-Symcon\scripts\Sonos\sonos.class.php(220): SonosUpnpClass->RegisterEventCallback('http:\\192.168....', 300)
#2 C:\IP-Symcon\scripts\Sonos\sonos.ips.class.php(182): SonosUpnpDevice->CallService('AVTransport', 'RegisterEventCa...', Array)
#3 C:\IP-Symcon\scripts\38506.ips.php(7): IPSSonosPlayer->RegisterEvents()
#4 {main}
  thrown
   Error in Script C:\IP-Symcon\scripts\Sonos\sonos.class.php on Line 282

Kannst du damit etwas anfangen und mir einen Tipp geben?

Viele Grüße

Burkhard

Verusche mal deinen Player neu zu starten. Sprich Strom aus, Strom an.
Ich werde die Tage mal schauen, aber der Fehler wird, denke ich, von dem Player produziert.

Das mit den Events kannst du vielleich auch hiermit testen. IPS-Steuerung-ect-mit-ServerSocket-und-Register-Variable

cu Xaver

Habe ich probiert, auch mit verschiedenen Playern, leider immer das gleiche Ergebis: 412 Precondition Failed

Super Skript, mein Respekt! Funktioniert tadellos, auch mit Port 9999.

Kann ich noch irgendetwas ausprobieren? Wenn ich mir mit echo den Inhalt von $content beim sendPacket ausgeben lasse, dann erhalte ich:

SUBSCRIBE /MediaRenderer/AVTransport/Event HTTP/1.1
HOST: 192.168.178.38:1400
CALLBACK: 
NT: upnp:event
TIMEOUT: Second-300
Content-Length: 0

Müsste CALLBACK nicht gefüllt sein? Bin momentan ratlos :frowning:

Edit: CALLBACK ist doch gefüllt und zwar mit ‚<http://xxx.xxx.xxx.xxx:9999>‘. Nur echo hat Probleme mit ‚<‘ …

Viele Grüße

Burkhard

Ja , Stimmt … Du findest aber auch immer alle Fehler die ich Einbaue g . Bin im Moment, wie du sicher hier im Forum lesen kannst, an vielen kleinen Ecken am basteln.
Da wird irgend was mit dem Auslesen der IPS Variable des Callbacks nicht passen.
Hier meine Kleine-Toolbox, hilft zwar nicht direkt, aber ich nutze fast immer dumpvar sieht besser aus

Da warst du schneller aller ich, dem ‚echo‘ einen Streich gespielt hat:D

dumpvar bringt die Wahrheit ans Licht:

--=> DUMPVAR (string) => SUBSCRIBE /MediaRenderer/AVTransport/Event HTTP/1.1
HOST: 192.168.178.38:1400
CALLBACK: <http:\\192.168.178.69:9999>
NT: upnp:event
TIMEOUT: Second-300
Content-Length: 0

CALLBACK ist also doch richtig gefüllt. Wäre ja auch zu einfach gewesen:(

Viele Grüße

Burkhard

Hallo zusammen,

erst mal vielen Dank an Xaver für die Classe und Burkhard als Tester.

hier mal kurz mein Ergebnis zur V4. Alles gelöscht, incl Server u Splitter.

Installation verlief bis auf einen Fehler problemlos.

Warning: Cannot auto-convert to Integer from Variant. Error: Invalid argument in [Objekt #30838 existiert nicht] on line 295

IP meines einzigen Players eingetragen, nochmal ausgeführt, alles super, Geräte gefunden, alles angelegt.

In der FW des IPS-Servers Port 9999 TCP freigegeben, Debug an der Serverinstanz und am Splitter aktiviert, Register Events gedrückt, es kommen Daten. Für gute 3 Minuten.

Leider Funktionieren manche Buttons im WF nicht. Mute wird geschaltet, aber die Variable aktualisiert nicht. Beim wieder ausschalten wird dann die Variable gesetzt, aber halt auf an.
Die Lautstärke wird gesetzt, und der Balken aktuelaisiert, aber nicht, wenn ich die Lautstärke über die App verändere.
Repeate u. shuffle laufen auf Fehler.

So weit,

Dann ändere mal http:\ in http:// :wink:
cu
Xaver

Jepp, die erste Fehlermeldung hab ich auch… (bisher immer übersehen :wink: … macht aber nix,
und Jepp viele … (öhmmmmm fast alle) funktionen sind noch nicht eingebunden. Im Moment sollten gehen,
GruppenLautstärke und Mute, Start, Stop, Pause, vor, zurück, öhmmm bin am überlegen ???

Ok… den Fehler mit der umgeherten Mute funktion/anzeige werde ich fixen, Danke .
Ebenso werden die Lautstärke ect. noch nicht akuallisiert.

Ich bin ehrlich gesagt noch nie dazu gekommen, die events länger als 3 Minuten zu testen, aber …
unter der Konfiguration kann man die zeit einstellen. Vorgabe sind 300 Sek das sind … 5 min.

Mich würde mal interessieren ob bei dir / euch auch die reaktion so träge ist. Sprich wenn ich mit dem Handy umschalte dauert es manchmal bis zu 1 minute bis was passier.

cu Xaver

Ach und natürlich ob sich eine Weiterentwicklung lohnt sprich Interesse besteht :confused:, und ob jeman mit machen möchte :smiley: und… nee jetzt reichts aber :eek:

zu blöd:eek: Das war’s.

Nun klappt das Registrieren und im Debug Fenster des Sockets sieht man Nachrichten hereinkommen.
Die Nachrichten werden auch im SonosSplitterScript verarbeitet, aber mehr passiert noch nicht.

  • außer der SID wird keine weitere Variable des Gerätes aktualisiert
  • es werden im Debug Pfad (bei mir c:\ip-symcon\logs) ganz viele Logdateien angelegt, die ich aber noch nicht verstehe

Sollte da nicht schon mehr passieren?

Auch kommen bei Lautstärkeänderungen oder Mute On/Off noch keine Events.

Soweit als kurzer Zwischenbericht.

Viele Grüße

Burkhard

Danke dir Burkhard, die vielen log dateien … hab ich vergesen den debug_path raus zunehmen? die dateien sollten nur immer komplette events beinhalten und ich habe die gebraucht um die dateien zu untersuchen. Außerdem nutze ich die gleicht konstellation auch mit versuchen bei der Fritzbox und dem Homematic und dem Sony-Verstärker und dem Samsung TV … hahaha, so viel zu den Log Dateien. grins
Ich hatte das Problem auch da lag es eindeutig daran dass der Player neu gestartet werden musste. In den Log dateien sieht man zb. aud die SID die übertragen wurde. Diese MUSS auch in der CONFIG der SplitterInstace als serialized array abgelegt sein.
Du kannst, solltest aber auch im Message Log fenster Nachriten wie SEND oder READ ect. sehen wenn DEBUG > 0

cu
Xaver

Also bei mit steht in der Var „Debug Pfad für Events zb. d: mp“ nur True.
d: mp gibts bei mir nicht.
Wird dann trotzdem geloggt?
Wenn ja, wohin?
Nicht dass mir das die Festplatte zumüllt.

nein, den habe ich eingetragen, um den Zusammenhängen auf die Spur zu kommen.:slight_smile:

Das sieht eigentlich gut aus bei mir. Werde ich morgen mal näher untersuchen.

Die Verzögerungen sehe ich aber auch bei mir. Und Events bei Lautstärkeveränderungen scheine ich auch keine zu bekommen. Was müsste denn da in den Logs stehen?

Auch habe ich den Eindruck, dass die Registrierung nach ein paar Minuten automatisch beendet wird, obwohl ich 3600 sec vorgegeben habe.

Momentan bin ich mir noch nicht sicher, ob sich der Ansatz wirklich zur dauerhaften Playerüberwachung eignet. Wie bekommt denn wohl die SONOS App die Veränderungen mit? Das geht blitzschnell, fast „realtime“.

Viele Grüße

Burkhard

Ja das stimmt, ich denke bevor ich weiter an dem Outfit bastle sollte ich das mit den Events in den Griff bekommen.
Das ist auch in soweit Interessant das es die NOTIFYS bei vielen Geräten gibt.
Habe gestern mal die Packete gescannt und mir ist aufgefallen, dass die SonosSoftware auch einen oder zwei ports öffnet.

Was ich verstehe ist der erste Post der Software:
SUBSCRIBE /MediaRenderer/RenderingControl/Event HTTP/1.1
CALLBACK: <http://192.168.112.100:3400/notify>

Was ich (noch) nicht verstehe ist dieser Post:

SUBSCRIBE /upnphost/udhisapi.dll?event=uuid:e52add57-4517-4c32-ba18-672b515fb2f8+urn:microsoft.com:serviceId:X_MS_MediaReceiverRegistrar HTTP/1.1
USER-AGENT: Linux UPnP/1.0 Sonos/28.1-83040 (ZPS1)
HOST: 192.168.112.100:2869
SID: uuid:9708122f-74a5-48ad-ac26-db1911cd3c77
TIMEOUT: Second-3600

Da wird doch irgend was über Windows Registriert ?

cu
Xaver

Hallo,

vielen Dank für das Script.

An einer Stelle stehe ich auf dem Schlauch und würde mich über einen Wink in die richtige Richtung freuen. Ich möchte herausfinden, ob der Sonos gerade etwas abspielt und dafür GetTransportInfo() nutzen.

So sieht das Script aus:

$p=new SonosUpnpDevice('192.168.100.20');
print_r($p->GetTransportInfo());

das Ergebnis:

Array
(
    [CurrentTransportState] => PLAYING
    [CurrentTransportStatus] => OK
    [CurrentSpeed] => 1
)

Ich möchte den CurrentTransportState in eine Variable schreiben. Kann mir da kurz jemand in Form eines 3-Zeilers auf die Sprünge helfen?

Danke und Gruß,
Christoph


:
:
$p->GetTransportInfo();
SetValue(Var_ID, $p['CurrentTransportState']);

:wink:

Danke - aber genau so in der Art hatte ich es schon versucht.

Ich habe mit

echo $p['CurrentTransportState'];

getestet, aber sowohl bei meiner als auch bei Deiner Variante kommt:

Fatal error:  Cannot use object of type SonosUpnpDevice as array in D:\Programme\IP-Symcon\scripts\45356.ips.php on line 18

Grüße,
Christoph

include('sonos\Sonos.IPS.class.php');
$p=new SonosUpnpDevice('192.168.178.58');
print_r($p = $p->GetTransportInfo());
echo($p['CurrentTransportState']);

Vielen Dank!