Die perfekte Lichtsteuerung mit Fibaro LUA - Teil 1

by fotolia.com
by fotolia.com
Geschrieben von crissxcross

Vergiss all deine Szenen und Scripte für Beleuchtungssteuerung, jetzt wird es wirklich smart.

[alert variation="alert-info" dismiss="dismiss"]Das Script wurde weiterentwicklet und bekam neue Funktionen. Einen weiterführenden Artikel findest du hier: Die perfekte Lichtsteuerung mit Fibaro LUA – Update 1[/alert]

Wir, also ich und meine Freundin, (Kind muss) haben entschieden umzuziehen. Freue mich schon wahnsinnig auf die neue Wohnung, vor allem weil die wirklich smart wird - bzw. diese das werden soll. Noch ist Sie nicht fertig, Vorteil für uns denn wir dürfen den Erstbezug vornehmen. So habe ich direkt dem Elektriker ein paar Fibaro Dimmer 2 in die Hand gedrückt, welche er hinter den Lichtschaltern verteilen soll. Durch die Fibaro Dimmer 2[icons icon="icon-link" color="#1e73be" size="13"], in Verbindung mit Tastern (anstelle von Schaltern) kann ich dann Szenen triggern (auslösen) und die Deckenbeleuchtung via Smartphone, Verknüpfungen oder Szenen steuern.

Daher suche ich momentan fleißig im Netz nach Ideen, welche die neue Wohnung noch smarter und mich damit etwas fauler machen können. Ich hoffe trotz Arbeit, Familie, Blog, IFA (im September) und Umzugsvorbereitungen finde ich noch etwas Zeit für siio, denn auf jedenfall möchte ich euch von allen Basteleien, Scripten, Virtuellen Modulen und anderen Smart Home Kram mit der Fibaro berichten. Das alles findet ihr ab sofort unter dem Tag: #ChrisBautSchloss oder unserer Fibaro "Wissensdatenbank"

Intelligente Beleuchtungssteuerung

Kennst du das auch? Du gehst Nachts noch mal PiPi und bist direkt Blind nachdem du das Licht einschalten hast? Das passiert dir mit dieser LUA Szene (Script) nicht mehr!

  • Einfache Konfiguration für Lichter und deren Dimm-Level
  • "on-time" pro Licht einstellbar
  • schaltet Lichter, auf einen bestimmten Dimmwert je nach Tageszeit
  • Script ändert das Dimm-Level der Leuchten (auch im eingeschaltetem Zustand), wenn sich die Tageszeit oder die Helligkeit ändert

Mit dem folgenden Script von Controlliving.nl[icons icon="icon-link" color="#1e73be" size="13"] (Danke Andreas[icons icon="icon-link" color="#1e73be" size="13"] für den Tipp und ein ganz besonderer Dank an Aleksander[icons icon="icon-link" color="#1e73be" size="13"] für den Support!), lässt sich die Beleuchtung vollautomatisch steuern. Hierbei können eine Vielzahl an Werten wie Helligkeit, Bewegung, Tageszeit und Anwesenheit der Bewohner berücksichtigt werden. Das LUA Script ist super einfach zu konfigurieren, aber dennoch wahnsinnig komplex - so komplex das es fast auf jeden Wohnbereich flexibel anwendbar ist.

Das LUA Script (Szene) schaltet zu den verschiedenen Tageszeiten, anhand einer Tageszeit Variable (mehr in Teil2) verschiedene von dir definierte Lampen ein, sobald eine Bewegung erkannt wurde und ein Mindest-LUX Wert (Helligkeit) unterschritten wird. Es unterstützt mehrere Helligkeits- und Bewegungsmelder und du kannst die Zeit festlegen, wie lange das Licht noch eingeschaltet bleiben soll, nachdem keine Bewegung mehr erkannt wurde.

Ausserdem verfügt das Script über ein "extra Function" Teil, in welchem du weiteren Script Code einfügen kannst, sogar mit IF - Then Regeln (WENN-DANN).

Da das Script auch viele Werte einbezieht, welche als Globale Variable abgefragt werden - wie zum Beispiel Tageszeit, Anwesenheit, Haus wach / schläft ect. - hat dieses Tutorial mehrere Teile. Hier in diesem Artikel findest du das vollständige LUA Script zum Download und ich erkläre dir die Stellen im Script, welche du anpassen musst, so das dass Script nach diesem Artikel heute noch bei dir funktioniert. Wie du am besten die anderen benötigten Variablen setzt, erkläre ich dir im nächsten Teil.

Lass uns mal starten, indem ich jetzt die Teile hier hinein kopiere, welche du anpassen musst. Natürlich werde ich jeweils noch ein paar Worte dazu verlieren. Am Ende dieses Artikels findest du dann den Download Link mit dem gesamten Script.

Beleuchtungs-Szenen LUA Script erklärt

Beginnen wir direkt in Zeile 1. In den %%properties wie immer die Elemente (Aktoren, Sensoren, Variablen ect.) - welche die Szene triggern, also auslösen. Bei dem Beleuchtungsscript sieht das so aus:

Ich denke allzuviel muss ich  hierzu nicht sagen. Die Szene kann also entweder durch Bewegung oder Veränderung der Helligkeit ausgelöst werden, sowie bei Veränderung der Tageszeit oder Anwesenheit. Bedeutet, wenn die Lichter gerade an sind und die Helligkeit überschreitet den Mindest LUX / Helligkeitswert, so werden diese ausgeschaltet. Gleiches gilt wenn sich dein Anwesenheitsstatus verändert, weil du das Haus verlassen hast. Auch wenn sich die Tageszeit verändert, beispielsweise von "Morning" auf "Day" und du noch am  Frühstückstisch sitzt, da du wieder getrödelt hast, gehen die Lampen in die entsprechende Lichtstimmung für "Day".

