SONOS PHP Class

Besten Dank für den Tipp, für den Anfang sollte ich die @ Einträge entfernen, damit die Fehler angezeigt werden ;-).
Normalerweise sollten alle Player die beim aufruf von IPSSonos_UpdateZoneInfos() in der Rückgabe von http://player:1400/status/topology enthalten sind, auch anlgelegt werden.
cu
Xaver

Ich habe noch einen zweiten Übeltäter auf Zeile 83 gefunden:

$tmp=@CreateVariable ('PL_'.$ident,0,VAR_WebFrontZonePlayersInstanceId,0,VAR_ProfilPlayAddZonePlayer,VAR_ActionScriptId,false,'');

Hier muss es auch „IPSSonos_CreateVariable“ statt „CreateVariable“ heißen.

Nun hat er alle Geräte angelegt :slight_smile:

Viele Grüße

Burkhard

Hallo Xaver,

hier fehlt mir leider noch etwas das Verständnis. Welche Adresse muss ich bei ‚Adresse für den Event Callback‘ ausfüllen? Auch die ‚Refreshzeit für Event Callback in sek.‘ ist mir leider noch nicht klar. Belasse ich es beim eingestellten Wert von 300 oder ist er hoch- bzw. herunterzusetzen? Muss ich dann die Scripte ‚Register Events‘ zyklisch aufrufen?

Ich brauche doch noch den einen oder anderen Anstoß :slight_smile:

Viele Grüße

Burkhard

Bei mir wird die Original Unit aus den IPSTools per __autoinclude automatisch geladen, daher sind mir die Fehler nicht aufgefallen. Wer die IPSTools installiert hat , wird von den Fehlern (womöglich) nichts merken :frowning:
cu
Xaver

Ok. Hier mal langsam, soweit es mir möglich ist:
Genau genommen wird duch den CallBack service die an den Player übergebene URL so lange bei Ereignissen des Players aufgerufen bis, entweder die URL nicht mehr erreichbar ist, oder die Zeit die (voreingestellt) 300 Sek , abgelaufen ist.
Du kannst ohne Probleme die Zeit auf 3600 oder höher setzten. Da musst du einfach probieren.

Die Übergebene URL wird vom Player bei einem Ereignis aufgerufen und es wird ein NOTIFY gesendet.

Dazu habe ich auf dem IPS Server einen eigenen ServerSocket installiert der die NOTIFY´S entgegennimmt und an die damit verbundene RegisterVariable (sozusagen) weiter reicht.

Die RegisterVariable arbeitet als Splitter, bei der durch den Aufruf der RegisterEvent funtion aus der IPSonosPlayer klasse dessen EventSid gespeichert wird, Die ist notwendig um die eingehenden Ereignisse in der Splitter Class den jeweiligen Playern zuzuordnen, als ob das nicht genug ist, kann jeder Player bis zu (glaube) 10 Events registieren.

Es git sicher noch viel zu bastenl, aber ich habe so viele kleine Projekte dass mir meist die Zeit fehlt kontinuierlich an einem zu Arbeiten.

Einige ToDoS stehen ja in der Install Datei.

cu
Xaver

Version OHNE die bisher gefundenen Fehler

sonos.ips.Beta_3.zip (30.1 KB)

Vielen Dank für die Erklärung. Das Prinzip ist mir jetzt soweit klar. Aber was muss ich in die Variable ‚Adresse für den Event Callback‘ einsetzen? Das ist mir noch unklar. Muss da eine IP Adresse rein?

Viele Grüße

Burkhard

Rein muss da die Adresse/IP des IPS Servers, zb. http://192.168.1.xxx:9999
9999 steht für den Port den ich als Vorgabe gesetzt habe und der im IPS Server dafür eingerichtete ServerSocket auf dem Port 9999 die NOTIFYS entgegen nimmt.
Den Port kannst du frei wählen, entweder schon im Installscript, oder in dem du den ServerSocket-Port änderst.

cu Xaver

Das macht Sinn. Nun suche ich noch die Stelle, wo dieser Wert verwendet wird. Meinem Eindruck nach wird weder ‚VAR_CallbackUrlID‘ noch ‚VAR_CallbackTimeID‘ irgendwo verwendet:confused:. Müssen nicht diese Informationen an den Player übergeben werden?

Viele Grüße

Burkhard

Ich lese hier gespannt mit und versuche die Lösungsvorschläge mit umzusetzen.

Bumaas stellt aber präziesere Fragen als ich es könnte.

Nur weiter so. Ihr seid nicht allein.

Die Variablen werden in der function „public function RegisterEvents()“ in der sonos.ips.class.php verwendet.


$player = new IPSSonosPlayer( PlayerInstanceObjectID );
$player->RegisterEvents();

Die Events sollte immer mit der Function RegisterEvents() aufgerufen werden weil damit auch das SID handling realisiert wird.

Ich merke schon, ich habe Probleme das verständlich zu erklären. (Programmierer Los hahaha)

cu Xaver

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: