NEWS
[Vorlage] HCL-Script (human centric lighting)
-
Hallo Liebe Community,
ich möchte euch kurz mein selbstgesticktes HCL (human centric lighting) Script vorstellen.
Ich bin kein gelernter Programmierer und habe mich beim Programmieren auch mehr durchgekämpft. Daher entschuldigt bitte etwaige "Schweinereien" im CodeNun erst einmal zum Hintergrund.
Was ist HCL? HCL steht, wie oben schon beschrieben, für human centric lighting.
Mit HCL möchte man den Circadianen Rhythmus des Menschen unterstützen. Bedeutet, dass man je nach Tageszeit unterschiedliche Helligkeiten und Farbtemperaturen im und ums Haus nutzt um den "Schlaf-Wach-Rhythmus" zu unterstützen. Einige kennen das vielleicht auch schon vom Smartphone. Apple zum Beispiel nennt das Night Shift. In diesem Modus werden Abends die Blauanteile die vom Display ausgesendet werden reduziert um die Produktion des Schlafhormons Melatonin nicht zu unterdrücken. Wer da noch mehr wissen möchte kann sich unter den folgenden Links genauer einlesen. Besonders den Leitfaden HCL von Prof. Andreas Schulz auf licht.de (erster Link) möchte ich hervorheben.https://www.licht.de/fileadmin/Publikationen_Downloads/1806_lw21_HCL_web.pdf
https://de.wikipedia.org/wiki/Human_Centric_Lighting
https://de.wikipedia.org/wiki/Circadiane_RhythmikSo nun zu meinem Versuch das ganze in JavaScript halbwegs nutzbar umzusetzen.
Ich habe erst einmal einen "HCL-Generator" gebaut.Für das nachfolgende Script habe ich zwei Datenpunkte angelegt:
0_userdata.0.Global.Global-Brightness
0_userdata.0.Global.Global-HCLBeide Datenpunkte sind vom Typ Zahl, haben als Maßeinheit %, einen minimalen Wert von 0 und einen maximalen Wert von 100.
//////////////////////////////////// ///// Auf und Abdimmen für HCL ///// //////////////////////////////////// // Ab 06:30 Uhr 2,5h lang jede Minute den Brightness-Global Wert um 1 erhöhen. schedule('{"time":{"exactTime":true,"start":"06:30"},"period":{"days":1}}', function () { var brightness = 1; setState('0_userdata.0.Global.Global-Brightness', brightness) var dimmup = setInterval(function() { if(brightness < 100) { brightness += 1 setState('0_userdata.0.Global.Global-Brightness', brightness) } else { setState('0_userdata.0.Global.Global-Brightness', 100) clearInterval(dimmup); } }, 9000000 / 100); // 2,5h durch 100 mal laufen lassen. }); // Ab 17 Uhr ein Stunde lang alle jede Minute den Brightness-Global Wert um 1% von 100% auf 50% verringern schedule('{"time":{"exactTime":true,"start":"17:00"},"period":{"days":1}}', function () { var brightness = 99; setState('0_userdata.0.Global.Global-Brightness', brightness) var dimdown = setInterval(function() { if(brightness > 50) { brightness -= 1 setState('0_userdata.0.Global.Global-Brightness', brightness) } else { setState('0_userdata.0.Global.Global-Brightness', 50) clearInterval(dimdown); } }, 3600000 / 50); // 1h durch 50 mal laufen lassen. }); // Ab 19:30 Uhr 1,5 Stunden lang jede Minute den Brightness-Global Wert um 1% von 50% auf 0% verringern schedule('{"time":{"exactTime":true,"start":"19:30"},"period":{"days":1}}', function () { var brightness = 49; setState('0_userdata.0.Global.Global-Brightness', brightness) var dimdown = setInterval(function() { if(brightness > 1) { brightness -= 1 setState('0_userdata.0.Global.Global-Brightness', brightness) } else { setState('0_userdata.0.Global.Global-Brightness', 0) clearInterval(dimdown); } }, 5400000 / 50); // 1,5h durch 50 mal laufen lassen. }); ///// ///// Abändern der Farbtemperatur für HCL ///// // Ab 6 Uhr drei Stunden lang alle 6 Minuten den HCL-Global Wert um 1 verringern schedule('{"time":{"exactTime":true,"start":"06:00"},"period":{"days":1}}', function () { var HCL = 99; setState('0_userdata.0.Global.Global-HCL', HCL) var hcl_to_cold = setInterval(function() { if(HCL > 1) { HCL -= 1 setState('0_userdata.0.Global.Global-HCL', HCL) } else { setState('0_userdata.0.Global.Global-HCL', 0) clearInterval(hcl_to_cold); } }, 10800000 / 100); // 3h durch 100 mal laufen lassen. }); // Ab 15:00 Uhr vier Stunden lang alle 6 Minuten den HCL-Global Wert um 1 erhöhen schedule('{"time":{"exactTime":true,"start":"15:00"},"period":{"days":1}}', function () { var HCL = 1; setState('0_userdata.0.Global.Global-HCL', HCL) var hcl_to_warm = setInterval(function() { if(HCL < 100) { HCL += 1 setState('0_userdata.0.Global.Global-HCL', HCL) } else { setState('0_userdata.0.Global.Global-HCL', 100) clearInterval(hcl_to_warm); } }, 14400000 / 100); // 4h durch 100 mal laufen lassen. });
Achtung, die Werte die dieses Script in die Datenpunkte schreibt, ist nicht der Wert, der in irgendwelchen Lampen geschrieben wird.
Ich habe hier "interval" verwendet. Das hat aber auf jeden Fall den Nachteil, das wenn man in dem Script etwas ändert und dieses speichert oder der ioBroker neugestartet wird dann fliegt man aus einem aktuell laufenden Interval raus. Sollte man nur im Hinterkopf behaltenDas zweite Script ist ein globales Script!
Dieses Script interpoliert die Wunschwerte (Colortemp & Brightness) einzelner Leuchtmittel entsprechend der Prozentwerte aus dem HCL-Generator.
Das Script heißt bei mir setHCL und hat zwei Funktionen:function interpolHCL (global_hcl_min, global_hcl_max) { var global_HCL = getState('0_userdata.0.Global.Global-HCL').val; var global_HCL_int = Math.floor(global_HCL * (global_hcl_max - global_hcl_min) / 100 + global_hcl_min); return global_HCL_int; } function interpolBRI(global_bri_min, global_bri_max) { var global_BRI = getState('0_userdata.0.Global.Global-Brightness').val; var global_BRI_int = Math.floor(global_BRI * (global_bri_max - global_bri_min) / 100 + global_bri_min); return global_BRI_int; }
Als letztes Fehlt noch die Verwendung in den einzelnen Scripten der Leuchtmittel:
///////////////////Variablenzuweisung////////////////// var brightness_min = 45; var brightness_max = 100; var HCL_min = 100; var HCL_max = 377; on(["0_userdata.0.Global.Global-HCL", "0_userdata.0.Global.Global-Brightness", "zigbee.0.group_13.state", "0_userdata.0.Wohnzimmer.Whz_Wand_essen.HCL-Automatik"], function (dp) { if (getState("0_userdata.0.Wohnzimmer.Whz_Wand_essen.HCL-Automatik").val == true) { if (getState("zigbee.0.group_13.state").val == true) { setState("zigbee.0.group_13.colortemp", interpolHCL(HCL_min, HCL_max)) setState("zigbee.0.group_13.brightness", interpolBRI(brightness_min, brightness_max)) } } });
Achso, ich habe vergessen zu erwähnen das ich noch für jedes Leichtmittel welches HCL nutzen soll auch einen zusätzlichen Datenpunkt angelegt habe in dem steht ob die HCL-Automatik eingeschaltet ist oder nicht
In dem oberen Beispiel wäre das der Datenpunkt
0_userdata.0.Wohnzimmer.Whz_Wand_essen.HCL-AutomatikIn einer Szene kann ich nun zum Beispiel erst mal die HCL-Automatik abschalten und irgendeine Farbe, Farbtemp oder Helligkeit einstellen. In einer weiteren Szenen kann ich hingegen erstmal die HCL-Automatik einschalten und den State des Leuchtmittels auf On stellen. Und die HCL-Automatik stellt die Werte entsprechend ein.
So jetzt habe ich bemerkt das es etwas durcheinander war und ich nun etwas zügig fertig werden musste mit dem Schreiben Sollte etwas unklar sein, dann gerne fragen.
Ich würde mich auch über Verbesserungen freuen.
Auch ein eigener Adapter wäre super cool. Aber davon habe ich absolut überhaupt keine Ahnung das umzusetzen.Ich hoffe das es der ein oder andere verwenden kann.
Ich bin auf jeden Fall ziemlich zufrieden so wie es funktioniert und sogar der WAF ist bei nahezu 100%Nachtrag:
So sieht der HCL bzw. Helligkeitswert im Verlauf aus:
Anpassungen:
- Die überflüssige Variablendeklaration aus dem Script "setHCL" entfernt. Danke an paul53
- Die minimal Werte für die Datenpunkte Global-HCL und Global-Brightness auf 0 gesetzt.
- Abends die Helligkeit von 50% erst ab 19:30 Uhr weiter runter dimmen.
-
@vain sagte:
var global_bri_min, global_bri_max, global_hcl_min, global_hcl_max, global_HCL, global_BRI;
Diese Zeile ist umsonst und verwirrend, da alle Variablen lokal deklariert und verwendet werden.
-
@paul53 Das ist richtig. Habe ich angepasst. Besten Dank!
-
Es gibt eine Adapteranfrage auf github für einen Beleuchtungsadapter ähnlich wie beispielsweise shuttercontrol funktioniert. Wenn sich dem jemand annehmen würde, dann könnte eine HCL-Steuerung prima in einem solchen Adapter untergebracht werden.
-
Sehr schön, danke für die Vorarbeit. Ich denke, ich werde das in mein Skript LightControl integrieren. Ich hab zwar schon sowas ähnliches drin, das wechselt aber nur von 100% auf 2% je nach Sonnenstand.
Und da ist auch meine Frage, ich hab mal kurz in das Skript reingesehen und Du verwendest feste Uhrzeiten. D.h. das System reagiert Sommer wie Winter gleich. Is das so beabsichtigt und sinnvoll? Wär hier nicht ein Astroevent + x Stunden sinnvoller? -
@pittini Moin, sorry für die späte Rückmeldung. Ich war leider aus gesundheitlichen Gründen etwas abgelenkt.
Das dieses Script auf feste Uhrzeiten reagiert ist genau so gewollt. Ich möchte mit dem HCL gerade im Winter der Müdigkeit vorbeugen und länger "Tageslicht" haben.Das Einzige was mich an meinem Script aktuell noch "stört" ist das ich nicht auf einen Restart vom gesamten System oder dem Scriptadapter reagieren kann. Soll heißen, sollte ich mich aktuell in der Zeit befinden in der die Farbtemp und/oder die Helligkeit langsam geändert wird und das System startet neu oder der Script adapter, dann verbleibt der gerade aktuelle Wert bis zum nächsten Schedule. Das Passierte bei uns jetzt nicht so häufig aber wenn man es doch mal hat, dann ist es etwas doof, denn man gewöhnt sich doch schon sehr an die HCLSteuerung. Gerade meine Frau findet die extrem super. Aber auch erst seit dem Sie mal gesehen hat wie es ohne ist.
Um das zu umgehen müsste man irgendwie anhand der Zeiten und des Interval errechnen zu welcher Uhrzeit er bei welchen Schritt sein müsste. So könnte man nach einem Neustart den Interval "wieder aufnehmen"
Aber der Störfaktor war bei uns noch nicht so groß das ich mir da die Mühe machen wollte.