Seite 2 von 2

Re: Regel Flurpräsenzmelder soll Licht_1 nicht zwichen 24:00 und 07:00 schalten, nur Licht_2 schalten.

Verfasst: 11. Dez 2018 13:40
von udo1toni
Man könnte natürlich auch mit getMinuteOfHour arbeiten, aber man muss halt bedenken, dass diese Bedgingung nur für die letzte Stunde gilt. Entsprechend sähe die korrekte Lösung so aus:

Code: Alles auswählen

if((now.getHourOfDay > 0 && now.getHourOfDay < 6) || (now.getHourOfDay = 6 && now.getMinuteOfHour < 31))
Es sind also drei logische Verknüpfungen mit Klammerung und vier Methoden notwendig. Die andere Variante mag nicht so eingängig sein ;) ist aber wesentlich schneller und effizienter.
Man kann übrigens den Term 6*60+31 auch direkt (sicherheitshalber in Klammern) in das if-Statement schreiben, das ist dann etwas besser lesbar, und natürlich kann man auch für den vorderen Wert die Minute berücksichtigen:

Code: Alles auswählen

if(now.getMinuteOfDay > (0*60 + 59) && now.getMinuteOfDay < (6 * 60 + 31))

Re: Regel Flurpräsenzmelder soll Licht_1 nicht zwichen 24:00 und 07:00 schalten, nur Licht_2 schalten.

Verfasst: 21. Aug 2019 19:55
von Baha77
Nach dem Umstieg auf Openhab 2.4 und das KNX Binding 2, habe ich mit Schwierigkeiten alles umgestellt bekommen. Leider bis auf diese eine Regel.

Code: Alles auswählen

  rule "LED Flur Licht nur von 00:00- 07:00"
when
    Item floor_Praezenzmelder1 received command
then
    if (receivedCommand == ON) {                  // Schaltbefehl ON
        if (now.getHourOfDay > 0  && now.getMinuteOfDay < 276) // 391 = 6 * 60 + 31
            floor_Led_kl_Treppe.sendCommand(ON)
        else                                      // zwischen 7 und 1 (gemeint ist 24) Uhr
            floor_Led_2Etage.sendCommand(ON)
            floor_Led_kl_Treppe.sendCommand(ON)
    } 
    
    else {                                      // Schaltbefehl OFF
    
   
    
        floor_Led_kl_Treppe.sendCommand(OFF)
        floor_Led_2Etage.sendCommand(OFF)
    }

    end

Code: Alles auswählen

Type switch			 : floor_Praezenzmelder1	 "Light"					  [ ga="0/7/5+<0/7/5 "]	

Code: Alles auswählen

2019-08-20 08:00:45.349 [vent.ItemStateChangedEvent] - floor_Praezenzmelder1 changed from ON to OFF
2019-08-20 08:01:39.697 [vent.ItemStateChangedEvent] - floor_Praezenzmelder1 changed from OFF to ON

Re: Regel Flurpräsenzmelder soll Licht_1 nicht zwichen 24:00 und 07:00 schalten, nur Licht_2 schalten.

Verfasst: 21. Aug 2019 22:45
von peter-pan
Wie wär's mit dieser Möglichkeit:

