Openhab / JavaScript isAfter() isBefore() - Vergleich now() zwischen 2 Daten

meph!sto

Vice Admiral
Registriert
Nov. 2003
Beiträge
6.318
Hi,
ich wende mich an euch, weil ich einfach nicht weiter weiß.
Vorab: ich habe von JavaScript gar keine Ahnung.

Ich prüfe täglich ob das heutige Datum zwischen 2 Vergleichswerte fällt.
Bisher habe ich nur den Monat des Jahres (MdJ, z.B. Mai = 05) als Vergleichsgröße genommen.
Beispiel:
Code:
var MOY = now.getMonthValue
if (MOY >= 4 && MOY <= 10)
    {
        logInfo("heating.rules", "TEST RULE TRIGGERED ; " + now.getMinute.toString)
    }
else
    {
        logInfo("heating.rules", "TEST RULE NOT TRIGGERED")
    }

Funktioniert auch ganz gut. Doch ist das nicht sonderlich schön und nicht sehr flexibel, da Tage gar nicht betrachtet werden.
Anfangs habe ich mit
Code:
var DOM = now.getDayOfMonth
Auch den aktuellen Tag in Betracht gezogen und gehofft ich könnte mir aus MOY und DOM die Daten zusammenbasteln. Funktioniert nur nicht.
Vergleichszeitraum:
START = "15.04"
ENDE = "15.10"

Bsp. für heute (07.05.2022) ergäbe
MOY = 5
DOM = 7
Der 07.05. liegt natürlich zwischen dem 15.04. und dem 15.10., der DOM (= 7) aber nicht.

Nun möchte ich prüfen ob now() zwischen START und ENDE fällt.
mit
Code:
now.isAfter(ZonedDateTime.parse("15-04",DateTimeFormatter.ofPattern("dd-MM")))
klappt das aber leider nicht.

Habt ihr Tipps wie ich das erledigen kann.
Danke !
 
Tipp:
console.log(now):
console.log(ZonedDateTime.parse("15-04",DateTimeFormatter.ofPattern("dd-MM")));

Einfach mal schauen, welche Werte da genau sind.

Und btw: "klappt das aber leider nicht." ist selten eine gute Beschreibung. Gibt es denn Fehlermeldungen?
Warum sprichst du von "now()" und schreibst dann nur "now.isAfter"?
 
Btw:
ZonedDateTime.parse("15-04",DateTimeFormatter.ofPattern("dd-MM"))
ist doch Java, und kein JavaScript, oder liege ich da komplett falsch?

Oder nutzt du js-joda?


OpenHab enthält wohl js-joda, nehme ich an. Ich würde dennoch mal die Ausgaben testen.
 
Danke für die Rückmeldungen.
Ich versuche euch mal mehr Input zu liefern (ich habe von JS,Java etc pp gar keine Ahnung).

Code:
logInfo("heating.rules",now().toString)
if (now.isAfter(ZonedDateTime.parse("15-04",DateTimeFormatter.ofPattern("dd-MM"))))
       {
                logInfo("heating.rules", "TEST RULE TRIGGERED ; " + now.getMinute.toString)
        }
        else
        {
                logInfo("heating.rules", "TEST RULE NOT TRIGGERED")
        }
Fehlermeldung:
Code:
2022-05-07 10:45:00.883 [INFO ] [nhab.core.model.script.heating.rules] - 2022-05-07T10:45:00.881658+02:00[Europe/Berlin]
2022-05-07 10:43:14.899 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'heating-1' failed: The name 'DateTimeFormatter' cannot be resolved to an item or type; line 38, column 46, length 17 in heating

Nachdem ich an den File-Anfang noch ein
Code:
import java.time.format.DateTimeFormatter
gesetzt habe, kommt:
Code:
2022-05-07 10:47:00.076 [INFO ] [nhab.core.model.script.heating.rules] - 2022-05-07T10:47:00.074907+02:00[Europe/Berlin]
2022-05-07 10:47:00.092 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'heating-1' failed: Text '15-04' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {MonthOfYear=4, DayOfMonth=15},ISO of type java.time.format.Parsed in heating

Irgendwas macht er schonmal, nur hier weiß ich 0 weiter.

Edit:

