Nanoleaf Aurora mit IPS steuern

Aktuelle Version des Skripts zur Steuerung einer Nanoleaf Aurora:

<?
$host="ip-adresse hier rein";
$token="---------";
$url="http://$host:16021/api/v1/$token/";
if (!Sys_Ping($host, 2)){
	die("$host nicht erreichbar");
}

switch ($_IPS['SENDER']){
case "RunScript":
    if(isset($_IPS['Action']))
    {
       switch($_IPS['Action'])
        {
           case "On":
		    $ch = curl_init($url."state/on");
		    $options = array(
		                   CURLOPT_RETURNTRANSFER => true,
		                   CURLOPT_CUSTOMREQUEST => 'PUT', 
		                   CURLOPT_HTTPHEADER => array('Content-type: application/json') ,
		                   CURLOPT_POSTFIELDS => '{"on":true}'
		                   );
		    curl_setopt_array($ch, $options);
		    $login = curl_exec($ch);
		    curl_close($ch);
		   break;
           case "Off":
    		$ch = curl_init($url."state/on");
		    $options = array(
		                   CURLOPT_RETURNTRANSFER => true,
		                   CURLOPT_CUSTOMREQUEST => 'PUT', 
		                   CURLOPT_HTTPHEADER => array('Content-type: application/json') ,
		                   CURLOPT_POSTFIELDS => '{"on":false}'
		                   );
		    curl_setopt_array($ch, $options);
		    $login = curl_exec($ch);
		    curl_close($ch);
		   break;
           case "Toggle":
    		$ch = curl_init($url."state/on");
		    $options = array(
		                   CURLOPT_RETURNTRANSFER => true,
		                   CURLOPT_CUSTOMREQUEST => 'PUT', 
		                   CURLOPT_HTTPHEADER => array('Content-type: application/json') ,
		                   CURLOPT_POSTFIELDS => '{"on":'.(GetValueBoolean(IPS_GetObjectIDByName("On", $_IPS["SELF"]))?"false":"true").'}'
		                   );
		    curl_setopt_array($ch, $options);
		    $login = curl_exec($ch);
		    curl_close($ch);
		   break;
           case "Brightness":
		    if(isset($_IPS['Value'])){
	    		$ch = curl_init($url."state");
			    $options = array(
			                   CURLOPT_RETURNTRANSFER => true,
			                   CURLOPT_CUSTOMREQUEST => 'PUT', 
			                   CURLOPT_HTTPHEADER => array('Content-type: application/json') ,
			                   CURLOPT_POSTFIELDS => '{"brightness":'.((int)$_IPS['Value']).'}'
			                   );
			    curl_setopt_array($ch, $options);
			    $login = curl_exec($ch);
			    curl_close($ch);
			}
		   break;
           case "Effect":
		    if(isset($_IPS['Effect'])){
	    		$ch = curl_init($url."effects");
			    $options = array(
			                   CURLOPT_RETURNTRANSFER => true,
			                   CURLOPT_CUSTOMREQUEST => 'PUT', 
			                   CURLOPT_HTTPHEADER => array('Content-type: application/json') ,
			                   CURLOPT_POSTFIELDS => '{"select":"'.$_IPS['Effect'].'"}'
			                   );
			    curl_setopt_array($ch, $options);
			    $login = curl_exec($ch);
			    curl_close($ch);
			}
		   break;
           case "Random":
			$ch = curl_init($url."effects");
			$result = json_decode(Sys_GetURLContent($url."effects/effectsList"),true);
		    $options = array(
		                   CURLOPT_RETURNTRANSFER => true,
		                   CURLOPT_CUSTOMREQUEST => 'PUT', 
		                   CURLOPT_HTTPHEADER => array('Content-type: application/json') ,
		                   CURLOPT_POSTFIELDS => '{"select":"'.$result[array_rand($result)].'"}'
		                   );
		    curl_setopt_array($ch, $options);
		    $login = curl_exec($ch);
		    curl_close($ch);
		   break;
		}
	}   
	break;
case "Execute":
	IPS_SetScriptTimer($_IPS['SELF'], 10);
	$result = json_decode(Sys_GetURLContent($url."effects/effectsList"),true);
	print_r($result);
	break;
case "TimerEvent":
	$result = json_decode(Sys_GetURLContent($url."state"),true);
	CreateOrSetVar("On",(boolean)($result['on']['value']==1),0,$_IPS['SELF']);
	CreateOrSetVar("Brightness",(int)($result['brightness']['value']),1,$_IPS['SELF']);
	CreateOrSetVar("hue",(int)($result['hue']['value']),1,$_IPS['SELF']);
	CreateOrSetVar("sat",(int)($result['sat']['value']),1,$_IPS['SELF']);
	CreateOrSetVar("ct",(int)($result['ct']['value']),1,$_IPS['SELF']);
	CreateOrSetVar("colorMode",(string)($result['colorMode']),3,$_IPS['SELF']);
	break;
	}