Bewegungsmelder und Lichtsensoren definieren

So nun ab in Zeile 24 und 25.

Hier gibst du die ID für den Bewegungsmelder und den Sensor für die Helligkeit ein. Die gleichen IDs hast du ja gerade oben in den Properties eingetragen. Wenn du mehrere Lichtsensoren verwenden möchtest, trägst du diese so ein:

In diesem Fall errechnet das Script von beiden Werten den Durchschnittswert. Die gleiche Formatierung kannst du verwenden wenn du mehrere Bewegungsmelder nutzen möchtest, um die Beleuchtung einzuschalten. Vergiss nicht die IDs der zusätzlichen Licht- und Bewegungsmelder auch oben in den Properties einzutragen!

So findest du übrigens die ID der Komponente heraus:

Fibaro - Geräte ID herausfinden

Fibaro - Geräte ID herausfinden

Globale Variablen anlegen

Da ab Zeile 33 globale Variablen verwendet werden, müssen wir diese erst einmal anlegen. Diese Variablen sagen später der Szene welche Tageszeit gerade ist, ob du Zuhause bist und ob das Haus gerade schläft (interessant für Tierbesitzer, damit Ihr Nachts keine Disco im Haus habt).

Um die Variablen anzulegen, gehe in der Weboberfläche des Fibaro HC2 oben auf: Steuerung > dann im linken Menü auf: Variablen Steuerung

Fibaro HC2 Variablen anlegen

Fibaro HC2 Variablen anlegen

Hier brauchen wir diesmal nicht die "einfachen" Variablen, sondern du scrollst nach ganz unten zu: "Vordefinierte Werte". Hier legst du nun 3 verschiedene Variablen an: SleepState ; TimeOfDay ; PresentState. Die Variablen bekommen folgende Werte:

  1. SleepState = Sleeping ; Awake
  2. PresentState = Home ; Away ; Holiday
  3. TimeOfDay = Morning ; Day ; Evening ; Night
Vordefinierte Variablen anlegen in Fibaro HC2

Vordefinierte Variablen anlegen in Fibaro HC2

Achte beim Anlegen der Variable auf die Groß- und Kleinschreibung! Mit diesen Variablen wird das Beleuchtungsscript eigentlich erst intelligent, denn durch diese erhält es die Informationen "was los ist". Natürlich müssen diese Variablen ab sofort korrekt gesetzt werden. Da du dies sicher nicht händisch machen möchtest, brauchen wir weitere Szenen oder virtuelle Module, welche dies für uns erledigen. Aber dazu in den nächsten Teilen dieser Turorialreihe mehr. (Wenn du sehr ungeduldig bist, hier ein Tipp: Über die Anwesenheitsprüfung hab ich hier und da schon einmal was geschrieben.)

Variablen zur intelligenten Lichtsteuerung

Variablen zur intelligenten Lichtsteuerung

Noch ein kleiner Tipp, stelle die SleepState Variable jetzt erstmal auf "Awake" ;-)

So dann hier noch fix der Ausschnitt von Codezeile 28-35 wo die Variablen gemappt werden:

Licht wenn Mindesthelligkeit unterschritten wird

In den Zeilen 39- 42 finden wir unsere Tageszeiten wieder. Hier geht es nun darum, wie dunkel es im Raum sein muss, damit das Licht eingeschaltet wird. Wir definieren hier also eine Mindeshelligkeit in Lux, welche unterschritten werden muss, damit das Licht angeht. Welche Werte du hier benötigst ist völliges Finetuning. Hier heißt es probieren, beobachten, testen und optimieren.

Lichter, auf bestimmten Dimmwert je nach Tageszeit

Hier kommen wir nun zu dem wirklich interessanten Teil - ab hier passiert dann auch mal was ;-) Ich rede von Zeile 53- 57. So sieht das ganze aus:

Voran die entsprechende Tageszeit, dahinter in den Klammern werden die Lichter definiert, welche eingeschaltet bzw. gedimmt werden sollen. Zum einschalten einer Relais[icons icon="icon-link" color="#1e73be" size="13"], oder was auch immer. Hier nochmal die unterschiedlichen Geräte Möglichkeiten:

  1. Zwischenstecker und Relais: {id=902, setValue="turnOn", onTime=300}
  2. Dimmer : {id=471, setValue="80", onTime=300}
  3. RGBW Module: {id=414, setValue={R="32", G="7", B="0", W="0"}, onTime=300}

Der Wert "onTime" definiert die Zeit, wie lange das Licht noch an bleibt, nachdem die letzte Bewegung erkannt wurde. Im Beispiel der onTime von 300 entsprticht dies 300 Sekunden, also 5 Minuten. Du kannst die onTime aber auch weglassen. Es gibt also 3 Möglichkeiten:

  1. Die Werte ohne den Timer setzen, benutze 2 Parameter: {LightID, "VALUE"}
  2. Die Werte mit Timer setzen benötigst du 3 Parameter: {LightID, "VALUE", timeInSeconds }
  3. Verwenden von virtuellen Modulen mit Slider: {LightID, "VALUE", "timeInSeconds", VirtualDeviceSliderID}

Im Beispiel ist die "Tageszeit" Sleep leer: lightsSleeping = {}; - heißt es werden keine Leuchten eingeschaltet. Daher vorhin mein Tipp beim Variablen anlegen, die SleepState Variabel erstmal auf Awake zu setzen, damit beim probieren und testen auch deine Lampen ganz sicher angehen ;-)