Code: Alles auswählen

       if ((now.withTimeAtStartOfDay.plusHours(22)).toString("HHmm") <= now().toString("HHmm")  && (now.withTimeAtStartOfDay.plusHours(23)).toString("HHmm") >= now().toString("HHmm")) {
           logInfo("Datum/Zeit test","Na geht doch")

Du musst nur die beiden Werte ersetzen. 22 = 0 und 23 = 7

Du kannst auch noch erweitern .plusDays(1), .plusMinutes(1) , plusSeconds(1). Das Ganze geht auch mit .minusDays, etc.

Re: Regel Flurpräsenzmelder soll Licht_1 nicht zwichen 24:00 und 07:00 schalten, nur Licht_2 schalten.

Verfasst: 22. Aug 2019 16:57
von udo1toni
Ich verstehe jetzt nicht, was Du mit "funktioniert nicht" meinst. Der Präsenzmelder meldet ON und OFF, und zwar 24 Stunden täglich. Im Zeitraum von 1 Uhr bis 4:35 (4*60 + 35 = 275) soll die Rule dann nur eine der Lampen schalten, ansonsten beide. Da ist ein fetter Fehler drin, denn Du möchtest zwei Items unter dem else stehen haben, hast aber keine geschweiften Klammern drum herum.
Nochmal zur Erläuterung: bedingte Verzweigungen wirken immer nur auf den nächsten Befehl. Wenn mehrere Befehle hintereinander bedingt ausgeführt werden sollen, musst Du einen Codeblock bilden, mit den geschweiften Klammern.

Code: Alles auswählen

  rule "LED Flur Licht nur von 00:00- 07:00"
when
    Item floor_Praezenzmelder1 received command
then
    if (receivedCommand == ON) {                  // Schaltbefehl ON
        if (now.getHourOfDay > 0  && now.getMinuteOfDay < (4*60 +36)) 
            floor_Led_kl_Treppe.sendCommand(ON)           // nur ein Befehl, deswegen braucht es keine Klammern
        else {                                     // zwischen 7 und 1 (gemeint ist 24) Uhr
            floor_Led_2Etage.sendCommand(ON)                // zwei Befehle, deshalb Klammern
            floor_Led_kl_Treppe.sendCommand(ON)
        }
    } else {                                      // Schaltbefehl OFF 
        floor_Led_kl_Treppe.sendCommand(OFF)             // hier ist es richtig
        floor_Led_2Etage.sendCommand(OFF)
    }
end

Re: Regel Flurpräsenzmelder soll Licht_1 nicht zwichen 24:00 und 07:00 schalten, nur Licht_2 schalten.

Verfasst: 22. Aug 2019 20:25
von peter-pan
Uuups!!! Sorry habe versucht an der falschen Schraube zu drehen :oops: und dabei den eigentlichen Fehler gar nicht gesehen. "Asche über mein Haupt" :roll:
Ich hätte trotzdem noch zwei Vorschläge für die innere If-Clause:

Code: Alles auswählen

     if (now.withTimeAtStartOfDay.plusHours(22).getHourOfDay >= 22  && now.withTimeAtStartOfDay.plusHours(23).getHourOfDay <= 23) {
         logInfo("Datum/Zeit test","Na geht doch oder auch nicht")
     }
 
oder noch besser bzw. globaler

Code: Alles auswählen

     var Number min = 22
     var Number max = 23

     if (now.withTimeAtStartOfDay.plusHours(min).getHourOfDay >= min  && now.withTimeAtStartOfDay.plusHours(max).getHourOfDay <= max) {
         logInfo("Datum/Zeit test","und es geht doch")
     }
	

Re: Regel Flurpräsenzmelder soll Licht_1 nicht zwichen 24:00 und 07:00 schalten, nur Licht_2 schalten.

Verfasst: 23. Aug 2019 12:35
von udo1toni
Nörgel, Nörgel...

Code: Alles auswählen

     if (now.withTimeAtStartOfDay.plusHours(22).getHourOfDay >= 22  && now.withTimeAtStartOfDay.plusHours(23).getHourOfDay <= 23) {
         logInfo("Datum/Zeit test","Na geht doch oder auch nicht")
     }
 
Beide Bedingungen sind immer erfüllt, denn now.withTimeAtStartOfDay liefert für das aktuelle Datum 0 Uhr zurück .plusHours(22) zählt 22 Stunden dazu, das Resultat ist also immer 22 Uhr für den aktuellen Tag. .getHourOfDay wird dann immer 22 liefern. Für den anderen Vergleich gilt das selbe, nur dass hier immer 23 geliefert wird. Man könnte stattdessen auch

Code: Alles auswählen

if(true)
schreiben ;)

Man kann mit

Code: Alles auswählen

