NEWS

[Vorlage] HCL-Script (human centric lighting)


  • Starter

    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 Code 🐷

    Nun 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_Rhythmik

    So 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-HCL

    Beide 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 behalten 😉

    Das 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-Automatik

    In 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:
    Bildschirmfoto 2020-07-09 um 11.01.29.jpg

    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.


  • Starter

    @paul53 Das ist richtig. Habe ich angepasst. Besten Dank!


  • Starter

    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.

    https://github.com/ioBroker/AdapterRequests/issues/439


  • Developer

    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?


Log in to reply
 

Suggested Topics

2.3k
Online

32.4k
Users

39.0k
Topics

528.5k
Posts