Seite 1 von 1

Licht an solange Bewegung vorhanden in einem Zeitfenster

Verfasst: 8. Feb 2020 21:16
von lukh
Hallo,

ich habe nun schon ganz viele Fragen hier im Forum zum Thema Bewegungsmelder und Lichtsteuerung durchgelesen und habe aus diesen Komponenten mir folgende Rule zusammen gestellt.
Ich habe dazu einige Fragen.

Die Rule soll folgendes machen:

In unterschiedlichen Zeitfenstern am Tage, soll das Licht in unterschiedlichen Dimmstärken einschalten, solange eine Bewegung vorhanden ist.

Ich hatte es erst mit einem Timer probiert. Das Problem ist nur dabei, das das Licht trotzdem ausschaltet, obwohl noch Bewegung im Raum vorhanden ist.

Nun sehen meine Regeln folgendermaßen aus:

Code: Alles auswählen

rule "Licht an im kleinen Flur 22 Uhr bis 6 Uhr"
    when 
        Item RT_KleinerFlur_N27_AlarmMotion received update ON
    then
        if(now.getHourOfDay > 22 && now.getHourOfDay < 24 && now.getHourOfDay > 0 && now.getHourOfDay < 6) {           
            if(LS_KleinerFlur_N33_SwitchDimmer1.state > 0) {
                return;
            }          
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(39)          
        }
end


rule "Licht aus im kleinen Flur 22 Uhr bis 6 Uhr"
    when 
        Item RT_KleinerFlur_N27_AlarmMotion received update OFF
    then
        if(now.getHourOfDay > 22 && now.getHourOfDay < 24 && now.getHourOfDay > 0 && now.getHourOfDay < 6) {  
            if(LS_KleinerFlur_N33_SwitchDimmer1.state == 0) {
                return;
            }
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(0)              
        }
end


rule "Licht an im kleinen Flur 6 Uhr bis 22 Uhr"
    when 
        Item RT_KleinerFlur_N27_AlarmMotion received update ON
    then
        if(now.getHourOfDay > 6 && now.getHourOfDay < 22) {           
            if(LS_KleinerFlur_N33_SwitchDimmer1.state > 0) {
                return;
            }          
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(80)          
        }
end


rule "Licht aus im kleinen Flur 6 Uhr bis 22 Uhr"
    when 
        Item RT_KleinerFlur_N27_AlarmMotion received update OFF
    then
        if(now.getHourOfDay > 6 && now.getHourOfDay < 22) {
            if(LS_KleinerFlur_N33_SwitchDimmer1.state == 0) {
                return;
            }
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(0)              
        }
end
Meine erste Frage zu diesen Regeln wäre, ob man das nicht auch nur in einer Regel zusammenfassen könnte?

Und weiter. Ist es erforderlich, das die Regeln jeweils abgebrochen werden, wenn das Licht schon an ist, bzw. aus ist?
Was wäre, wenn ich diese Abfragen weglassen würde
if(LS_KleinerFlur_N33_SwitchDimmer1.state == 0) {return;} bzw.
if(LS_KleinerFlur_N33_SwitchDimmer1.state > 0) {return;}

Und letzte Frage, kann ich das nicht dennoch mit einem eigenen Timer in der Rule realisieren, denn zurzeit setze ich den Timer in der Konfiguration des Bewegungsmelders?

Re: Licht an solange Bewegung vorhanden in einem Zeitfenster

