Sonos Lautstärke mit Homematic Taster ändern

Hallo zusammen,

Habe mir soeben die Testversion von IP-Symcon installiert und auch gleich mal etwas probiert, nun möchte ich bei meinem Sonos Player die Lautstärke verändern mittelst eines HomeMatic Tasters.
Hierfür habe ich ein Skript angelegt, die Lautstärken Änderung funktioniert einwandfrei wenn ich auf „Ausführen“ klicke.

Ich vermute mal ich mache die Status abfrage des Tasters falsch, anbei mal mein Skript.

<?

$test=getValueBoolean(10159 /*[Taste 7 Badezimmer\PRESS_SHORT]*/); 
if($test==True);
{
SNS_ChangeVolume (19980 /*[Sonos]*/,+10);
}

?>


Ich möchte hier auch noch einen Langen Tastendruck für Volume -10 einbauen, dies sollte sich doch dann mit einer else bedingung einbauen lassen oder?

Ich danke schon mal recht herzlich für die Unterstützung :wink:

Liebe Grüße,

Du musst dem Skript ein Ereignis hinzufügen, welches auf Variablenaktualisierung der Tastervariable auslöst.

Dann viel Spaß beim Ausprobieren der Möglichkeiten von IP-Symcon.

Wichtig ist, dass Homematic Taster sich Aufgrund der Besonderheiten von Homematic nicht verhalten wie Homematic Aktoren, daher muss zunächst einmal sichergestellt sein, dass sich die Datenpunkte des Tasters auch in IP-Symcon aktualisieren, wenn der Taster gedrückt wird. Hierzu ist es hilfreich sich mal die Beschreibung HomeMatic-Taster in IPS durchzulesen. Bei Tastern kann man nur das Ereignis Variablenaktualisierung nutzten, daher funktioniert Dein Skript so auch nicht.

Um bei einem kurzen Tastendruck etwas Auszulösen ist wie folgt vorzugehen:

[ul]
[li]zunächst sicherstellen, dass alles auf der CCU so konfiguriert wurde das eine Aktualisierung der Datenpunkte stattfindet (HomeMatic-Taster in IPS )
[/li][li]Skript zu schalten
[/li]


<?
SNS_ChangeVolume (19980 /*[Sonos]*/,+10);
?>

[li]Skript markieren, CTRL+4 Ereignis hinzufügen -> Ausgelöstes Ereignis -> Variable PRESS_SHORT des entsprechnden Kanals des Tasters auswählen -> Auslöser: Bei Variablenaktualisierung -> Aktion: Skript starten, Ziel ist das Skript (siehe oben)
[/li][/ul]
jetzt sollte sobald der Taster einmal gedrückt wird das Skript ausgeführt werden. Man muss dann logischer Weise mehrmals drücken um jeweils die Lautstärke zu erhöhen.

Hierzu must Du mit den Datenpunkten PRESS_LONG und PRESS_LONG_RELEASE arbeiten und einer Hilfvariable und erneut einem Ereignis. Dazu muss erst mal sichergestellt sein das diese Variablen korrekt in IP-Symcon aktualisieren. (siehe Einrichtung oben). Wenn das gegeben ist bzw. das mit dem kurzen Tastendruck funktioniert und da Rückmeldung gegeben hast, kann man Dir dann auch im zweiten Schritt helfen.

Ergänzend ist es besser das Skript z.B. so zu wählen:

Lauter, Tastendruck bei Variablenaktualisierung z.B. Druck Oben


$volume = GetValue(IPS_GetObjectIDByIdent("Volume", 19980 /*[Sonos]*/)); // Auslesen der Variable Volume
 if($volume != 100)
 {
SNS_ChangeVolume (19980 /*[Sonos]*/,+10); 	
 }

Leiser, Tastendruck bei Variablenaktualisierung z.B. Druck Unten


$volume = GetValue(IPS_GetObjectIDByIdent("Volume", 19980 /*[Sonos]*/)); // Auslesen der Variable Volume
 if($volume != 0)
 {
 	SNS_ChangeVolume (19980 /*[Sonos]*/,-10); 
 }

Die if Bedingung stellt sicher, dass auch wirklich nur dann ein Befehl geschickt wird, wenn dies notwendig ist. Wenn die Lautstärke schon 100 % ist, muss ja auch nicht noch mal ein Befehl abgesetzt werden.