function CreateOrSetVar($VarName,$VarValue,$VarType,$RefID){
	if ($subitem=@IPS_GetObjectIDByName($VarName,$RefID)){
	   setvalue($subitem,$VarValue);
	}
	else{
	   $subitem=IPS_CreateVariable($VarType);
	   IPS_SetName($subitem, $VarName);
	   IPS_SetParent($subitem, $RefID);
	   setvalue($subitem,$VarValue);
	}
return $subitem;
}
?>

Zur „Installation“ das Skript irgendwo ablegen und einmal per Hand ausführen. Danach sollten sich die vars darunter anlegen. Einige Beispiele:

Ein: „IPS_RunScriptEx(<id des scripts>, Array(„Action“=>„On“));“
Helligkeit: IPS_RunScriptEx(18037 /[Nanoleaf Aurora]/, Array(„Action“=>„Brightness“,„Value“=>„20“);

Andere Kommandos siehe Quelltext !

Mir sind bisher nur 2 Anwender bekannt, daher alles etwas rudimentär ohne Modul oder Kommentare. Bei Fragen schickt mir am besten eine PM oder email…

Hallo TomW
Vielen Dank für Dein Skript. Ein / Aus funktioniert bei mir wunderbar :slight_smile: .

Jedoch habe ich ein „Hänger“ mit den Rest. Kannst Du mir ein Beispiel geben wie ich die Brightness oder colorMode ansteuern kann?:confused:

Vielen Dank, Gruss saschild

Ja, in der Version ging das nicht. ich stelle morgen ein aktualisiertes Script hier rein.

und habe 2 größere Installationen. Wie machst du das denn so im WebFront oder ist das für dich nicht so ein Thema?

Mich nervt z.Z., dass ich immer zwischen IPS und Nanoleaf-App hin und her wechseln muss. Jetzt habe ich mit Hilfe deines Scripts zwar Scripte für simples An/Aus, was ja schon super ist. Aber komfortabler wäre ja, wenn man Gruppen und Farbe direkt im WebFront auswählen könnte. Muss man für sowas ein IPS-Modul schreiben? (wie z.B. für Phillips Hue, da kann man alles im WebFront einstellen)

Nein es muss lediglich das Skript angepasst werden. Ein Modul würde lediglich ein Konfigurationsformular anbieten aber an Funktionen macht es das gleiche wie ein entsprechendes Skript. Wenn ihr wollt könnt ihr da aber natürlich auch ein Modul basteln. Der erste Schritt dahin wäre das Skript so anzupassen das es Funktionen umfasst und dann daraus eine Klasse zu bauen. Wenn ihr dazu Fragen habt dann fragt das sollte aber an sich schnell erledigt sein ist ja nicht viel Code.

Ich habe seit dem Wochenende auch ein Nanoleaf und habe mich mal hingesetzt und ein PHP Modul als Basis zur Steurerung geschrieben.

Zu finden hier. Du kannst ja mal Rückmeldung geben ob das bei Dir auch funktioniert bzw. ob was fehlt. Ich habe mich noch nicht sehr intensiv damit auseinander gesetzt was das Ding alles kann daher erst mal die grundlegenden Funktionen.

Weis jemand von Euch ob es möglich ist auch einzelne Dreiecke anzusteuern bzw. wie das funktioniert?

Habe gleich Auroras in verschiedenen Räumen, daher war das etwas steinig mit der ersten Einrichtung. Habe nicht sofort kapiert, dass es vom Konzept her eine IO-Instanz und dazu auch noch einen separaten Splitter gibt. Bei 2 Auroras hießen die Instanzen blöderweise auch noch sofort gleich und dann geht das alles schnell hin und her über Kreuz … :smiley:
Dann stand im zweiten Splitter auch noch behaarlich die IP vom ersten Aurora-Modul drinn, was mir nicht aufgefallen ist, weil ich im IO-Modul natürlich DNS-Namen verwende und die IP erstmal garnicht als falsch erkannt habe. Dann kann man lange versuchen, Token anzufordern. :frowning:
Ist es überhaupt nötig, dass die IP sowohl im IO-Modul, wie auch im Splitter drinstehen muss bzw. könnte der Splitter nicht die IP vom IO-Modul mitnutzen?
Egal. Nach etwas hin und her läuft es jetzt aber super!!!

Also erstmal Hut ab für deine Super Lösung! Danke!

In der Api-Doku kann man nachsehen, wie man theoretisch einzelne Panels steuern kann. Ist aber auf den ersten Blick nicht ganz so einfach, weil man es natürlich mit Koordinaten zu tun bekommt, weil man die Panels ja wilkührlich an die Wand kleben kann. Da kann man aber auch die Nanoleaf-App nehmen für die Erstellung solcher Muster. Die kann man dann als neues Muster unter eigenem Namen abspeichern. Es ist einfacher, dieses Muster abzurufen als die Fummelei auf API-Ebene, finde ich. Dazu dürfte man aber nicht nur die Default-Muster im WebFront auswählen dürfen, sondern auch die selbst gespeicherten oder per Download nachgerüsteten Muster, die man bestimmt über die API erfragen und in der GUI zur Auswahl auflisten kann.

Wenn du noch kein Rythm-Modul für die Aurora hast -> unbedingt anschaffen. Zur Musik ist das Teil gleich noch viel cooler, finde ich. Die Moves haben die ganz gut umgesetzt.

Schön wäre natürlich ,wenn man die Rythm-Muster ebenfalls auswählen und so in den „Sound“-Modus mit Rythm-Modul wechseln könnte … :wink:

Ich finde turnusmäßig folgenden Fehler im Logfile:

29.10.2017 22:43:12*| FlowHandler*| Kann Daten nicht zur Instanz #22912 weiterleiten: <br />
<b>Warning</b>: Property Port is not of type String in <b>C:\Program Files\IP-Symcon\modules\IPSymconNanoleaf\Nanoleaf Splitter\module.php</b> on line <b>140</b><br />

Kann es vielleicht sein, dass der Call-Back-Port im IO-Modul fest auf 1900 eingestellt ist und ich bei zwei Aurora-Instanzen mit gleichem Port deshalb Probleme bekomme?

Da bist Du ehrlich gesagt Ersttester, da ich zur Zeit nur ein Nanoleaf Aurora besitze. Mal sehen vielleicht werden es ja irgendwann mehr, meine Tochter fand das Ding so toll das sie am besten auch eins haben will. Der IO ist ein Multicast Socket und dient eigentlich nur dazu regelmäßig die Mitteilungen des Nanoleaf Aurora mitzubekommen, falls sich z.B. die IP ändert oder der Port bekommt das dann IP-Symcon mitgeteilt und wird automatisch angepasst. Ich muss mal schauen ob das für viele Nanoleaf Aurora schlüssig ist, so weit habe ich fürs erste ehrlich noch gar nicht alles durchdacht. Daher sind Deine Erfahrungen und Beobachtungen wertvoll. Der Splitter ist die eigentliche Kommunikationsinstanz mit dem Nanoleaf Aurora, der IO dient wie gesagt nur dazu mitzubekommen wenn sich die IP oder Port ändern sollte bzw. zum Erstmaligen übermitteln der Konfigurationseinstellungen durch den Nanoleaf Aurora.

Ja das werde ich noch sicher ergänzen, habe das Ding aber erst 2 Tage muss mir das mal selber näher anschauen was damit alles geht. Auslesen kann man das auf alle Fälle ich muss dann nur das Variablenprofil dynamisch anpassen das muss ich mal schauen wie ich das am besten hinbekomme und bei 32 wäre dann Schluss dann müste eine neue Variable angelegt werden. Vielleicht macht da dann aber auch eine HTMLBox mit einem Auswahlmenü mehr Sinn.

Habe ich zur Zeit noch nicht werde ich aber wohl noch ergänzen. Da muss ich aber mal schauen was die API dazu zur Zeit hergibt.

Das schaue ich mir morgen Abend mal näher an da muss sich wohl ein Fehler eingeschlichen haben. Mit dem Port hat das nichts zu tun der 1900 ist fest das ist einfach der SSDP Port des Multicast Sockets und der ist fest und für alle Geräte gleich. Entscheidend ist der Port der im Splitter steht das ist der Port des jeweiligen Geräts der zur Kommunikation genutzt wird.

Nun, auf Aurora-Seite kann natürlich der gleiche Port genutzt werden. Mich irritiert, dass ich nun 2 IO-Instanzen habe, in denen die „eigene“ Rechner-IP für den Callback drinsteht und jeweils der gleiche „Empf-Port“ 1900. Da ja jeder IO einen eigenen Socket öffnet, können doch eigentlich nicht beide auf 1900 lauschen, oder? (Ich habe z.B. auch 3 CCUs und musste den Callback-Port auf dem IPS-Rechner für alle drei eindeutig anpassen)
Wenn doch, woher weiß er dann, in welche IO-Instanz die Variablen-Instanzen aktualisiert werden sollen? Wenn der gleiche Port tatsächlich richtig wäre, dann müsste ja ein IO-Modul für 2 Splitter reichen, allerdings werden diese automatisch angelegt und verknüpft.

Wenn ich ehrlich bin, leuchtet mir das Konzept noch nicht ganz ein. Wieso muss IPS überwachen, ob sich die IP oder der Port von den Aurora-Modulen ändert?
IPS-Nutzern mit ein wenig technischem Background dürfte klar sein, dass ich Geräten, mit denen ich dauerhaft kommunizieren möchte, eine feste IP oder zumindest per DHCP die jeweils gleiche IP verpassen sollte. Da könnte man schon vom Nutzer beim Setup einmalig erwarten, diese dann auch in das IP-Feld einzutragen.
Sorry für die blöden Fragen. Ich verstehe nur gerne, was da so passiert.

Übrigens nochmal meinen Respekt:
Ich bin auch viel am basteln und programmieren, aber 2 Tage nach dem Auroa-Kauf gleich ein ganzes Modul zu schreiben und dafür anzubieten ist ziemlich krass!
Ich hab natürlich auch sofort die API angeschaut und zumindest mal ein simples On-/off gescriptet für die einzelnen Raum-Szenarien aber richtig tief einsteigen bei den Geräten tue ich normalerweise erst etwas später … man hat ja auch so immer noch 1000 andere Baustellen … :smiley:

(Außer bei meiner schönen neuen HUE Beyond: da hab ich in der API einen Farbwechsel-Modus entdeckt, der in der App für diese Leuchte nicht eingeschaltet werden kann - da konnte ich nicht wiederstehen und habe sofort lostebastelt … :D)

Doch das geht da es ein Multicast Socket ist da können mehrere den gleichen Port nutzten. Auf Port 1900 melden sich alle Geräte die meinen Ihren Status per SSDP ins Netzwerk melden zu müssen. Daher kommt auch auf jedem Multicast Socket das gleiche an von allen Geräten und muss dann gefiltert werden. Aber Du hast recht ich werde das zumindest versuchen so zu ändern das alle Nanoleaf nur einen einzigen IO nutzten.

Ja ich werde das versuchen so abändern das es durchaus mehrere Splitter gibt aber nur einen IO das ist vielleicht nicht so irritierend. Der IO dient nur dazu das Nanoleaf seine Kontaktdaten mittteilt. Die Kommunikation erfolgt nicht über den IO sondern über den Spliter der in regelmäßigen Intervallen die Daten mit den vom Nanoleaf übermittelten Daten abfragt.

Dies wird so empfohlen weil dies vorkommen kann. Du hast aber recht ein versierter Nutzer sollte per DHCP eine feste IP zuweisen dann sollte das grundsätzlich kein Problem sein.

Das sieht im Prinzip so aus

Multicastsocket (SSDP) —————
…|
Nanoleaf ——————————Splitter——Gerät

Der Splitter kommuniziert direkt mit dem Nanoleaf und schickt Befehle bzw. Sendet einen Request um Daten zu erhalten. Der SSDP dient nur dazu das Nanoleaf per Broadcast mittteilt das es im Netzwerk anwesend ist und wie die Lampe zu erreichen ist.

Dann schauen wir mal muss auch erst mal damit spielen das kann man bestimmt noch erweitern bzw. erst mal die Fehler alle beseitigen.

So kleiner Fehler beseitigt, Bugfix ist online. Den Rest muss ich mir dann mal in Ruhe anschauen was das automatische generieren der Profile und so weiter angeht.

Habe aktualisiert und keine Fehler mehr … :slight_smile:

Kleine Idee für ein Upgrade: Die Poll-Zeiten sollte man vielleicht einstellen können. Ich habe gesehen, du holst die Stati alle 5 Sekunden für alle Variablen. Mir würden 60 oder mehr Sekunden reichen. Warum?

Weil man so oft nun auch wieder nicht ins WebFront schaut, ob Aurora an ist … :wink:

Ich hatte schon öfter Probleme mit so kleinen Devices, wenn man sie dauerhaften Abfragen aussetzt. Ich hatte mal privat ein Zabbix (Nagios-Fork) laufen, dass periodisch alles bei mir zu Hause auf Verfügbarkeit und Reaktion getestet hat. Wenn das Ding lief und alle par Sekunden gepingt und API-Calls auf alle Geräte und VMs durchgeführt hat, sind mir reihenweise Dienste und Geräte ständig weggeschmiert. Sogar die Fritzbox war betroffen. (Periodischer http Aufruf auf Deckseite)
Seither ist mir Monitoring egal, weil das Monitoring ständig für Ausfälle sorgte … :smiley:
Ich weiß halt nicht, wie stabil die Auroras bleiben.

Gut habe ich mal ergänzt, dann kann das jeder nach seinem Belieben einstellen. Ist zu finden in der Nanoleaf Instanz dort kann der Wert im Formular verstellt werden. Ich hatte den initial Wert auf 5 Sekunden gesetzt, weil es ja auch um Automatisierung geht, das beste wäre natürlich Echtzeit, aber das geht ja nicht, da man ja eine Abfrage schicken muss. Mir geht es dabei um Automatisierungsprozesse wenn die Lampe an ist oder z.B. eine bestimmte Szene eingestellt ist oder eine bestimmte Farbe eingestellt ist soll IP-Symcon darauf reagieren können um z.B. weitere vorhandene Beleuchtung im Raum automatisch an die Szene anzupassen. Wenn man grundsätzlich alles über IP-Symcon macht auch Alexa dann bekommt IP-Symcon ja sowieso alles mit. Wenn Du aber z.B. die Farbe in der App anpasst sollte das ja IP-Symcon auch zeitnah mitbekommen um z.B. andere Lampen im Raum auch zeitgleich in der Farbe oder Helligkeit verstellen zu können. So könnte man dann z.B. Hue und Nanoleaf über IP-Symcon synchronisieren in einem Raum. Da kam mir jetzt eine Zeitraum von 60s nicht gut vor um reagieren zu können. Eigentlich wäre ja eher 1 Sekunde ideal, aber ich habe das erst mal auf 5 Sekunden gestellt, weil ich nicht weis wie schnell man den Nanoleaf Aurora mit solchen Sachen abschießen kann. Das wird dann erst die Erfahrung im Alltag zeigen. Kannst ja mal mit dem Intervall rumspielen und Rückmeldung geben was bei Dir noch stabil läuft.

Habe jetzt bei beiden Auroras 60 Sekunden eingestellt und es funktioniert. Danke!
Jetzt werde ich das ganze mal beobachten.

Ich habe die Statusupdates mit 60 Sekunden Takt laufen lassen und am übernächsten Tag waren beide Aurora’s nicht mehr per Software schaltbar.
Kurioserweise wurden Status-Anfragen per API-Get noch weiterhin per JSON zurückgeliefert.
Ich habe es dann mit veränderndenPost-Calls direkt probiert, z.B. die Dinger ein oder auszuschalten und es ging nicht. Nach Reset per Stromleitung ziehen wurden die gleichen Calls aber wieder verarbeitet und auch ein Schalten über IPS war wieder möglich.
Da das vorher noch nie der Fall war, vermute ich, dass es doch am regelmäßige API-Einsatz per Status-Poll liegt, weil beide Module parallel ausgefallen sind. Läuft das denn mit deinen 5 Sekunden-Polls über mehrere Tage stabil? Hast du mal versucht, dann per WebFront ein- oder auszuschalten?

Ich hatte die Panels immer mal wieder wo anders gehabt, weil ich auch noch mit der Farbe getestet hatte. Habe jetzt heute die Panels fest an der Wand montiert und diese sind nun dauerhaft am Strom. Ich werde das mal beobachten ob das bei mir auch auftritt. Ich habe mir jetzt im übrigen nach Deinen Begeisterungsstürmen auch ein Rhythm geholt und muss sagen das ist schon sehr nett, also danke für den Tipp.