Verfasst: 9. Feb 2020 10:31
von lukh
Ein Versuch von mir, alles in eine Regel zu bekommen. Leider funktioniert das eben sowenig, wie die Regeln, die ich zuvor benutzt habe :(

Code: Alles auswählen

rule "Licht im kleinen Flur"
    when 
        Item RT_KleinerFlur_N27_AlarmMotion  received command
    then
        switch(receivedCommand.toString) {
            case "ON": {
                if(now.getHourOfDay > 0 && now.getHourOfDay < 6) {           
                    if(LS_KleinerFlur_N33_SwitchDimmer1.state > 0) {
                        return;
                    }          
                    LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(39) 
                } 
                if(now.getHourOfDay > 6 && now.getHourOfDay < 22) {           
                    if(LS_KleinerFlur_N33_SwitchDimmer1.state > 0) {
                        return;
                    }
                    LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(55)  
                }  
            }   
            case "OFF": {
                if(now.getHourOfDay > 0 && now.getHourOfDay < 6) {           
                    if(LS_KleinerFlur_N33_SwitchDimmer1.state == 0) {
                        return;
                    }          
                    LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(0) 
                } 
                if(now.getHourOfDay > 6 && now.getHourOfDay < 22) {           
                    if(LS_KleinerFlur_N33_SwitchDimmer1.state == 0) {
                        return;
                    }
                    LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(0)  
                }  
            }   

        }
           
end
Jemand eine Idee, was falsch sein könnte?
Zumindest bekomme ich keine Fehlermeldung beim Hochladen auf OH. Auch VSC sagt zumindest, das der Syntax in Ordnung ist.

Re: Licht an solange Bewegung vorhanden in einem Zeitfenster

Verfasst: 9. Feb 2020 16:34
von 03chris
Hallo lukh,
ich würde das mit einem Timer lösen:

Code: Alles auswählen

var Timer tSwitchDimmer1 = null

rule "Licht im kleinen Flur"
    when 
        Item RT_KleinerFlur_N27_AlarmMotion  changed to ON  //oder received command ON
    then
        if (tSwitchDimmer1 !== null)
            tSwitchDimmer1.reschedule(now.plusMinutes(3))
        else {
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand( if (now.getHourOfDay > 22 || now.getHourOfDay < 6) 39 else 55)
            tSwitchDimmer1=createTimer(now.plusMinutes(3))[
                LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(0) 
                tSwitchDimmer1 = null
            ]
        }
end

Re: Licht an solange Bewegung vorhanden in einem Zeitfenster

Verfasst: 9. Feb 2020 17:11
von udo1toni
Deine Herangehensweise ist kompliziert. Abgesehen davon stimmen Deine Bedingungen nicht:

Code: Alles auswählen

if(now.getHourOfDay > 22 && now.getHourOfDay < 24 && now.getHourOfDay > 0 && now.getHourOfDay < 6) {
heißt: die Stunde des Tags ist gleichzeitig größer als 22, kleiner als 24, größer als 0 und kleiner als 6. Diese Bedingung ist nie erfüllt. ;)
Abgesehen davon ist der Wertebereich von getHourOfDay 0 bis 23, die eine Bedingung (<24) ist also immer erfüllt. Du möchtest eher eingrenzen auf

Code: Alles auswählen

if(now.getHourOfDay > 21 || now.getHourOfDay < 6)) {
heißt zwischen 22 Uhr und 6 Uhr (entweder Stunde ist größer 21 (also ab 21:59:59 Uhr plus 1 Sekunde) oder Stunde ist kleiner als 6 (also bis 05:59:59 Uhr inklusive)

Aber eigentlich ist es wesentlich einfacher.
Du möchtest zu bestimmten Zeiten einen Sollwert setzen. Definiere dafür ein ungebundenes Item oder alternativ eine Variable (das Item hat den Vorteil, dass Du in der UI den Wert anzeigen kannst). Das setzt Du nun zu den entscheidenden Zeitpunkten:

Code: Alles auswählen

rule "Sollwert Helligkeit 1"
when
    Time cron "0 0 22 * * ?" // täglich 22 Uhr
then
    nSoll.postUpdate(39)
end

rule "Sollwert Helligkeit 2"
when
    Time cron "0 0 6 * * ?" // täglich 6 Uhr
then
    nSoll.postUpdate(80)
end

rule "Licht bei Bewegung"
when
    Item RT_KleinerFlur_N27_AlarmMotion changed
then
    if(RT_KleinerFlur_N27_AlarmMotion.state == ON) {
        if(LS_KleinerFlur_N33_SwitchDimmer1.state != nSoll.state)
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(nSoll.state)
    } else {
        if(LS_KleinerFlur_N33_SwitchDimmer1.state != 0)
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(0)
    }
end
Die beiden ersten Regeln kümmern sich nur um die Helligkeitsstufe, die letzte Rule kümmert sich nur um das Ein-/ und Ausschalten des Lichts.
Soll das Licht per Timer gesteuert werden, kommt es darauf an, wie der Bewegungsmelder signalisiert. Im Zweifel würde ich nur beim Erkennen von keiner Bewegung einen Timer zum Ausschalten starten, das geht aber natürlich nur, wenn das OFF zuverlässig kommt.

Re: Licht an solange Bewegung vorhanden in einem Zeitfenster

Verfasst: 9. Feb 2020 19:54
von lukh
Huiuiuiui, hab gerade meiner Frau erklärt, das ich zu blöd zum Programmieren bin!
Hab Ihr erklärt, das ich hier im Forum meinen Code reingestellt habe, der 3 Seiten lang ist, nicht funktioniert und als Antwort bekomme ich drei Zeilen und die Lampen gehen an. :mrgreen:

Danke an 03cris und udo1toni!

Leider konnte ich Deine Rule nicht testen, 03cris, und bin auch nicht auf eine Lösung bisher gekommen.
VSC gibt folgende Fehlermeldung aus:
The method createTimer(DateTime, (Object)=>Timer) is undefined for the type Timer [Zeile 11]

Code: Alles auswählen

var Timer tSwitchDimmer1 = null

rule "Licht im kleinen Flur"
    when 
        Item RT_KleinerFlur_N27_AlarmMotion  changed to ON  //oder received command ON
    then
        if (tSwitchDimmer1 !== null)
            tSwitchDimmer1.reschedule(now.plusMinutes(3))
        else {
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand( if (now.getHourOfDay > 22 || now.getHourOfDay < 6) 39 else 55)
            tSwitchDimmer1.[color=#FF0000]createTimer[/color](now.plusMinutes(3))[
                LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(0) 
                tSwitchDimmer1 = null
            ]
        }
end
Bei Deiner Regel, udo1toni, bekam ich auch Fehlermeldung, die ich aber lösen konnte.
Das neu erstellte Item nSoll hatte zum Anfang keinen Wert. Mit der Konsole konnte ich erst mal einen zuweisen.
Sonst hätte ich bis 22 Uhr warten müssen.
smarthome:update nSoll 55

Die zweite Fehlermeldung war in Zeile 28
Type mismatch: cannot convert from State to Number

Code: Alles auswählen

rule "Sollwert Helligkeit 1"
when
    Time cron "0 0 22 * * ?" // täglich 22 Uhr
then
    nSoll.postUpdate(39)
end

rule "Sollwert Helligkeit 2"
when
    Time cron "0 0 6 * * ?" // täglich 6 Uhr
then
    nSoll.postUpdate(80)
end

rule "Licht bei Bewegung"
when
    Item RT_KleinerFlur_N27_AlarmMotion changed
then
    if(RT_KleinerFlur_N27_AlarmMotion.state == ON) {
        if(LS_KleinerFlur_N33_SwitchDimmer1.state != nSoll.state)
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand([color=#BF0000]nSoll.state[/color])
    } else {
        if(LS_KleinerFlur_N33_SwitchDimmer1.state != 0)
            LS_KleinerFlur_N33_SwitchDimmer1.sendCommand(0)
    }
end
Da hatte dann ein
nSoll.state as Number
geholfen.

Das Item nSoll habe ich als Number erstellt.
Hätte ich das auch anders erstellen können, so, das keine Fehlermeldung entstanden wäre?

Was mir wirklich gut gefällt, ist die einfache Festlegung der Zeit und den entsprechenden Dimmwerten.
Und vor allem auch, das ein selbsttätiges Einschalten trotzdem dazu führt, das das Licht ausgeschaltet wird, sobald der Bewegungsmelder auf OFF geht. Das kommt dann der Kammer zugute, da wir da noch aus Gewohnheit, den Lichtschalter benutzen.
Dort habe ich keine Regel erstellt, sonder über Associationsgruppen das Licht gesteuert. Hier bleibt das Licht dann an, wenn ich mit dem Schalter das Licht anschalte.

Mich würde noch interessieren, warum mein zweiter Versuch nicht geklappt hat.
Mit receivedCommand und Case.
Ich hatte in dieser Regel gleich zum Anfang einen logInfo-Eintrag gesetzt und nie einen Logeintrag bekommen, wenn der Bewegungsmelder eine Bewegung erkannt hat.
Kann es damit zusammenhängen, das bei einem Bewegungsmelder kein receivedCommand zustande kommt?
Also er empfängt ja keine Kommandos, sondern schaltet einfach nur, oder liegt der Fehler woanders?

Re: Licht an solange Bewegung vorhanden in einem Zeitfenster

Verfasst: 9. Feb 2020 20:05
von Darkwin101

Code: Alles auswählen

tSwitchDimmer1.createTimer(now.plusMinutes(3))
sollte wohl das heissen:

Code: Alles auswählen

tSwitchDimmer1= createTimer(now.plusMinutes(3))

Re: Licht an solange Bewegung vorhanden in einem Zeitfenster

Verfasst: 9. Feb 2020 20:15
von 03chris
Stimmt, mein Fehler. Hab korrigiert.

Re: Licht an solange Bewegung vorhanden in einem Zeitfenster

Verfasst: 9. Feb 2020 20:29
von udo1toni
lukh hat geschrieben: 9. Feb 2020 19:54 Da hatte dann ein
nSoll.state as Number
geholfen.
Ja, typischer Fehler, manchmal muss man einen bestimmten Typ erzwingen, manchmal nicht. da falle ich auch nach Jahren immer mal wieder drauf rein.

Wie der Timer korrekt erzeugt wird, hat ja Darkwin101 schon geschrieben.