Vielen lieben Dank für die ganzen Antworten,

Jetzt klappt das soweit mit dem Lauterstellen.
Muss ich jetzt für das Leiser regeln ein neues Skript anlegen oder kann man auf 2 Ereignisse in einem Skript reagieren ?

Gruß,

Du brauchst auf alle Fälle zwei Ereignisse, weil diese ja unabhängig voneinander bei zwei Kanälen auftreten. Ganz simpel ist es, man nimmt einfach zwei Skripte, dann muss auch nicht weiter auswertet werden, da sich das Ereignis ja nur auf ein einzelnes Skript bezieht.

Es macht aber durchaus Sinn und ist insbesondere bei komplexeren Abläufen auch sinnvoll nur ein einziges Skript zu benutzten, was sich dann um den gesamten Ablauf kümmert.

Um dann zu differenzieren wann was ausgeführt werden soll, musst Du dann aber eine Abfrage einbauen.

Um festzustellen wer das Skript ausgelöst hat, gibt es in IP-Symcon Systemvariablen. Diese beinhalten je nachdem unterschiedliche Werte, in dem Fall ist ja eine Variable der Auslöser, also stehen auch die Systemvariablen zu Variable zur Auswahl bzw. in dem Skript zur Verfügung.

Ein einziges Skript sieht dann also so aus:


IPS_LogMessage("Sonos Lautstärke", "Event ".$_IPS['EVENT'].", ID ".$_IPS['VARIABLE'] ); // Gibt eine Meldung im Meldungsfenster aus
$volume = GetValue(IPS_GetObjectIDByIdent("Volume", 19980 /*[Sonos]*/)); // Auslesen der Variable Volume 
// Abfragen der auslösenden Variable über Objekt ID
if($_IPS['VARIABLE'] == 12345) // Auslöser ist Variable mit der ObjektID 12345
{
 if($volume != 100) 
 { 
	SNS_ChangeVolume (19980 /*[Sonos]*/,+10);      
 }  
}
if($_IPS['VARIABLE'] == 23456) // Auslöser ist Variable mit der ObjektID 23456
{
if($volume != 0) 
 { 
 	SNS_ChangeVolume (19980 /*[Sonos]*/,-10);  
 }  
}

Hier ist dann jeweils in der if Klammer die passende Objekt ID einzutragen die der Auslöser für das Ereignis ist

Hallo Fonzo,

Vielen dank für deine schnelle Antwort,

Ich habe jetzt in dem Skript die Objekt ID des Objektes PRESS_SHORT und PRESS_LONG eingefügt.

Beim test des Skriptes erscheint folgende Fehlermeldung:

Notice: Undefined index: EVENT in C:\IP-Symcon\scripts\10046.ips.php on line 3

Notice: Undefined index: VARIABLE in C:\IP-Symcon\scripts\10046.ips.php on line 3

Notice: Undefined index: VARIABLE in C:\IP-Symcon\scripts\10046.ips.php on line 6

Notice: Undefined index: VARIABLE in C:\IP-Symcon\scripts\10046.ips.php on line 13

Was mache ich hier Falsch?

Herzlichen Dank und lieben Gruß,
Adrian

Du darfst das Script nicht über die Console ausführen !
Diese Werte stehen nur zur Verfügung wenn das Ereignis das Script startet.

Michael

Danke für den Hinweis, jetzt funktioniert es natürlich :wink:

Ich bin begeistert, auch der Eintrag im Log ist so super um es nachzuvollziehen perfekt! :smiley:

Im Moment nutze ich das ganze noch über die RaspberryMatic CCU mit HVL um Sonos, Hue und Harmony zu steuern.

Ich schalte die Sonos Player momentan so:

Alle Player sind Aus / Pause drücke ich jetzt im Badezimmer eine Taste am HomeMatic taster geht der Speaker an.
Gehe ich nun in die Küche und drücke dort auf eine Taste am HomeMatic taster wird der Player in der Küche automatisch dem vom Badezimmer untergeordnet.

