da ich recht viele Hue-Lampen habe und die Lampen nicht immer nur über die CCU gesteuert werden, brauchte ich eine zuverlässige Art den Status der Lampen abzufragen.
Es hat sich gezeigt, dass die vorhandenen Wege bei vielen Lampen nicht praktikabel sind und die CCU recht stark belasten wenn man den Status Zeitnah abfragen möchte.
Da sowohl CCU als auch die Hue-Bridge recht träge sind, kann sich die Laufzeit eines Scripts schnell zu einigen Sekunden summieren und im dümmsten Fall „überholen“ sich die aufrufen.
Außerdem ist es nicht besonders elegant für jede Lampe einen Aufruf zu starten, wenn man den Status aller Lampen über eine einzelne Abfrage setzen kann.

Ergebnis ist das Folgende Script (gekürzt auf 5 Lampen). Ich verwende hierbei keines der vorhandenen Scripte, sondern rufe direkt per CURL das komplette Status-JSON der HUE-Lampen ab.
Leider bietet die CCU keinen JSON-Parser o.ä. und man muss die Datenpunkte per rudimentäre String-Operationen aus dem JSON extrahieren.
Die CCU verhält sich hierbei zeitweise recht eigenartig. Verschachteln der einzelnen Operationen mag sie beispielsweise nicht.
Bislang lese ich nur den Dimmwert der Lampen und den ON/OFF Status aus, weil ich meine Lampen in einem einzelnen CUxD-Gerät mit jeweils einem Kanal pro Lampe angelegt habe.
Sobald ich Zeit habe, werde ich die Lampen in separate CuxD-Geräte auftrennen und Farbe und Sättig mit auswerten.
Code: Alles auswählen
!XXXXXXXXXXXXXXXXXXXX!
! HUE Status abrufen !
!XXXXXXXXXXXXXXXXXXXX!
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("LD_LIBRARY_PATH=/usr/local/addons/cuxd /usr/local/addons/cuxd/curl -f http://172.31.22.151/api/newdeveloper/lights");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
var v = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
string seperator = ':{\"state\": {';
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
! Separieren der einzelnen JSON pro Light !
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
string Light01 = v.StrValueByIndex(seperator, 01);
string Light02 = v.StrValueByIndex(seperator, 02);
string Light03 = v.StrValueByIndex(seperator, 03);
string Light04 = v.StrValueByIndex(seperator, 04);
string Light05 = v.StrValueByIndex(seperator, 05);
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
! Dimmlevel der Lampen Bestimmen !
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
string BriHelp01 = Light01.StrValueByIndex(",",1); integer Bri01 = BriHelp01.Substr(6, 3); Bri01 = 0 - Bri01.ToInteger();
string BriHelp02 = Light02.StrValueByIndex(",",1); integer Bri02 = BriHelp02.Substr(6, 3); Bri02 = 0 - Bri02.ToInteger();
string BriHelp03 = Light03.StrValueByIndex(",",1); integer Bri03 = BriHelp03.Substr(6, 3); Bri03 = 0 - Bri03.ToInteger();
string BriHelp04 = Light04.StrValueByIndex(",",1); integer Bri04 = BriHelp04.Substr(6, 3); Bri04 = 0 - Bri04.ToInteger();
string BriHelp05 = Light05.StrValueByIndex(",",1); integer Bri05 = BriHelp05.Substr(6, 3); Bri05 = 0 - Bri05.ToInteger();
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
! Status der Lampe (bei false wird der Bri-Wert auf 0 gesetzt) !
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
string StateHelp01 = Light01.StrValueByIndex(",", 0); if (StateHelp01.Substr(16, 5) == false) {Bri01 = -0;}
string StateHelp02 = Light02.StrValueByIndex(",", 0); if (StateHelp02.Substr(16, 5) == false) {Bri02 = -0;}
string StateHelp03 = Light03.StrValueByIndex(",", 0); if (StateHelp03.Substr(16, 5) == false) {Bri03 = -0;}
string StateHelp04 = Light04.StrValueByIndex(",", 0); if (StateHelp04.Substr(16, 5) == false) {Bri04 = -0;}
string StateHelp05 = Light05.StrValueByIndex(",", 0); if (StateHelp05.Substr(16, 5) == false) {Bri05 = -0;}
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
! Übernehmen der Werte ins HM Frontend !
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
dom.GetObject("CUxD.CUX2801002:1.SET_STATE").State(Bri01); dom.GetObject("CUxD.CUX2801002:1.LEVEL").State();
dom.GetObject("CUxD.CUX2801002:2.SET_STATE").State(Bri02); dom.GetObject("CUxD.CUX2801002:2.LEVEL").State();
dom.GetObject("CUxD.CUX2801002:3.SET_STATE").State(Bri03); dom.GetObject("CUxD.CUX2801002:3.LEVEL").State();
dom.GetObject("CUxD.CUX2801002:4.SET_STATE").State(Bri04); dom.GetObject("CUxD.CUX2801002:4.LEVEL").State();
dom.GetObject("CUxD.CUX2801002:5.SET_STATE").State(Bri05); dom.GetObject("CUxD.CUX2801002:5.LEVEL").State();
Zu den einzelnen Schritten:
Code: Alles auswählen
!XXXXXXXXXXXXXXXXXXXX!
! HUE Status abrufen !
!XXXXXXXXXXXXXXXXXXXX!
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("LD_LIBRARY_PATH=/usr/local/addons/cuxd /usr/local/addons/cuxd/curl -f http://172.31.22.151/api/newdeveloper/lights");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
var v = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
string seperator = ':{\"state\": {';
{"1":{"state": {"on":false,"bri":254,"hue":25653,"sat":254,"effect":"none","xy":[0.4084,0.5168],"ct":290,"alert":"none","colormode":"xy","reachable":true}, "type": "Extended color light", "name": "Schlafzimmer", "modelid": "LCT001", "manufacturername": "Philips","uniqueid":"XX:XX:XX:XX:XX:XX:XX:XX-XX", "swversion": "66013452", "pointsymbol": { "1":"none", "2":"none", "3":"none", "4":"none", "5":"none", "6":"none", "7":"none", "8":"none" }},"2":{"state": {"on":true,"bri":40,"hue":5769,"sat":230,"effect":"none","xy":[0.6233,0.3565],"alert":"none","colormode":"hs","reachable":true}, "type": "Color light", "name": "Treppe OG", "modelid": "LST001", "manufacturername": "Philips","uniqueid":"XX:XX:XX:XX:XX:XX:XX:XX-XX", "swversion": "66013452", "pointsymbol": { "1":"none", "2":"none", "3":"none", "4":"none", "5":"none", "6":"none", "7":"none", "8":"none" }},"3":{"state": {"on":true,"bri":254,"alert":"none","reachable":true}, "type": "Dimmable light", "name": "White Diele V", "modelid": "LWB003", "manufacturername": "Philips","uniqueid":"XX:XX:XX:XX:XX:XX:XX:XX-XX", "swversion": "3.0.0.7119", "pointsymbol": { "1":"none", "2":"none", "3":"none", "4":"none", "5":"none", "6":"none", "7":"none", "8":"none" }}
Das JSON beginnt für jede Lampe mit der entsprechenden Nummer (1-n) und dem String :{"state": {. Man kann also die einzelnen Lampen anhand des state-Strings separieren. Da im Separator Anführungszeichen sind, musste ich ihn in eine Variable zwischenspeichern.
Code: Alles auswählen
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
! Separieren der einzelnen XML pro Light !
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
string Light01 = v.StrValueByIndex(seperator, 01);
{"state": {"on":false,"bri":254,"hue":25653,"sat":254,"effect":"none","xy":[0.4084,0.5168],"ct":290,"alert":"none","colormode":"xy","reachable":true}, "type": "Extended color light", "name": "Schlafzimmer", "modelid": "LCT001", "manufacturername": "Philips","uniqueid":"00:17:88:01:00:b3:3c:3c-0b", "swversion": "66013452", "pointsymbol": { "1":"none", "2":"none", "3":"none", "4":"none", "5":"none", "6":"none", "7":"none", "8":"none" }},"2"
Code: Alles auswählen
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
! Dimmlevel der Lampen Bestimmen !
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
string BriHelp01 = Light01.StrValueByIndex(",",1); integer Bri01 = BriHelp01.Substr(6, 3); Bri01 = 0 - Bri01.ToInteger();
Substr liefert dann den reinen Zahlenwert (aber als String) durch abschneiden der ersten 6 Zeichen ("bri":). Der SET_STATE Befehl von CUxD erwartet einen negativen Integer Wert und errechnet daraus eigenständig den Prozentualen Wert innerhalb des Wertebereichs. Aus diesem Grund ziehen wir den Wert von 0 ab (nicht schön, aber der einige Weg den ich mittel trial and error gefunden habe)."bri":254
Code: Alles auswählen
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
! Status der Lampe (bei false wird der Bri-Wert auf 0 gesetzt) !
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
string StateHelp01 = Light01.StrValueByIndex(",", 0); if (StateHelp01.Substr(16, 5) == false) {Bri01 = -0;}
OFF-Topic: Aus diesem Grund schaltet sich die Hue-Lampe auch nicht aus, wenn der Dimmwert in der CCU auf 0 gesetzt wird. Mit einer einfachen IF-Abfrage in den bekannten TCL-Scripten kann man das aber beheben.
Code: Alles auswählen
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
! Übernehmen der Werte ins HM Frontend !
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
dom.GetObject("CUxD.CUX2801002:1.SET_STATE").State(Bri01); dom.GetObject("CUxD.CUX2801002:1.LEVEL").State();
Natürlich kann man auch die anderen Werte auslesen. Hier z.B. den Hue (Farb-)Wert:
Code: Alles auswählen
string HueHelp08 = Light08.StrValueByIndex(",",2); integer Hue08 = HueHelp08.Substr(6, 6); Hue08 = Hue08.ToInteger();