Seite 1 von 1

Alle Hue-Lampen gleichzeitig "nativ" per Script auslesen

Verfasst: 01.02.2016, 02:05
von FanTC
Hallo,

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\": {';
Mit diesem simplen Aufruf laden wir das komplette Array der Lampenstatus in die Variable „v“. Das sieht dann so aus:
{"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);
Mittels StrValueByIndex bekommt mein ein Array, in dem die Informationen pro Lampe getrennt abgespeichert sind und wieder in eine Variable gespeichert werden können.
{"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();
Die einzelnen Datenpunkte sind nun mit Komma separiert und lassen sich mittels StrValueByIndex einzeln auslesen.
"bri":254
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).

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;}
Bei HUE-Lampen ist der Dimmwert in der Bri-Variable auch gespeichert, wenn sie ausgeschaltet sind. In der CCU Logik wäre dieser aber 0 und muss deswegen im OFF-Fall auf 0 gesetzt werden.
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();
Der neue aktuelle Dimmwert kann nun mittels SET_STATE gesetzt werden. Ich verwende SET_STATE, weil es nicht gewollt ist das die CCU eine Aktion ausführt (insbesondere wichtig, wenn man nicht die oben erwähnte Änderung des TCL vornimmt). Jedoch wird der neue Wert in der CCU so nicht sichtbar. Mittels anschließendem „leerem“ LEVEL-Befehl, aktualisiert die CCU jedoch den Wert.


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();

Re: Alle Hue-Lampen gleichzeitig "nativ" per Script auslesen

Verfasst: 02.02.2016, 08:55
von Cash
wie oft läßt Du denn das Script laufen?

Meine Idee derzeit wäre ein Ablauf der Lampensteuerung...

Ich habe 6 Lampen. 3 davon sind meine Haupt Tv Beleuchtung. Dafür habe ich von Philips auch einen Hue Schalter zum ein- und ausschalten.

Wenn ich nun Abends nach 22 Uhr die drei Lampen ausschalte wäre es cool wenn die 4 Hue Lampe (Ambiente-Licht in einer Ecke) 5 Minuten später ausgeht.

Die Hue Lampe 5 im Flur soll 10 Minuten später ausgehen. Gleichzeitig mit dem ausschalten der ersten drei Lampen sollte das Ambiente Licht im Schlafzimmer für 15 Minuten angehen... Das wäre mir smart genug. Welche Werte die Lampen haben brauche ich nicht. Ich schalte die Hue auch weiterhin mit der Hue App oder per Sprache.

Dereit lasse ich die Hue Lampen 4 und 5 lediglich per CCU am Tag per Zeitsteuerung ein- bzw ausschalten unter Berücksichtung von Urlaub, Feiertag usw...
Mit der Zeitsteuerung funktioniert auch soweit aber je nach Film wird es Abends mal 10 Minuten früher oder später deshalb wäre halt die Schaltfolge oben ganz nett aber dazu müßte ich CCU ja jede Minute die Hue Lampen 1-3 abfragen. Das einfachste wäre wohl ein Homematic Wandschalter aber der Hue Schalter ist schon echt gut...

Re: Alle Hue-Lampen gleichzeitig "nativ" per Script auslesen

Verfasst: 02.02.2016, 23:07
von FanTC
Das Script läuft für die Lampen alle 5 Sekunden und zusätzlich habe ich das Script noch mal für meine Hue-Gruppen angepasst und das läuft alles 7 Sekunden. Jedoch habe ich inzwischen auf einen Raspberry umgestellt, auf der CCU würde ich eher 15 Sekunden aufwärts nehmen.
Wichtig ist es einen CUxD Timer zu verwenden. Der CCU Timer verträgt derart kurze Intervalle nicht und bring die CCU zum Abstürz!

Dein Szenario verträgt ja eine gewisse Trägheit locker, von daher kannst du das Script gut nutzen.

Die Homematic Taster haben halt den Nachteil, dass man die Hue-Lampen dann nicht dimmen kann… Hierzu habe ich bereits eine Lösung (ohne CCU.IO) gesucht, aber leider bislang ohne Erfolg.

Re: Alle Hue-Lampen gleichzeitig "nativ" per Script auslesen

Verfasst: 03.02.2016, 09:41
von Cash
Dazu dann mal ein paar Fragen. Ich habe versucht den Code mal anzupassen, da ich ja eigentlich nur Abfragen muss ob die Lampe an oder aus ist...

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://xxx.xxx.xxx.xxx/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 XML pro Light !
    !XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
     
    string Light01 = v.StrValueByIndex(seperator, 01);

   !XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
    ! Status der Lampen Bestimmen !
    !XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
   
    string Status_Light01 = Light01.Substr(16, 5)
 
    !XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
    ! Übernehmen der Werte ins HM Frontend !
    !XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!
     
    ????????????