Drücke ich nun im Badezimmer wieder drauf bekommt der Küchenplayer automatisch den Coordinator zugewiesen und der Player im Badezimmer wird aus der Gruppe entfernt und auf Pause gesetzt.
Das funktioniert so mit beliebig vielen Lautsprechern.

Ist sowas auch mit IP Symcon als Anfänger zu realisieren ?
Oder ist das sehr komplex zu Programmieren ?

Gruß,
Adrian

Grundsätzlich geht alles, Du solltest erst mal mit einzelen Befehlen testen ob das ausgeführt wird was Du willst. Wenn das so funktioniert musst Du dann halt beliebig die Methoden hinter einander auflisten die Du willst das diese abgearbeitet werden.

Du brauchst dazu so was wie


SNS_SetGroup(integer $InstanceID, integer $groupCoordinator);
SNS_SetGroupVolume(integer $InstanceID, integer $volume);
SNS_Stop(integer $InstanceID);
usw.

Wie so was grundsätzlich funktioniert hast Du ja bereits an einem Skript getestet, mit einem Ereignis das auslöst sobald der Taster gedrückt wurde wird dann ein Skript aufrufen das wiederum bestimmte Dinge ausführt.

Ich würde mal ein grobes Skript auf Grundlage des Skripts oben zusammen kopieren mit den Funktionen die Du brauchst.
Dann kannst Du das ja ausprobieren bzw. hier posten dann kann man Dir bei Bedarf noch einen Hinweis geben wo etwas angepasst werden muss. Am ehesten versteht und lernt man solche Dinge, wenn man diese selber ausprobiert, wobei man Dir, wenn es hängt, gerne Tipps geben und helfen kann.

Ich hab mich mal dran getraut, die toggle Funktion klappt schonmal…

<?

IPS_LogMessage("Sonos Play/Pause", "Event ".$_IPS['EVENT'].", ID ".$_IPS['VARIABLE'] ); // Gibt eine Meldung im Meldungsfenster aus
$status = GetValue(IPS_GetObjectIDByIdent("Status",21503 /*[Sonos_Badezimmer\Status]*/ )); // Auslesen der Variable Volume 
// Abfragen der auslösenden Variable über Objekt ID
if($_IPS['VARIABLE'] == 21533) // Auslöser ist Variable mit der ObjektID 12345
{
 if($status == 3) 
 { 
    SNS_Play(21503 /*[Sonos_Badezimmer\Status]*/,1);   
 }  
}
if($_IPS['VARIABLE'] == 21533) // Auslöser ist Variable mit der ObjektID 23456
{
if($status != 1) 
 { 
    SNS_Play(21503 /*[Sonos_Badezimmer\Status]*/,3);    
 }  
}  



?>

Jedoch erhalte ich im Log Fehler trotz korrekter Funktion:

20.05.2018 19:22:25 | ScriptEngine | Ergebnis für Ereignis 28552
<br />
<b>Warning</b>: Objekt mit Ident Status wurde nicht gefunden in <b>C:\IP-Symcon\scripts\10048.ips.php</b> on line <b>4</b><br />
<br />
<b>Warning</b>: Variable #0 existiert nicht in <b>C:\IP-Symcon\scripts\10048.ips.php</b> on line <b>4</b><br />
<br />
<b>Warning</b>: Instanz #21503 existiert nicht in <b>C:\IP-Symcon\scripts__generated.inc.php</b> on line <b>119</b><br />
<br />
<b>Fatal error</b>: Uncaught exception ‚Exception‘ with message ‚Instance does not implement this function‘ in C:\IP-Symcon\scripts__generated.inc.php:124
Stack trace:
#0 C:\IP-Symcon\scripts\10048.ips.php(17): SNS_Play(21503, 3)
#1 {main}
thrown in <b>C:\IP-Symcon\scripts__generated.inc.php</b> on line <b>124</b><br />

Das Objekt Status kennt ja insgesamt 6 Möglichkeiten

0 - Prev
1 - Play
2 - Pause
3 - Stop
4 - Next
5 - Transition

muss ich hier noch etwas beachten beim ausgeben des Variablen inhaltes?
Könnte hier der Fehler im Log herkommen?

Gruß,

Mir fällt gerade noch auf das mir jetzt immer die aktuelle Position etc. im Log ausgegeben wird:

20.05.2018 19:30:52*| VariableManager*| [Sonos_Badezimmer\Position] = 0:00:23
20.05.2018 19:30:52*| VariableManager*| [Sonos_Badezimmer\Position] = 0:00:23
20.05.2018 19:30:57*| VariableManager*| [Sonos_Badezimmer\Position] = 0:00:28
20.05.2018 19:31:02*| VariableManager*| [Sonos_Badezimmer\ContentStream] = SWR3 CLUB - POP AND GO
20.05.2018 19:31:02*| VariableManager*| [Sonos_Badezimmer\Position] = 0:00:03
20.05.2018 19:31:02*| VariableManager*| [Sonos_Badezimmer\Details] = <table width=„100%“>
<tr>
<td>
<div style=„text-align: right;“>
<div><b>SWR3 CLUB - POP AND GO</b></div>
<div> </div>
<div>SWR3</div>
</div>
</td><td width=„170px“ valign=„top“>
<div style=„width: 170px; height: 170px; perspective: 170px; right: 0px; margin-bottom: 10px;“>
<img src=„http://cdn-radiotime-logos.tunein.com/s24896q.png“ style=„max-width: 170px; max-height: 170px; -webkit-box-reflect: below 0 -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.88, transparent), to(rgba(255, 255, 255, 0.5))); transform: rotateY(-10deg) translateZ(-35px);“>
</div>
</td></tr>
</table>

Das bläst ja das Logfile unnötig auf oder?

Jede Variablenänderung landet im Logfile.
Michael

Ok,
Das heißt die Einträge kommen dann nicht von meinem Skript…
Aber woher kommt die Fehlermeldung ? Die wird mir um Log auch Rot hervorgehoben.

Die Methode IPS_GetObjectIDByIdent holt die ObjektID eines Objekts, in dem Fall der Variable Status, um diese zurückzugeben. Dabei wird nach der Ident gesucht, diese kann eingesehen werden, wenn das Objekt mit CTRL+Enter geöffnet wird, dort kann man die Ident ablesen. Dabei wird unter der übergeordneten Instanz, das ist in dem Fall die Sonos Instanz, geschaut ob eine Variable mit der Ident „Status“ vorhanden ist.


$status = GetValue(IPS_GetObjectIDByIdent("Status",21503 /*[Sonos_Badezimmer\Status]*/ ));

Der Fehler liegt also in dem Fall darin, dass im zweiten Teil die Variable selber ausgewählt worden ist, hier müstest Du einfach die Sonos Instanz selber angeben, dann wird die Variable mit Status innerhalb der Instanz gefunden.

Alternativ kannst Du natürlich auch den Wert direkt auslesen.

Also entweder


$status = GetValue(IPS_GetObjectIDByIdent("Status",12345 /*[Sonos_Badezimmer]*/ )); // Objekt ID der Sonos Badezimmer Instanz angeben

oder


$status =  GetValue(21503 /*[Sonos_Badezimmer\Status]*/ );

Guten Tag zusammen,

Ich bin absolut hell auf begeistert, ich habe zuvor auch schon ioBroker versucht und bin an dieser Aufgabe komplett verzweifelt mit JavaScript…

Ich habe die Funktion nun wie beschrieben umgesetzt bekommen, ohne Fehlermeldungen im Log :smiley:

Hier mal der Code:

<?

IPS_LogMessage("Sonos Play/Pause", "Event ".$_IPS['EVENT'].", ID ".$_IPS['VARIABLE'] ); // Gibt eine Meldung im Meldungsfenster aus

//Definition bzw. hohlen diverser Variablen

//Play Status
$statusBadezimmer = GetValue(IPS_GetObjectIDByIdent("Status",19980 /*[Sonos_Badezimmer]*/));
$statusEsszimmer = GetValue(IPS_GetObjectIDByIdent("Status",10049 /*[Sonos_Esszimmer]*/));

//Gruppenmember
$ingroupBadezimmer = GetValue(16352 /*[Sonos_Badezimmer\MemberOfGroup]*/);
$ingroupEsszimmer = GetValue(16369 /*[Sonos_Esszimmer\MemberOfGroup]*/);


