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.
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.
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.
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 ?
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
Danke für den Hinweis, jetzt funktioniert es natürlich
Ich bin begeistert, auch der Eintrag im Log ist so super um es nachzuvollziehen perfekt!
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 ?
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.
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?
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.
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
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.
Ich hatte die andere Software noch am Laufen nun Funktioniert das doch nicht mehr ganz so wie gewünscht
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.
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).