Habe natürlich weiter geforscht und bin (glaub' ich) der Lösung etwas näher gekommen.
Ich hatte das Gefühl dass die Funktion isAfter() immer eine Jahreszahl benötigt hatte.

Variablen:
Code:
var String HEAT_OFF_FROM = "15.04."+now.getYear
var String HEAT_OFF_UNTIL = "15.10."+now.getYear
Aufruf:
Code:
 logInfo("heating.rules",now().toString)
 logInfo("heating.rules",HEAT_OFF_FROM)
 if (now.isAfter(LocalDate.parse(HEAT_OFF_FROM,DateTimeFormatter.ofPattern("dd.MM.yyyy"))))
 {
        logInfo("heating.rules", "TEST RULE TRIGGERED ; " + now.getMinute.toString)
 }
 else
 {
        logInfo("heating.rules", "TEST RULE NOT TRIGGERED")
 }

Ausgabe:
Code:
2022-05-07 11:50:00.436 [INFO ] [nhab.core.model.script.heating.rules] - 2022-05-07T11:50:00.435200+02:00[Europe/Berlin]
2022-05-07 11:50:00.440 [INFO ] [nhab.core.model.script.heating.rules] - 15.04.2022
2022-05-07 11:50:00.447 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'heating-1' failed: An error occurred during the script execution: Could not invoke method: java.time.chrono.ChronoZonedDateTime.isAfter(java.time.chrono.ChronoZonedDateTime) on instance: 2022-05-07T11:50:00.442443+02:00[Europe/Berlin] in heating
 
Zuletzt bearbeitet:
import java.time.format.DateTimeFormatter
Das ist Java-Code... kann der wirklich aus JS heraus genutzt werden?

Scheinbar schon. Sekunde.

Die Meldung sagt doch, dass es kein ZonedDateTIme erzeugen kann. Wie denn auch: Welche Zone meinst du?
Dein Pattern enthält keine Zonen-Information, und dein Datum auch nicht. Stattessen mal LocalDateTIme probieren.


Hier siehst du ein Beispiel für ein Pattern mit Zone und einem Zeitpunkt mit Zone (Beispiel 1):
https://howtodoinjava.com/java/date-time/zoneddatetime-parse/
Nicht, dass du dich dran orientieren sollst, sondern als Begründung, warum es nicht geht.
 
Zuletzt bearbeitet:
Danke für deine Hilfe.
Ich habe (s.o.) statt ZonedDateTime auf "LocalDate" umgestellt: Ergebnis ist oben zu entnehmen.
 
Deine Salami-Taktik ist echt nicht zielführend.

Woher kommt "now" her? Ich habe sowas ja indirekt schon mal gefragt.

"now" ist wieder Zoned... Und deine andere ist halt nicht Zoned. Der Vergleich geht halt nicht.
 
Meine Salami-Taktik ist def. keine Absicht.
Ich versteh' hiervon eben sehr wenig, daher kann ich nur beantworten was meine Hirnzellen verstehen können (und das ist nicht viel).

Was genau meinst du mit "woher" das "now" kommt ?
Das gibt mir doch einfach den aktuellen Zeitstempel zum Zeitpunkt des Aufrufs wieder.

Welche Möglichkeiten habe ich denn nun ?
Das "now" irgendwie in ein nicht-Zoned Format umwurschteln oder meinen Vergleichsstring in ein Zoned-Format bringen ?
 
Poste doch einfach mal mehr Quellcode. Das meine ich mit Salami-Taktik.

und wo wird now definiert? Deklariert/Zugewiesen? Das meine ich mit "wo kommt das her?"
 
Der Quellcode ist innerhalb einer Openhab RULE-Datei.
Ob das etwas Openhab eigenes ist, weiß ich nicht. Kann ich auch nicht einschätzen.
Code:
import java.time.format.DateTimeFormatter
/*
#################################################################################################
#                                       GLOBALS VARIABLES                                       #
#################################################################################################
*/
var Number COMFORT = 20.0|"°C" /* DEFAULT TEMP */
var Number COMFORT_BATH = 20.0|"°C" /* BATHROOM TEMP */
var Number ECO_BATH = 13.0|"°C"
var Number ECO = 13.0|"°C"
var Number MAXTRGTTMP = 14.0|"°C" /* MAX TEMPERATURE THRESHOLD */
var Number SXHRTRGTTMP = 6.0|"°C" /* 6HRS MORNING TEMPERATURE THRESHOLD */
var String HEAT_OFF_FROM = "15.04."+now.getYear
var String HEAT_OFF_UNTIL = "15.10."+now.getYear
/*
#################################################################################################
#                                       TEST RULE                                               #
#################################################################################################
*/

rule "TEST: HEATING RULE."
when
        Time cron "0 * * ? * *"
then
        logInfo("heating.rules",now().toString)
        logInfo("heating.rules",HEAT_OFF_FROM)
        if (now.isAfter(ZonedDateTime.parse(HEAT_OFF_FROM,DateTimeFormatter.ofPattern("dd.MM.yyyy")).withZoneSameInstant(ZoneId.systemDefault()))) //(MOY >= 4 && MOY <= 10 && DOM >= 15)) &>
        {
                logInfo("heating.rules", "TEST RULE TRIGGERED ; " + now.getMinute.toString)
        }
        else
        {
                logInfo("heating.rules", "TEST RULE NOT TRIGGERED")
        }
end

Mehr steht da nicht drin.
Dieses "now" musste ich nirgends definieren, das gab es "out-of-the-box".
 
So kannst du es auch machen, brauchst aber dann wohl noch den import für ZoneId.
import java.time.ZoneId

Wobei nein, das Parsen geht ja immer noch nicht. Würde mal das probieren:
Code:
import java.time.format.DateTimeFormatter
import java.time.ZoneId
import java.time.LocalDateTime
/*
#################################################################################################
#                                       GLOBALS VARIABLES                                       #
#################################################################################################
*/
var Number COMFORT = 20.0|"°C" /* DEFAULT TEMP */
var Number COMFORT_BATH = 20.0|"°C" /* BATHROOM TEMP */
var Number ECO_BATH = 13.0|"°C"
var Number ECO = 13.0|"°C"
var Number MAXTRGTTMP = 14.0|"°C" /* MAX TEMPERATURE THRESHOLD */
var Number SXHRTRGTTMP = 6.0|"°C" /* 6HRS MORNING TEMPERATURE THRESHOLD */
var String HEAT_OFF_FROM = "15.04."+now.getYear
var String HEAT_OFF_UNTIL = "15.10."+now.getYear
/*
#################################################################################################
#                                       TEST RULE                                               #
#################################################################################################
*/

rule "TEST: HEATING RULE."
when
        Time cron "0 * * ? * *"
then
        logInfo("heating.rules",now().toString)
        logInfo("heating.rules",HEAT_OFF_FROM)
        if (now.isAfter(LocalDateTime.parse(HEAT_OFF_FROM,DateTimeFormatter.ofPattern("dd.MM.yyyy")).atZone(ZoneId.systemDefault()))) //(MOY >= 4 && MOY <= 10 && DOM >= 15)) &>
        {
                logInfo("heating.rules", "TEST RULE TRIGGERED ; " + now.getMinute.toString)
        }
        else
        {
                logInfo("heating.rules", "TEST RULE NOT TRIGGERED")
        }
end
 
Zuletzt bearbeitet:
Dieser Code
Code:
import java.time.format.DateTimeFormatter
import java.time.ZoneId
import java.time.LocalDateTime
/*
#################################################################################################
#                                       GLOBALS VARIABLES                                       #
#################################################################################################
*/
var Number COMFORT = 20.0|"°C" /* DEFAULT TEMP */
var Number COMFORT_BATH = 20.0|"°C" /* BATHROOM TEMP */
var Number ECO_BATH = 13.0|"°C"
var Number ECO = 13.0|"°C"
var Number MAXTRGTTMP = 14.0|"°C" /* MAX TEMPERATURE THRESHOLD */
var Number SXHRTRGTTMP = 6.0|"°C" /* 6HRS MORNING TEMPERATURE THRESHOLD */
var String HEAT_OFF_FROM = "15.04."+now.getYear //ZonedDateTime.parse(now.getYear+"-04-15T00:00:00.000Z").withZoneSameInstant(ZoneId.systemDefault())
var String HEAT_OFF_UNTIL = "15.10."+now.getYear
/*
#################################################################################################
#                                       TEST RULE                                               #
#################################################################################################
*/

rule "TEST: HEATING RULE."
when
        Time cron "0 * * ? * *"
then
        logInfo("heating.rules",now().toString)
        logInfo("heating.rules",HEAT_OFF_FROM)
        if (now.isAfter(LocalDateTime.parse(HEAT_OFF_FROM,DateTimeFormatter.ofPattern("dd.MM.yyyy")).atZone(ZoneId.systemDefault()))) //(MOY >= 4 && MOY <= 10 && DOM >= 15)) &&  MOY <= 10))
        {
                logInfo("heating.rules", "TEST RULE TRIGGERED ; " + now.getMinute.toString)
        }
        else
        {
                logInfo("heating.rules", "TEST RULE NOT TRIGGERED")
        }
end
Erzeugt folgende Ausgabe 
[CODE]
2022-05-07 13:06:00.486 [INFO ] [nhab.core.model.script.heating.rules] - 2022-05-07T13:06:00.484757+02:00[Europe/Berlin]
2022-05-07 13:06:00.490 [INFO ] [nhab.core.model.script.heating.rules] - 15.04.2022
2022-05-07 13:06:00.497 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'heating-1' failed: Text '15.04.2022' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: null,ISO resolved to 2022-04-15 of type java.time.format.Parsed in heating

Hilft das weiter ?
Ich bin ratlos
 
Okay, das Parsen muss so aussehen:

Hier wird am 15.10 abgeschaltet:
Code:
import java.time.format.DateTimeFormatter
import java.time.ZoneId
import java.time.LocalDate
...
LocalDate.parse(HEAT_OFF_FROM, DateTimeFormatter.ofPattern("dd.MM.yyyy"))
       .atStartOfDay(ZoneId.systemDefault());

Hier wird erst abgeschaltet, wenn der 15.10. vorbei ist:
Code:
import java.time.format.DateTimeFormatter
import java.time.ZoneId
import java.time.LocalDate
import java.time.LocalTime
...
LocalDate.parse(HEAT_OFF_FROM, DateTimeFormatter.ofPattern("dd.MM.yyyy"))
        .atTime(LocalTime.MAX).atZone(ZoneId.systemDefault());

Weiß nicht genau, welches du haben willst.
 
Zuletzt bearbeitet:
Du bist der Beste, danke ! Hast mich auf den richtigen Weg gebracht :)
Habe nun weitergemacht und bin zu einem (für mich) zufriedenstellenden Ergebnis gekommen:
Folgender Code:
Code:
var String HEAT_OFF_FROM = "04-15" /* APRIL 15TH */
var String HEAT_OFF_UNTIL = "10-15" /* OCTOBER 15TH */
/*
#################################################################################################
#                                       TEST RULE                                               #
#################################################################################################
*/