if($_IPS['VARIABLE'] == 21533 /*[Taste 8 Badezimmer\PRESS_SHORT]*/) 
{
 if($statusEsszimmer == 1 && $statusBadezimmer == 3) 
 { 
    SNS_SetGroup(19980 /*[Sonos_Badezimmer]*/,10049 /*[Sonos_Esszimmer]*/);
    SNS_Play(19980 /*[Sonos_Badezimmer]*/);  
 }  
}


if($_IPS['VARIABLE'] == 21533 /*[Taste 8 Badezimmer\PRESS_SHORT]*/)
{
if($statusBadezimmer == 1 && $ingroupBadezimmer == true) 
 { 
    SNS_SetGroup(19980 /*[Sonos_Badezimmer]*/,0);
    SNS_Stop(19980 /*[Sonos_Badezimmer]*/);
 }  
 if($statusBadezimmer == 1 && $ingroupBadezimmer == false) 
 { 
    SNS_Stop(19980 /*[Sonos_Badezimmer]*/);
 }  
}  



?>

Gibt es hier eventuell Verbesserungsmöglichkeiten?

Jetzt wirds ja dann komplizierter… nun bringe ich einen dritten Player ins Spiel jetzt muss ich ja zwischen 2 suchen welcher gerade läuft und genau diesen auswählen um meinen neuen hinzuzufügen.
Würde man dies ebenfalls nach diesem Schema wieder mit diversen „if bedingungen“ Aufbauen oder gibt es hier eine andere Taktik ?

Vielen dank schonmal für eure sehr Hilfreichen Beiträge.

Liebe Grüße,
Adrian

Ein kleiner Fehler meinerseits…

Ich hatte die andere Software noch am Laufen nun Funktioniert das doch nicht mehr ganz so wie gewünscht :frowning:

Mach da wohl doch irgendetwas falsch.

Spielt bei beiden Lautsprechern Musik ohne das sie in einer Gruppe sind und ich auf die Taste drücke wird der Player im Badezimmer zum Esszimmer hinzugefügt, eigentlich sollte dieser erst einmal ausgeschalten werden und beim erneuten wieder einschalten dann zur Gruppe Esszimmer hinzugefügt werden.

Das Ausschalten bzw. entfernen aus der Gruppe funktioniert so leider garnicht…

Vielleicht schilderst du nochmal Stichpunkt artig wann genau was bei welchem Tastendruck passieren soll und ob es sich um einen normalen Taster oder einen 6fach Taster handelt. Dann kann man Dir auch eher bei dem logischen Aufbau Tipps geben. Momentan bist Du wohl der einzige der weis was genau wann passieren soll.

Also wie viele Player sind es insgesamt? Wann soll welches Szenario greifen, wieviele verschiedene Gruppen Konstellationen gibt es usw.?

Das sollte an sich auch kein Problem sein um Dir da zu helfen musst Du nur eine Klare Vorstellung davon haben wann was passieren soll und was es für Ausnahmen gibt. Entsprechend Deinen Annahmen kann man dann so ein Skript zusammen bauen. Dies wird dann halt sehr individuell, aber wenn es steht bist Du froh wenn es funktioniert.
In dem von Dir geschilderten Fall müsstest Du also erst mal, bevor das Skript etwas macht, prüfen in welchem Zustand die Geräte eigentlich sind und davon abhängig dann erst etwas ausführen. Das was Du Dir im Prinzip im Kopf ausdenkst, wenn ich das mache soll dies passieren, ist nichts anderes als eine weitere If Abfrage.

In Deinem Beispiel müsstest Du also erst mal prüfen ob denn beide Geräte in einer Gruppe sind. Wenn das nicht der Fall ist sendest Du nur einen Stop Befehl an das Gerät im Bad.


if($statusBadezimmer == 1 && $ingroupBadezimmer == true) 

Kann nicht stimmen, die Variable die Du abfragst MemberOfGroup enthält 0 für keine Gruppe und ansonsten einen numerischen Wert für ein Sonos Gerät. Die Variable ist also vom Typ Integer und nicht Boolean (true/false).

Daher müsste die Bedingung eher so aussehen


if($statusBadezimmer == 1 && $ingroupBadezimmer > 0) 

Wenn das Gerät also auf Play ist (1) und Teil einer Gruppe, der Wert der Gruppe muss dann eben nicht 0 sein, dann soll sich das Gerät nur ausschalten.