Das heißt ist meine Abfrage für den Status der Lampe richtig? Es sollte dort ja nun false oder on stehen je nach Status?

Und wie kriege ich nun den "Status_Light01" in eine Variable?

Verträgt die ccu2 diese häufigen Abfragen? Ich denke mit einer Abfrage alle 2 Minuten kann ich leben. Aber verkraftet das die CCU?

Re: Alle Hue-Lampen gleichzeitig "nativ" per Script auslesen

Verfasst: 03.02.2016, 11:53
von Blackeye
Hi,

erst einmal eine super Lösung zum auswerten des Dimmwertes!!!!!
Ich habe als CUXED Gerät die MultiDIMEXCEC Variante gewählt und hier wird der Dimmwert über den Schieberegler auch schön in der CCU angezeigt.
Es wird also nicht unbedingt eine Variable benötigt. Der Schalter zeigt so den richten Status direkt an.
Ich habe mir so einen HUE Taster gebastelt.

Der Status wird ausgelesen und je nachdem wie der Zustand ist entweder ein oder ausgeschaltet. Da ich die Lampen ja auch über die HUE App schalten kann, lese ich auch alle 2 Minuten den Status der Lampen aus und zeige Diesen über den Schalter an. So kann ich die Lampen direkt über die CCU und über die HUE APP schalten.

Wenn jetzt noch das Dimmen klappen würde......

Hier vielleicht ein Ansatz:

http://homematic-forum.de/forum/viewtop ... &start=240

Wenn das so rum geht, sollte es doch auch in die andere Richtung funktionieren, oder?

Wäre super wenn du das schaffen würdest.... :P :P

lars

Re: Alle Hue-Lampen gleichzeitig "nativ" per Script auslesen

Verfasst: 20.02.2016, 19:41
von leerzeichen
FanTC hat geschrieben:...Sobald ich Zeit habe, werde ich die Lampen in separate CuxD-Geräte auftrennen und Farbe und Sättig mit auswerten.
Ich frag mal ganz frech drauf los. Hast du Zeit und Muse schon gehabt das Script auf die Farbe und Sättigung zu erweitern? :D

Vielleicht noch als generelle Verständnisfrage, wenn ich deine Scripte nutzen möchte.
Ich benötige dafür das CuXD Gerät (28) SYSTEM EXE, z.B. die 19 Tasten Ferbedienung, oder das Multi-Dim-Exe?

Soweit ich verstanden habe, kann man das Script über das HomeMatic Script verwenden, ohne tcl welche auf der CCU2 liegen müssen?

Gruss und Danke :)

Re: Alle Hue-Lampen gleichzeitig "nativ" per Script auslesen

Verfasst: 16.01.2017, 12:41
von speedcow
Auf Anregung des hier veröffentlichen Skript, habe ich mich mal an die Umsetzung zur Abfrage des Hue Lampenstatus gemacht und alle dafür notwendigen Schritte in einer kleinen Doku zusammen gestellt. Das hier veröffentliche Skript läuft derzeit (Stand: 16.01.17) leider nicht, da Philips bei einem der letzten Firmware-Updates für die Hue-Bridge den JSON-Feed leicht verändert hat. Ich habe die notwendige Anpassung in meinem Skript vorgenommen. Die Schritt für Schritt Anleitung habe ich unter http://homematic.simdorn.net/philips-hue-lampenstatus/ veröffentlicht.

Ich freue mich auf ein Feedback, beantworte aber auch gerne Fragen und leiste Hilfestellung.

Viel Spass bei der Umsetzung

Re: Alle Hue-Lampen gleichzeitig "nativ" per Script auslesen

Verfasst: 29.03.2017, 11:38
von wesseli
@spedcow

Bitte prüfe mal Dein Script. Die Werte für die Farbsättigung stimmen nicht, dort werden die Farbwerte eingelesen.

Code: Alles auswählen

string SatHelp01 = Light01.StrValueByIndex(",",3); integer Sat01 = SatHelp01.Substr(6, 6); Sat01 = Hue01.ToInteger();
Auch gibt es Probleme, mit dem verwendeten "SET_STATE"-Befehl.

Code: Alles auswählen

dom.GetObject("CUxD.CUX2801002:1.SET_STATE").State(Bri01);
Der Status wird nicht gesetzt.

VG
wesseli