Extra Funktionen pro Tageszeit

Hier kannst du dich austoben! Beachte aber, das dieser Teil vom Script immer ausgelöst wird wenn Bewegung erkannt wurde. Der gesetzte MinLux Wert spielt hier keine Rolle. Dennoch eine schöne Spielwiese um Beispielsweise in der "extraMorningFunc" zu prüfen ob der iKettle schon Wasser gekocht hat und wenn nicht, dann kannst du ihn hier einschalten. Oder schalte in der "extraEveningFunc" noch deine Lieblingslampe an, wenn der XBMC Player läuft. If- then Befehle sind hier nämlich durchaus möglich.

Beispiel:

Zu finden sind die Extra Funktionen ab Zeile 66.

Das wars schon! Mehr musst du an dem Script für die Szene nicht ändern. Also los: Gehe auf die Weboberfläche deines Fibaro HC2, gehe zu Szenen und lege eine neue Szene mit LUA an. Dort wechsel du auf die Registerkarte: Erweitert und kopierst das Script hinein. Danach kannst du all deine Anpassungen vornehmen.

[carousel arrows="display" buttons="display" caption="display"] [panel title="Smart Lights" description="Szene - Morning und Day"]lichtszene-day[/panel] [panel title="Smart Lights" description="Szene - Evening"]lichtszene-evening[/panel] [panel title="Smart Lights" description="Szene - Night"]lichtszene-night[/panel] [panel title="Smart Lights" description="Szene - Evening Flur"]lichtszene-evening-treppe[/panel] [panel title="Smart Lights" description="Szene - Night Flur"]lichtszene-night-treppe[/panel] [/carousel]

Das Script kannst du hier herunterladen

Ich bin mega gespannt, wie du das Script einsetzt, welche Lichter du steuerst. Poste gern Bilder in unserem Forum!  Wenn du coole Scripte oder Virtuelle Module hast, immer her damit, ich teste gern alles was meine neue Wohnung smarter macht.

Titelbild by fotolia.com

Diesen Blogpost hat geschrieben ...

crissxcross

Chris, Gründer und Blogger von siio.
Gelernter IT-Systemelektroniker, seit vielen Jahren beruflich als Produktmanager im Smart Home unterwegs. Technikverliebter Familienvater, Apple Fan. Nach einigen Jahren Stadtleben wieder froh auf dem Land zu sein.

