Max_G
(Max G)
November 8, 2020, 5:20am
1
Platform information:
Hardware: Raspberry Pi 3 Model B Rev 1.2_
System: Host: rpi3ohv2 Kernel: 5.4.51-v7+ armv7l bits: 32 Console: tty 2
Distro: Raspbian GNU/Linux 10 (buster)
OpenJDK Runtime Environment (Zulu 8.31.1.122-linux_aarch32hf) (build 1.8.0_181-b122)
Version: 2.5.10 (Build) (apt-get), text-based config
binding = astro,exec,logreader,network,ntp,systeminfo,fritzboxtr0641,expire1,mqtt1,weather1
ui = paper,basic,classic,restdocs
persistence = rrd4j,mapdb
action = mail,mqtt
transformation = map,javascript,xslt,scale,jsonpath
I am trying to evaluate a time calculation w/o success. The rule
rule "Sonoff: Shed_NLO_PIR timer"
when
Item Shed_NLO_PIR received update ON
then
val Integer remainingTimeThreshold = 60 * 1000
if (now.millis - Shed_NLO_PIR_LUP.lastUpdate.millis < remainingTimeThreshold)
{
logInfo("Sonoff.2.05", "Shed_NLO_PIR_LUP now - LUP....: {} sec", now.millis - now.millis - Shed_NLO_PIR_LUP.lastUpdate.millis)
}
… it produces an error:
2020-11-08 15:12:06.369 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Sonoff: Shed_NLO_PIR timer': cannot invoke method public abstract long org.joda.time.ReadableInstant.getMillis() on null
The more I think about this DateTime not being DateTimeType and all, I’d like to ideally convert all to millis() and work with that…0.
The calendar method is deprecated:
val DateTime lup = new DateTime ((Shed_NLO_PIR_LUP.state as DateTimeType).calendar.currentTimeMillis)
According to the docs , this shoudd work:
val Number lup = (Shed_NLO_PIR_LUP.state as DateTimeType).zonedDateTime.timeInMillis
…, but it doesn’t!
It errors with:
2020-11-08 15:36:08.152 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Sonoff: Shed_NLO_PIR timer': 'timeInMillis' is not a member of 'java.time.ZonedDateTime'; line 50, column 26, length 67
Any hints appreciated.
Unfortunately I cannot help in detail, but I hope there is helpful information at DateTime Conversion (openHAB 2.x)
1 Like
5iver
(Scott Rushworth)
November 8, 2020, 10:24am
3
Maybe this would help?
ZonedDateTime … until … ChronoUnit.TemporalUnit …
import java.time.temporal.ChronoUnit
...
val date_1 = Virtual_DateTime_1.getStateAs(DateTimeType).zonedDateTime
val date_2 = Virtual_DateTime_2.getStateAs(DateTimeType).zonedDateTime
val seconds_between = date_1.until(date_2, ChronoUnit.SECONDS)
val minutes_between = date_1.until(date_2, ChronoUnit.MINUTES)
val days_between = date_1.until(date_2, ChronoUnit.DAYS)
val weeks_between = date_1.until(date_2, ChronoUnit.WE…
The use of ZonedDateTime will future proof things for OH3 (no more Joda Time).
import java.time.temporal.ChronoUnit// put this before any rules or global variables
rule "Sonoff: Shed_NLO_PIR timer"
when
Item Shed_NLO_PIR received update ON
then
val remainingTimeThreshold = 60// don't cast unless you absolutely have too
val seconds_since_last_update = (new DateTimeType(Shed_NLO_PIR_LUP.lastUpdate.toString)).zonedDateTime.until((new DateTimeType).zonedDateTime, ChronoUnit.SECONDS)
if (seconds_since_last_update < remainingTimeThreshold) {
logInfo("Sonoff.2.05", "Shed_NLO_PIR_LUP now - LUP....: {} sec", seconds_since_last_update)
}
end
Max_G
(Max G)
November 8, 2020, 11:55am
4
Thanks guys… I should have replied earlier…
I read the link anfeanger provided and found the solution.
This works:
val Number lup = (Shed_NLO_PIR_LUP.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
Final rule (just tested):
rule "Sonoff: Shed_NLO_PIR timer"
when
Item Shed_NLO_PIR_pxy received update ON
then
// setpoint value for initial and subsequent timer durations
val PIR_Duration = (Shed_NLO_PIR_Timeout.state as DecimalType).intValue
// ms when allowing rescheduling the timer before its scheduled end time
val Integer rescheduleThreshold = 60 * 1000
// get the last update time stamp for Shed_NLO_PIR_LUP
val Number lup = (Shed_NLO_PIR_LUP.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
logInfo(logPrefix + "2.01", "Shed_NLO_PIR_LUP now - LUP....: {}", now.millis - lup)
if (Shed_NLO_PIR_Timer === null || Shed_NLO_PIR_Timer.hasTerminated())
{
logInfo(logPrefix + "2.02", "Shed_NLO_PIR..................: ON for {} minutes", PIR_Duration)
Shed_NLO_PIR.postUpdate(ON)
Shed_NLO_PIR_LUP.postUpdate(new DateTimeType())
Shed_NLO_PIR_Timer = createTimer(now.plusMinutes(PIR_Duration), [|
logInfo(logPrefix + "2.03", "Shed_NLO_PIR..................: OFF")
Shed_NLO_PIR.postUpdate(OFF)
Shed_NLO_PIR_LUP.postUpdate(new DateTimeType())
Shed_NLO_PIR_Timer = null
])
}
else
{
/*
logInfo(logPrefix + "2.04", "now.millis....................: {}", now.millis)
logInfo(logPrefix + "2.05", "LUP...........................: {}", lup)
logInfo(logPrefix + "2.06", "Shed_NLO_PIR_LUP now - LUP....: {}", now.millis - lup)
logInfo(logPrefix + "2.07", "rescheduleThreshold...........: {}", rescheduleThreshold)
logInfo(logPrefix + "2.08", "is lup + duration - now < 6000: {}", lup + (PIR_Duration * 60 * 1000) - now.millis)
*/
// allow reschedule within 60 sec before end of timer
if ((lup + (PIR_Duration * 60 * 1000) - now.millis) < rescheduleThreshold)
{
logInfo(logPrefix + "2.09", "if = .........................: true")
logInfo(logPrefix + "2.10", "Shed_NLO_PIR rescheduled......: yes, for {} minutes", PIR_Duration)
Shed_NLO_PIR_Timer.reschedule(now.plusMinutes(PIR_Duration))
Shed_NLO_PIR_LUP.postUpdate(new DateTimeType())
}
}
end