rule "TEST: HEATING RULE."
when
        Time cron "0 * * ? * *"
then
        logInfo("heating.rules",now().toString)
        logInfo("heating.rules",HEAT_OFF_FROM)
        if (now.isAfter(ZonedDateTime.of(LocalDateTime.parse(now.getYear+"-"+HEAT_OFF_FROM+"T00:00"),ZoneId.systemDefault())) && now.isBefore(ZonedDateTime.of(LocalDateTime.parse(now.getYear+"-"+HEAT_OFF_UNTIL+"T00:00"),ZoneId.systemDefault())) )
        {
                logInfo("heating.rules", "TEST RULE TRIGGERED ; " + now.getMinute.toString)
        }
        else
        {
                logInfo("heating.rules", "TEST RULE NOT TRIGGERED")
        }

Ergibt folgende Ausgabe:
Code:
2022-05-07 13:47:00.872 [INFO ] [nhab.core.model.script.heating.rules] - 2022-05-07T13:47:00.871157+02:00[Europe/Berlin]
2022-05-07 13:47:00.877 [INFO ] [nhab.core.model.script.heating.rules] - 04-15
2022-05-07 13:47:00.893 [INFO ] [nhab.core.model.script.heating.rules] - TEST RULE TRIGGERED ; 47

Genau wie erhofft.
 
  • Gefällt mir
Reaktionen: tollertyp
Zurück
Oben