51 Kommentare

  • Danke für die super Beschreibung :)
    Wird wohl das nächste Projekt werden die Lichtsäuerung zu überarbeiten aber graut mir davor das an das System anzupassen, Arbeite mit anderen Variablen :(

    Trotzdem super Sache.

  • Hm... Wenn es sich um ein Lua-Script handelt (und die Syntax deutet sehr darauf hin) dann würde man normalerweise keine Semikolons benutzen. Das hat mich beim lesen des Codes zunächst doch sehr verwirrt... ;) Hier ist ein guter Einstiegspunkt, möchte man Lua etwas vertiefen. http://lua-users.org/wiki/

  • Hi Crissxcross,

    vielen Dank für das tolle Script.

    Ich habe das gesamte Script kopiert und nur die genannten Parameter geändert. Oder hätte ich erstmal einen Teil des Scripts löschen müssen?Denn ich bekomme jetzt die Fehlermeldung Error in line 631:unexpected symbol near '%'

    Vielen Dank für Deine Hilfe

  • Super Script,

    wollte das ganze für meine Rollos umbauen. Leider funktioniert das nicht. Hat da vll. einer einen Tip für mich ;)

    Danke & Gruss

  • Hallo und guten Tag Chris,

    ich habe mir deine Scene mal auf meine Fibaro HC2 geladen und die Werte für Sensoren und meinem Dimmer geändert.
    Im Debug wird auch angezeigt das der Dimmer einschaltet. Leider macht er es nicht wirklich. Könntest Du dir mal meine Scene ansehen?
    Ich bin mit meinem Wissen noch am Anfang und finde den Fehler nicht.
    Wenn ich die Scene in der Grafischen einstelle Geht das verfluchte Licht an und zwar genau mit den gleichen ID für die Sensoren und Dimmer

    Mit freundlichen Grüßen

    René

      • Da ich keinen anderen weg finde probiere ich es über diesen weg!
        Ich möchte mich bei euch im Forum anmelden bekomme aber keine EMail zugeschickt mit der
        ich mich anmelden könnte ! Freu mich jetzt schon auf eure Hilfe.
        HC2 User

        Mfg

    • hallo, hast du eine lösung für dein problem?? ich habe leider das gleich problem. mit einigen dimmern gehts mit der mehrheit leider nicht. neues anlernen der dimmer hat leider auch keinen erfolg gebracht. hat jmd einen tip woran es liegen könnte?

    • Hi René,
      vielleicht musst du die Zeile:
      DimmerDeviceType = { „com.fibaro.multilevelSwitch“ }
      zu
      DimmerDeviceType = { „com.fibaro.multilevelSwitch“, „com.fibaro.FGD212“ } ändern.
      Bei mir hat das geholfen.

      Gruß Seppl

      • Hi
        erstmal ein super Tip!
        allerdings sind die Apostroph Zeichen falsch. Habe ein bissl gebraucht den Fehler zu finden.
        Hier das richtige (für diejenigen die das selbe problem haben)
        DimmerDeviceType = { "com.fibaro.multilevelSwitch", "com.fibaro.FGD212" }

        • Aja kommt automatisch so....
          die Apostroph Zeichen müssen oben stehen.
          Für diejenigen die es noch nicht wissen so wie ich vorher ;-)

  • Hallo zusammen,

    ich habe das Skript genutzt und mit einem MotionSensor funktioniert es auch (danke euch für dieses tolle Forum!!). Wie kann ich denn einen 2. oder 3. MotionSensor einbinden? Mit Trennung per Komma funktioniert es leider nicht - auch nicht, wenn ich den Value im Header einbinde... Dann reagiert das Skript nicht, obwohl die MotionSensoren auf "ausgelöst" stehen.
    Ich habe es aber richtig verstanden, dass ich für jeden Raum am Besten ein eigenes Skript nutze, oder (sorry, bin newbee... ;-))

    Danke für eure Hilfe!

  • Habe die Anleitung befolgt und alles angepasst. Leider scheint es mit meinen Philipps Hues nicht zu gehen, Es kommt folgender Fehler:
    Error: Light status unknown

    Liegt das an der etwas anderen Lampenart?

  • Erst mal vielen Dank für das tolle Script! Ich hab noch ne Frage zu den einzelnen Tageszeiten, da ich bemerkt hab, die werden bei mir nicht automatisch verändert. Woher weiß mein HC2, ob es Morning, Day,... ist?
    Hab ich da ein Script verschlafen?

    Danke Joe

    • Hi,

      das sind glaub ich immer individuelle Lösungen. Die PresentState wird bei mir über RFID geregelt, SleepState über ein Knopf vor dem Schlafzimmer. Bei SleepState könnten zum Beispiel auch Sleeptracker zur Verwendung kommen. Wie gesagt, da hat jeder seine eigene Herangehensweise.

      Gruß

  • Das teil ist toll ! Ich habe es in diversen Räumen am Laufen. Eine Frage bitte, ich bekomme einen Fibaro Wallplug nicht zum Laufen, er ist der letzte in der Kette mit der ID 124. Muss dieser anders gesetzt werden ?

    lightsMorning = {{id=151, setValue="5", onTime=180},{id=61, setValue="turnOn", onTime=180},{id=59, setValue="turnOn", onTime=180},{id=124, setValue="turnOn", onTime=180}};
    lightsDay = {{id=151, setValue="5", onTime=180},{id=61, setValue="turnOn", onTime=180},{id=59, setValue="turnOn", onTime=180},{id=124, setValue="turnOn", onTime=180}};
    lightsEvening = {{id=151, setValue="5", onTime=180},{id=61, setValue="turnOn", onTime=180},{id=59, setValue="turnOn", onTime=180},{id=124, setValue="turnOn", onTime=180}};
    lightsNight = {{id=151, setValue="5", onTime=180},{id=61, setValue="turnOn", onTime=180},{id=59, setValue="turnOn", onTime=180},{id=124, setValue="turnOn", onTime=180}};
    --setValue={R="255",G="255",B="255",W="255"}

  • Habe leider ein Problem, steige da irgendwie nicht hinter.

    Bekomme im Debug 2 Meldungen:
    - sensor lux: 8 is lower then minValue 65535
    Sensor zeigt 8 lux an...im Script sind die Standardwerte drin.
    - no lights set for Evening.

    Habe aber alles soweit richitg eingetragen
    lightsSleeping = {}; --lights that are triggered when Sleepstate is sleeping.
    lightsMorning = {{id=74, setValue="50"},{id=27, setValue="50"},{id=101, setValue="99"},{id=72, setValue="99"},{id=68, setValue="50"}};
    lightsDay = {{id=74, setValue="99"},{id=27, setValue="80"},{id=101, setValue="99"},{id=72, setValue="99"},{id=68, setValue="80"}};
    lightsEvening = {{id=74, setValue="50"},{id=27, setValue="50"},{id=101, setValue="99"},{id=72, setValue="99"},{id=68, setValue="50"},{id=103, setValue="80"},{id=116, setValue="80"},{id=114, setValue="80"}};
    lightsNight = {{id=101, setValue="10", onTime=90},{id=72, setValue="10", onTime=90},{id=68, setValue="10", onTime=90}};

    Könnte mir hier bitte jemand helfen? DANKE

  • Hallo Criss,

    ist es möglich Philips HUE Lampe mit der perfekte Lichtsteuerung zu steuern? Aktuell habe ich noch keine Lampen würde mir diese, abhängig von der Antwort, aber zulegen wollen. Ich habe bereits gesehen, dass ich in der HC2 ein PlugIn installieren kann um die HUE zu steuern.

    Ziel soll es sein, mein Flurlicht über ein Motion Sensor tageszeitabhängig zu steuern. und selbstverständlich bei Abwesenheit alles zu deaktivieren.

    Vielen Dank für die Antwort

  • Hallo,

    ich habe mal noch eine Frage zu dem Script. Kann man in dem Script eine Art Dauerschleife aktivieren. Immer wenn die Schalter oder Lampen geschaltet sind endet es bei mir. Ich würde gerne, dass das Script immer läuft.

    Grüße

  • Ich wollte gerne das bei Sonnenaufgang und bei Dunkelheit das Licht angeht und dann sich nachher abschaltet und am Abend auch. Damit das mit dem Script funktioniert muss ich es ja jedes mal starten. Dachte mir das man dann die Abfrage des Scriptes immer durchlaufen lässt und wenn die Bedingungen stimmen das sich dann das Licht einschaltet. Vielleicht hast Du aber eine andere Idee mit eine Script was ich nehmen könnte. Wollte gerne über Script das Steuern damit ich die Befehle so langsam lerne.

    Bin noch ein Neuling was Fibaro und Scripte angeht. Aber das Forum hier und die Admin´s sind echt eine große Hilfe. Danke

    Grüße

  • Vielen Dank, mit dem Script bastele ich auch schon rum. Aber der Beginn des Morgens ist in dem Script nicht gut und ich versuche die Variable Morning vor dem Sonnenaufgang zu bringen. Da der Sonnenaufgang um 8.00 Uhr beginnt und mein Tag um 9.00Uhr startet ist die Variable Morning etwas kurz. Mir wäre es lieber wenn der Morgen schon 7.00Uhr beginnt. Da bin ich gerade dabei das zu verändert. Habe aber noch keine Lösung.Wenn Du da ein Tipp hast das zu ändern mit einem LUA Befehlt würde ich mich freuen.

    Grüße

  • Das will einfach nicht laufen - im Debug sieht aber alles OK aus.
    Hat jemand eine Idee was fehlen könnte?

    --[[
    %% properties
    236 value
    238 value
    %% globals
    TimeOfDay
    PresentState
    --]]

    --[[ Change - XXX value - above. One for motion sensor, one for Light sensor.
    TimeOfDay global variable and lux make sure that the scene
    will be triggered when you are already in the room and something changes.

    Set your settings below, lights and add extra functions
    Feel free to suggest changes or contact when having problems.
    It is not allowed to sell or distribute this software and earlier versions without the approval of Control Living
    � 2014 - 2015 Smart lights by Control Living
    Version 1.6.7
    --]]

    --------------------------------------------------------------------
    -----------------------YOUR LIGHT SETTINGS--------------------------

    motionSensorID = {236}; -- change id for your motion sensor.
    LuxSensorID = {238}; -- change id for your light sensor.

    --Enter the name of your Global variable. WITHOUT IT, THE SCENE DOES NOT WORK. Capital sensitive!
    sleepState = "SleepState"; --Sleep globalstate variable.
    timeOfDay = "TimeOfDay"; --Time of Day Global variable.
    presentState = "PresentState"; --Present state Global variable.

    --Enter the values of your global variables stated above. If not using, copy the name in front of the "YourValueName"
    sleepStateMapping = {Sleeping="sleeping", Awake="awake"};
    timeOfDayMapping = {Morning="morning", Day="day", Evening="evening", Night="night"};
    presentStateMapping = {Home="home", Away="away", Holiday="holiday"};

    -- Set the lux value for which the lights have to be turned on.
    -- If you don't want to use the MinLux then just set it to: 65535
    minLuxMorning = 65535;
    minLuxDay = 65535;
    minLuxEvening = 65535;
    minLuxNight = 65535;

    --If the current lux value is above the maxlux, the lights will turn off after their set onTime.
    maxLuxMorning = 300;
    maxLuxDay = 300;

    --[[
    Now the most important part:
    Here you can enter what light, for how long and at what value has to be turned on.
    Leave empty brackets for no lights.
    To set the light value without timer use 2 parameters: {id=LightID, setValue="VALUE"}
    To set the light value with timer use 3 parameters: {id=LightID, setValue="VALUE", onTime=timeInSeconds }
    To set the light value for RGBW: use the above, where setValue is: setValue={R="255",G="255",B="255",W="255"}
    -- RGBW set: {id=LightID, setValue={R="255",G="255",B="255",W="255"}, onTime=timeInSeconds }
    --]]

    lightsSleeping = {}; --lights that are triggered when Sleepstate is sleeping.
    lightsMorning = {{id=250, setValue="99", onTime=300},{id=491, setValue="99", onTime=300},{id=902, setValue="turnOn", onTime=360}};
    lightsDay = {{id=250, setValue="turnOn", onTime=90},{id=491, setValue="80", onTime=90}};
    lightsEvening = {{id=250, setValue="60", onTime=300},{id=491, setValue="60", onTime=300},{id=902, setValue="turnOn", onTime=300}};
    lightsNight = {{id=250, setValue="45", onTime=60}, {id=491, setValue="45", onTime=60}};

    --Manual Override, the time that lights will not be turned ON again after manually turning them off.
    OverrideFor = 90;
    dimmDownTime = 10;

    --------------------------------------------------------------------
    -------------------------EXTRA FEATURES-----------------------------

    extraMorningFunc = function()
    -- Add your extra code here. If you want some checks or maybe run a virtual device button.
    --This code is always triggered if there is motion.
    -- movieLights = {{180, "10"},{181, "10"} };
    --if (xbmc == "playing" ) then CallLightArray(movieLights);
    ExtraDebug("Extra morning function called");
    end

    extraDayFunc = function()
    -- Add your extra code here. If you want some checks or maybe run a virtual device button.
    --This code is always triggered if there is motion.
    ExtraDebug("Extra day function called");
    end

    extraEveningFunc = function()
    -- Add your extra code here. If you want some checks or maybe run a virtual device button.
    --This code is always triggered if there is motion.
    ExtraDebug("Extra evening function called");
    end

    extraNightFunc = function()
    -- Add your extra code here. If you want some checks or maybe run a virtual device button.
    --This code is always triggered if there is motion.
    ExtraDebug("Extra night function called");
    end

    extraLightTriggerChecks = function()
    --add extra checks here. and return the total true or false value.
    --if returning false the lights will not be triggered.
    -- for instance: return ( (pcTurnedOff == true ) and (xbmc ~= "Empty") );
    -- return true to enable lights to turn on
    return true;
    end

    extraOffChecks = function()
    --return true to keep lights on.
    return false;
    end

    --------------------------------------------------------------------
    ----------------------ADVANCES SETTINGS-----------------------------
    local showStandardDebugInfo = true; -- Debug shown in white
    local showExtraDebugInfo = false; -- Debug shown in orange

    --------------------------------------------------------------------
    --------------------------------------------------------------------
    -- DO NOT CHANGE THE CODE BELOW --
    --------------------------------------------------------------------
    --UPDATE FROM HERE

    --private variables
    startSource = fibaro:getSourceTrigger();
    keepLightsOn = false;
    timerRunning = false;
    previousLights = nil;
    version = "1.6.7";

    SavedState = {
    homeStatus = "",
    sleepState = 0,
    timeOfDay = "",
    lux = 0,
    motion = 0,
    startTime = 0
    }

    CurrentState = {
    homeStatus = "",
    sleepState = "",
    timeOfDay = "",
    lux = 0,
    motionState = 0,
    currentLightArray = {}
    }

    RGBWDeviceType = { "com.fibaro.RGBW", "com.fibaro.colorController", "com.fibaro.FGRGBW441M" }
    BinaryDeviceType = { "com.fibaro.binarySwitch","com.fibaro.FGWP101", "turnOn" }
    DimmerDeviceType = { "com.fibaro.multilevelSwitch" }

    OffModes = {None, ByScene, ManualOverride }

    function Debug( color, message )
    fibaro:debug(string.format('%s', "span", color, message, "span"));
    end

    --Making sure that only one instance of the scene is running.
    fibaro:sleep(50); --sleep to prevent all instances being killed.
    if (fibaro:countScenes() > 1) then
    if (showExtraDebugInfo) then
    Debug( "grey", "Abort, Scene count = " .. fibaro:countScenes());
    end
    fibaro:abort();
    end

    --------------------------EXECUTION----------------------------------

    function SetCurrentStatus()
    ExtraDebug("Updating current variable statuses");
    CurrentState.homeStatus = GetPresentState();
    CurrentState.timeOfDay = GetTimeOfDay();
    CurrentState.sleepState = GetSleepState();
    CurrentState.lux = GetAverageLuxValue();
    CurrentState.motionState = GetCurrentMotionStatus();
    end

    function SaveCurrentStatus()
    ExtraDebug("Saving current variable statuses");
    SavedState.homeStatus = CurrentState.homeStatus;
    SavedState.timeOfDay = CurrentState.timeOfDay;
    SavedState.sleepState = CurrentState.sleepState;
    SavedState.lux = CurrentState.lux;
    SavedState.motion = CurrentState.motionState;
    end

    function CheckStatusChanges()
    ExtraDebug("Status change check");
    if (CurrentState.homeStatus ~= SavedState.homeStatus ) or (CurrentState.timeOfDay ~= SavedState.timeOfDay ) then
    if (CurrentState.homeStatus ~= presentStateMapping.Home ) then
    TurnOffLights();
    else
    SceneTriggered();
    --reset time.
    end;
    end
    SaveCurrentStatus();
    -- if we still have a motion then reset timer.
    if ( (CurrentState.motionState ~= 0 or extraOffChecks() ) and not IsMaxLuxExceeded() ) then
    ExtraDebug( "Resetting time" );
    SavedState.startTime = os.time();
    else
    ExtraDebug("Timer is not reset.");
    end
    --any other case, we are not resetting the timer.
    end

    function IsMaxLuxExceeded()
    if (CurrentState.timeOfDay == timeOfDayMapping.Morning and CurrentState.lux > maxLuxMorning ) then
    ExtraDebug( "Current lux value: " .. CurrentState.lux .. " higher then max Lux Morning: " .. maxLuxMorning .. ".");
    return true;
    elseif (CurrentState.timeOfDay == timeOfDayMapping.Day and CurrentState.lux > maxLuxDay ) then
    ExtraDebug( "Current lux value: " .. CurrentState.lux .. " higher then max Lux Day: " .. maxLuxDay .. ".");
    return true;
    end
    return false;
    end

    function LightsOff( lightArray )
    local stillLightsOn = 0;
    local currentTime = os.time();
    for i = 1,#lightArray do
    if ( lightArray[i].onTime ~= nil) then
    lightItem = lightArray[i];
    lightItem.OffMode = CheckManualOverrideItem( lightItem );
    --local
    if ( lightItem.OffMode == "ManualOverride" ) then
    ExtraDebug("Manual override for light: [" .. lightItem.id .. "]" .. lightItem.name .. " active, not turning on");
    goto continue;
    end
    --On till:
    local timeL = SavedState.startTime + (lightItem.onTime);
    local timeLeft = timeL - currentTime;
    if (timeLeft >= 0 ) then ExtraDebug("Time left for: [" .. lightItem.id .. "]" .. lightItem.name .. ": " .. timeLeft .. " seconds" ); end
    if ( timeLeft < dimmDownTime ) then
    if ( lightItem.OffMode ~= "ManualOverride" ) then
    lightItem.OffMode = "ByScene";
    end
    if ( (timeLeft <= 0) and (lightItem.currentValue ~= 0) ) then
    fibaro:call(lightItem.id, "turnOff");
    StandardDebug("Switch off light: [" .. lightItem.id .. "]'" .. lightItem.name .."'");
    else
    if ( item.lightType == "com.fibaro.multilevelSwitch" ) then
    currentValueDiv = roundit(((lightItem.currentValue) / (dimmDownTime)), 0);
    currentValueNew = (lightItem.currentValue - currentValueDiv);
    if (currentValueNew 0 ) do
    ExtraDebug("Still in override for: " .. (OverrideTimer + OverrideFor ) - os.time() .. " seconds" );
    fibaro:sleep(1000);
    UpdateLightValues(currentLightArray);
    OverrideForAll = CheckIfAllInOverrideMode(currentLightArray);
    motion = GetCurrentMotionStatus();
    if ( motion ~= 0 ) then
    OverrideTimer = os.time();
    end
    end
    else return false;
    end
    -- if ( (OverrideTimer + OverrideFor ) - os.time() minLux ) then
    StandardDebug( "Sensor lux: " .. newLuxValue .. " higher then minValue: " .. minLux .. " : no action");
    else
    StandardDebug("Sensor lux: " .. newLuxValue .. " is lower then minValue: " .. minLux);
    SetLightValues(lightArray);
    CallLightArray( lightArray, "on" );
    CheckPreviousLights( lightArray );
    end
    else
    ExtraDebug("ExtraLightTriggerChecks failed, so no lights");
    end
    end

    function SceneTriggered()
    if ( CurrentState.homeStatus ~= presentStateMapping.Home ) then
    ExtraDebug("Presentstate = not at home, so no lights");
    elseif ( CurrentState.sleepState == sleepStateMapping.Sleeping ) then
    LightperDayPart( 65535, lightsSleeping );
    elseif ( CurrentState.timeOfDay == timeOfDayMapping.Morning ) then
    extraMorningFunc();
    LightperDayPart( minLuxMorning, lightsMorning );
    elseif ( CurrentState.timeOfDay == timeOfDayMapping.Day ) then
    extraDayFunc();
    LightperDayPart( minLuxDay, lightsDay );
    elseif ( CurrentState.timeOfDay == timeOfDayMapping.Evening ) then
    extraEveningFunc();
    LightperDayPart( minLuxEvening, lightsEvening );
    elseif ( CurrentState.timeOfDay == timeOfDayMapping.Night ) then
    extraNightFunc();
    LightperDayPart( minLuxNight, lightsNight );
    else
    ErrorDebug( "No lights: " .. CurrentState.timeOfDay );
    end
    if (keepLightsOn == true) then
    RunTimer();
    end
    end

    function SceneTriggeredByLights( st )
    if (st == "off") then
    ExtraDebug( "light turned off, sleep 4 sec" );
    fibaro:sleep(4000);
    elseif (st == "on") then
    ExtraDebug( "light turned on, activating timer" );
    fibaro:sleep(4000);
    --TODO: add light to current array.
    --keepLightsOn = true;
    --RunTimer();
    end
    end

    ------------------------STATUS functions------------------------------

    function GetTimeOfDay()
    return LookupGlobal( timeOfDay, "TimeOfDay", "Day");
    end

    function GetSleepState()
    return LookupGlobal( sleepState, "sleepState", "Awake");
    end

    function GetPresentState()
    return LookupGlobal( presentState, "presentState", "Home");
    end

    function LookupGlobal( name, stateName, default )
    local ps = fibaro:getGlobalValue( name );
    if ( (ps ~= "") and (ps ~= nil ) ) then
    ExtraDebug("returned " .. stateName .. ": " .. ps );
    return ps;
    else
    ErrorDebug( stateName .. " variable not found");
    return default;
    end
    end

    function lightsStatus( id )
    --check if lights are already on.
    allLights = {lightsSleeping, lightsMorning, lightsDay, lightsEvening, lightsNight };
    for i = 1,#allLights do
    for iL = 1, #allLights[i] do
    local lightItem = allLights[i][iL];
    if ( lightItem.id == tonumber(id) ) then
    if ( lightItem.currentValue == 0 ) then
    return "off";
    else
    return "on";
    end
    end
    end
    end
    ErrorDebug("Light status unknown");
    return "Unknown";
    end

    function GetTimeOfDayLightArray()
    if ( CurrentState.sleepState == sleepStateMapping.Sleeping ) then
    return lightsSleeping;
    elseif ( CurrentState.timeOfDay == timeOfDayMapping.Morning ) then
    return lightsMorning;
    elseif ( CurrentState.timeOfDay == timeOfDayMapping.Day ) then
    return lightsDay;
    elseif ( CurrentState.timeOfDay == timeOfDayMapping.Evening ) then
    return lightsEvening;
    elseif ( CurrentState.timeOfDay == timeOfDayMapping.Night ) then
    return lightsNight;
    end
    end

    function GetCurrentMotionStatus()
    local sensorbreached = 0;
    if (CheckIfTable(motionSensorID, "motionSensorID") ) then
    for i = 1,#motionSensorID do
    if ( tonumber(fibaro:getValue(motionSensorID[i], "value")) > 0 ) then
    sensorbreached = 1;
    end
    end
    else
    --if not a table, just return the value of the containing ID
    sensorbreached = tonumber(fibaro:getValue(motionSensorID, "value"))
    end
    return sensorbreached;
    end

    function GetAverageLuxValue()
    local luxAverage = 0;
    if (CheckIfTable(LuxSensorID, "LuxSensorID") ) then
    if (#LuxSensorID == 1) then
    return tonumber(fibaro:getValue(LuxSensorID[1], "value"));
    end
    for i = 1,#LuxSensorID do
    luxAverage = luxAverage + tonumber(fibaro:getValue(LuxSensorID[i], "value"));
    end
    luxAverage = roundit( (luxAverage / #LuxSensorID), 0 );
    else
    --if not a table, just return the value of the containing ID
    luxAverage = tonumber(fibaro:getValue(LuxSensorID, "value"));
    end
    return luxAverage;
    end

    function UpdateLightValues( currentArray )
    for i = 1,#currentArray do
    item = currentArray[i];
    newValue = fibaro:getValue(item.id, "value");
    item.currentValue = tonumber(newValue) ~= nil and tonumber(newValue) or ( newValue == "true" and 1 or 0 );
    if ( item.lightType == "com.fibaro.RGBW" )then
    color = fibaro:getValue(item.id, "color");
    c = {R="0", G="0", B="0", W="0", brg="0" }
    c.R, c.G, c.B, c.W = color:match("([^,]+),([^,]+),([^,]+),([^,]+)");
    c.brg = fibaro:getValue(item.id, "brightness");
    item.currentValue = c;
    end
    end
    end

    function SetLightValues(currentArray)
    for i = 1,#currentArray do
    item = currentArray[i];
    item.name = tostring(fibaro:getName(item.id));
    item.OffMode = "NoOverride";
    if (item.name == nil) then item.name = "Unknown"; end
    item.lightType = GetDeviceType( item.id );
    end
    end

    function GetDeviceType(itemId)
    deviceType = fibaro:getType(item.id);
    if ( idIsInList(deviceType, RGBWDeviceType) ) then
    deviceType ="com.fibaro.RGBW";
    elseif ( idIsInList(deviceType, BinaryDeviceType) ) then
    deviceType = "com.fibaro.binarySwitch";
    elseif ( idIsInList(deviceType, DimmerDeviceType ) ) then
    deviceType = "com.fibaro.multilevelSwitch";
    --elseif( ) then
    --deviceType = "Philips.Hue";
    end
    return deviceType;
    end

    --------------------Helper functions--------------------------------

    function CheckLightToBeTurnedOnAgain(lightItem)
    if not (lightItem.OffMode=="ByScene") then return; end

    if (lightItem.lightType == "com.fibaro.multilevelSwitch" ) then
    if (lightItem.currentValue) 0 ) then
    SceneTriggered();
    end
    elseif ( idIsInList( startSourceID, LuxSensorID ) ) then
    StandardDebug( triggerDebug .. " Lux sensor" );
    ExtraDebug( "Lux value changed to: " .. CurrentState.lux );
    if ( CurrentState.motionState > 0 ) then
    SceneTriggered();
    end
    else
    StandardDebug( triggerDebug .. " Light switch" );
    st = lightsStatus( startSourceID );
    if (st == "Unknown") then
    ErrorDebug( "Unknown light trigger" );
    else
    SceneTriggeredByLights( st );
    end
    -- Maybe we can change the light preset to make it more intelligent.
    -- Maybe we can change the Lux preset to make it more intelligent.
    end
    elseif ( startSource["type"] == "global" ) then
    StandardDebug( "Triggered by: " .. "global variable" );
    -- If home status away, we trigger so the current array will be turned off. If motion, turn them on.
    if (CurrentState.homeStatus ~= presentStateMapping.Home) then
    TurnOffLights();
    elseif (CurrentState.motionState > 0 ) then
    SceneTriggered();
    end
    else
    StandardDebug( "Triggered by: " .. startSource["type"] .. " , Not checking the motion state." );
    --Just run the Light Code, not checking for motion. Probably triggered manually.
    if ( startSource["type"] == "other" ) then
    SceneTriggered();
    end
    end

    Debug( "green", "� Smart Lights V" .. version .. " | by Control Living, Finished" );
    Debug( "green", "-------------------------------------------------------" );
    --fibaro:abort(); --otherwise scene will stay alive to long.

    --UPDATE TILL HERE

    [DEBUG] 18:03:43: Home status: home
    [DEBUG] 18:03:43: Motion status: No movement
    [DEBUG] 18:03:43: Triggered by: 236 Motion sensor
    [DEBUG] 18:03:43: � Smart Lights V1.6.7 | by Control Living, Finished
    [DEBUG] 18:03:43: -------------------------------------------------------
    [DEBUG] 18:03:44: Home status: home
    [DEBUG] 18:03:44: Motion status: movement
    [DEBUG] 18:03:44: Triggered by: 236 Motion sensor
    [DEBUG] 18:03:44: Sensor lux: 17 is lower then minValue: 65535
    [DEBUG] 18:03:44: Lights turned: on for day

  • Hallo liebes Forum,
    ich würde die perfekte Lichtsteuerung gerne in einem Raum (Küche) bei mir so anpassen, dass auch wenn die Alarmanlage aktiv ist und die globale Variable auf „away“ gesetzt wurde bei erkannter Bewegung die Lampen in diesem Raum aktiviert werden. Aktuell werden Abwesenheit PresentState = „away“ die Lampen nicht mehr angesteuert werden.
    Vielen Dank für die Unterstützung

  • Hallo zusammen
    Erstmal besten Dank für die echt tolle Arbeit. Funktioniert mit meinem SingelSwitch soweit ich es testen konnte Perfekt.

    Auch wenn dies schon oft gefragt wurde möchte ich nochmals bezüglich Hue einhaken. Im einen Abschnitt wird folgendes beschrieben: "3. Verwenden von virtuellen Modulen mit Slider: {LightID, „VALUE“, „timeInSeconds“, VirtualDeviceSliderID}"

    Müssten sich die Hue Leuchten damit nicht ansteuern lassen? Denn diese können sich ja relativ simpel in als Virtuelles Modul anlegen lassen. Es müsste nur auf den Slider zugegriffen werden können.

    Besten Dank im Voraus und Grüss

  • Hallo,
    ich møchte das, das Licht nicht eingeschaltet wird wenn der Fernsehr an ist.
    Auch das wenn der Fernsehr eingeschaltet wird das Licht aus geht.
    Wie mache ich das am besten?

    MfG
    Rocco

Gib deinen Senf dazu!

Cookie Consent mit Real Cookie Banner