if(now.isAfter(some DateTimeType) && now.isBefore(some other DateTimeType))
auch einen Zeitraum abfragen, aber ob das nun eleganter ist? könnte man einfach die Uhrzeit hinschreiben, im Klartext, würde ich mir das ja gefallen lassen, aber so einfach ist das eben nicht. Deshalb bevorzuge ich .getMinuteOfDay (man könnte auch problemlos sekundengenau mit .getSecondOfDay arbeiten) das liefert int zurück, damit kenne ich mich aus ;)

Re: Regel Flurpräsenzmelder soll Licht_1 nicht zwichen 24:00 und 07:00 schalten, nur Licht_2 schalten.

Verfasst: 23. Aug 2019 14:17
von peter-pan
Nix Nörgel, Nörgel ;) . Sachliche Kritik hat noch keinem geschadet (auch und vor allem mir nicht :oops: ). Ich bin halt ein Dummy ;) , aber ich versuche zu lernen

Ich dachte nur, wenn man 22 = 0 und 23 = 7 setzt bzw. min = 0 und max = 7 müsste es doch klappen, aber da haben sich meine Synapsen wohl nicht richtig verbunden :? .

Was hältst du denn davon ? (noch'n Versuch :lol: )

Code: Alles auswählen

     var Number min = 13
     var Number max = 15

     if (now.withTimeAtStartOfDay.plusHours(min).getHourOfDay <= now().getHourOfDay  && now.withTimeAtStartOfDay.plusHours(max).getHourOfDay > now.getHourOfDay()) {
         logInfo("Datum/Zeit test","wie wär's damit")
     }
 
Natürlich geht es auch noch weiter mit Minuten und so, aber für den Anfang :?:

Re: Regel Flurpräsenzmelder soll Licht_1 nicht zwichen 24:00 und 07:00 schalten, nur Licht_2 schalten.

Verfasst: 24. Aug 2019 07:45
von udo1toni
Na ja, so funktioniert es wenigstens, aber ganz ehrlich, wie kompliziert willst Du es denn noch machen? ;)

Code: Alles auswählen

now.withTimeAtStartOfDay.plusHours(min).getHourOfDay
ist perDefinition immer gleich min, das gleiche gilt entsprechend für den max-Ausdruck, Du kannst also stattdessen schreiben

Code: Alles auswählen

if(min <= now().getHourOfDay  && max > now.getHourOfDay)
was (bis auf die Vertauschungen) meinem Code entspricht.

Ich denke, was Du meinst, ist folgendes Konstrukt:

Code: Alles auswählen

if(now.isAfter(now.withTimeAtStartOfDay.plusHours(6).plusMinutes(30).plusSeconds(15)) && now.isBefore(now.withTimeAtStartOfDay.plusHours(18).plusMinutes(45).plusSeconds(35)))
Ich hab ein Gegenbeispiel:

Code: Alles auswählen

if(now.minusHours(6).getHourOfDay < 16)
trifft auf den Zeitraum zwischen 6 Uhr und 22 Uhr zu. das heißt, man kommt ohne die und-Verknüpfung aus. Funktioniert natürlich genauso auch minutengenau oder gar sekundengenau.
Rules werden bei ihrer ersten Ausführung compiliert, das bedeutet das aus einem statischen Ausdruck wie z.B.

Code: Alles auswählen

if(now.getSecondOfDay > 6*60*60+30*60+15 && now.getSecondOfDay < 18*60*60+45*60+35)
dieser Ausdruck wird:

Code: Alles auswählen

if(now.getSecondOfDay > 23415 && now.getSecondOfDay < 67535)
In der Rule steht aber immer noch der Term, aus dem man leicht ersehen kann, dass die Bedingung zwischen 06:30:15 und 18:45:35 (exklusive) gültig ist.
Wahlweise kann man natürlich auch statt 60*60 gleich 3600 schreiben, und ein kleiner Kommentar an der Seite hilft, sich später daran zu erinnern, was man da rechnet.

Re: Regel Flurpräsenzmelder soll Licht_1 nicht zwichen 24:00 und 07:00 schalten, nur Licht_2 schalten.

Verfasst: 24. Aug 2019 13:37
von peter-pan
...du bist einfach Klasse