Get Time Period on System Start Failing due to getCalendar()

My bad/apologies, shortly after writing my last response I went off to hospital to have a child :smiley:

Revisiting this now, with a bit more focus and clarity (only a bit mind!), the log shows;

2017-12-10 06:00:01.063 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule ‘Calculate time of day state’: ‘toEpochSecond’ is not a member of ‘org.eclipse.smarthome.core.library.types.DateTimeType’; line 32, column 24, length 51

2 Likes

You will need to use something like (riseStart.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000. I recently added this to the draft release notes…

2 Likes

Thanks @5iver, based on this, I was able to get this working using;

rule "Calculate time of day state"
when
    System started or
	Channel 'astro:sun:local:morningNight#event' triggered END or // Dawn 
    Channel 'astro:sun:local:civilDawn#event' triggered START or  // Morning
	Channel 'astro:sun:local:rise#event' triggered END or // Day
    Channel 'astro:sun:local:civilDusk#event' triggered START or // Twilight
	Channel 'astro:sun:local:civilDusk#event' triggered END or // Evening
	Channel 'astro:sun:local:morningNight#event' triggered START or // Night
	Time cron "0 0 0 * * ? *"
then
  Thread::sleep(1000) // make sure we are a tad past midnight to give Astro a chance to recalculate DateTimes for today

  val long dawn = (DawnStart_Time.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000
  val long morning = (MorningStart_Time.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000
  val long day = (DayStart_Time.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000
  val long twilight = (TwilightStart_Time.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000
  val long evening = (EveningStart_Time.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000
  val long night = (NightStart_Time.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000

  var curr = "UNKNOWN"

  switch now {
        case now.isAfter(dawn) && now.isBefore(morning):		curr = "Dawn"
        case now.isAfter(morning) && now.isBefore(day):     	curr = "Morning"
        case now.isAfter(day) && now.isBefore(twilight):		curr = "Day"
        case now.isAfter(twilight) && now.isBefore(evening):	curr = "Twilight"
        case now.isAfter(evening) && now.isBefore(night):		curr = "Evening"		
        case now.isAfter(night):								curr = "Night"
  }

  if(TimePeriodOfDay.state.toString != curr) {
    logInfo("EXTRA", "Current time of day is now " + curr)
	sendMail("email@ddre.ss", "Time of Day", "It's " + curr)							
    TimePeriodOfDay.sendCommand(curr)
  }
end```
 
and


```php

rule "Dawn Started"
when
	Item Dawn changed to ON or
	Channel 'astro:sun:local:morningNight#event' triggered END or //MorningNight end, signals start of Dawn
	Item TimePeriodOfDay changed to Dawn
then
        logInfo("EXTRA", "Its Dawn: " + now)
		logInfo("EXTRA", "Channel astro:sun:local:morningNight#event triggered END")		
		sendMail("email@ddre.ss", "Time of Day", "Its Dawn: " + now)				
        Dawn.sendCommand(ON)
		Morning.sendCommand(OFF)			
        Day.sendCommand(OFF)
		Twilight.sendCommand(OFF)			
        Evening.sendCommand(OFF)
        Night.sendCommand(OFF)
        TimePeriodOfDay.postUpdate("Dawn")
end

rule "Morning Started"
when
	Item Morning changed to ON or
	Channel 'astro:sun:local:civilDawn#event' triggered START or //Morning, after night, triggered by the start of civilDawn
	Item TimePeriodOfDay changed to Morning
then
		logInfo("EXTRA", "Its Morning: " + now)
		logInfo("EXTRA", "Channel astro:sun:local:civilDawn#event triggered START")		
		sendMail("email@ddre.ss", "Time of Day", "Its Morning: " + now)				
		Dawn.sendCommand(OFF)
		Morning.sendCommand(ON)
		Day.sendCommand(OFF)
		Twilight.sendCommand(OFF)
		Evening.sendCommand(OFF)
		Night.sendCommand(OFF)	
		TimePeriodOfDay.postUpdate("Morning")
end

rule "Day Started"
when
	Item Day changed to ON or
	Channel 'astro:sun:local:rise#event' triggered END or //Sunrise
	Item TimePeriodOfDay changed to Day
then
        logInfo("EXTRA", "Its Day: " + now)
		logInfo("EXTRA", "Channel astro:sun:local:rise#event triggered END")
		sendMail("email@ddre.ss", "Time of Day", "Its Day: " + now)						
        Dawn.sendCommand(OFF)
		Morning.sendCommand(OFF)
        Day.sendCommand(ON)
		Twilight.sendCommand(OFF)			
        Evening.sendCommand(OFF)
        Night.sendCommand(OFF)
        TimePeriodOfDay.postUpdate("Day")
end

rule "Twilight Started"
when
	Item Twilight changed to ON or
	Channel 'astro:sun:local:civilDusk#event' triggered START or //civilDusk with -120 offset, starts to get dark from here
	Item TimePeriodOfDay changed to Twilight	
then
		logInfo("EXTRA", "Its Twilight: " + now)
		logInfo("EXTRA", "Channel astro:sun:local:civilDusk#event triggered START")
		sendMail("email@ddre.ss", "Time of Day", "Its Twilight: " + now)				
		Dawn.sendCommand(OFF)
		Morning.sendCommand(OFF)
		Day.sendCommand(OFF)
		Twilight.sendCommand(ON)
		Evening.sendCommand(OFF)
		Night.sendCommand(OFF)	
		TimePeriodOfDay.postUpdate("Twilight")	
end

rule "Evening started"
when
	Item Evening changed to ON or
	Channel 'astro:sun:local:civilDusk#event' triggered END or //Evening, triggered by civilDusk End
	Item TimePeriodOfDay changed to Evening	
then
        logInfo("EXTRA", "Its Evening: " + now)
		logInfo("EXTRA", "Channel astro:sun:local:set#event triggered START")
		sendMail("email@ddre.ss", "Time of Day", "Its Evening: " + now)				
        Dawn.sendCommand(OFF)
		Morning.sendCommand(OFF)
        Day.sendCommand(OFF)
		Twilight.sendCommand(OFF)		
        Evening.sendCommand(ON)
        Night.sendCommand(OFF)
        TimePeriodOfDay.postUpdate("Evening")
end

rule "Night started"
when
	Item Night changed to ON or
	Channel 'astro:sun:local:morningNight#event' triggered START or //Night, an hour or so before midnight
	Item TimePeriodOfDay changed to Night	
then
        logInfo("EXTRA", "Its Night: " + now)
		logInfo("EXTRA", "Channel astro:sun:local:morningNight#event triggered START")
		sendMail("email@ddre.ss", "Time of Day", "Its Night: " + now)				
		Dawn.sendCommand(OFF)
		Morning.sendCommand(OFF)
        Day.sendCommand(OFF)
		Twilight.sendCommand(OFF)			
        Evening.sendCommand(OFF)
        Night.sendCommand(ON)
        TimePeriodOfDay.postUpdate("Night")
end```
1 Like

You should remove the

* 1000

from the example in the release notes, this was only in Vini´s rule.

I don’t understand what you mean. The * 1000 is needed to convert to milliseconds.

hm, i thought, this was only in this special rule…

I have changed all my rules to the new way without * 1000 and i didn´t see any problems so far.

So the right update of the rule is this?

old:
val dawn = new Date((DawnStart_Time.state as DateTimeType).calendar.timeInMillis)

new:
val dawn = new Date((DawnStart_Time.state as DateTimeType).getZonedDateTime.toEpochSecond * 1000)

What do i get when i don´t use * 1000 ? Is the new thing not in milliseconds? Is this 1/1000 milliseconds?

This is my rule and it works without *1000:

rule "Xiaomi Temp 4 time since"
when
		Time cron "0 * * * * ?"
then
		var Number lastthingy4 = (Xiaomi_Temp_4_last_connection.state as DateTimeType).getZonedDateTime.toEpochSecond
		var Number myminutes4 = ((now.millis - lastthingy4) / 60000)
		Xiaomi_Temp_4_time_since.postUpdate(myminutes4)
end

I get the same results as before with “.calendar.timeInMillis”.

Why???

EDIT:

Strange, now i see it, now after some hours of running the updated rule i see the wrong values.

You are right, i need * 1000 in this rules too.

The .toEpochSecond method returns a Long, which represents the number of seconds since 1970-01-01T00:00:00Z.

https://docs.oracle.com/javase/8/docs/api/java/time/chrono/ChronoLocalDateTime.html#toEpochSecond-java.time.ZoneOffset-

And the old one? Which number did i get with it?

seconds since 1970 too?

The old one (.calendar.timeInMillis) returned milliseconds since the start of the Unix Epoch.

More accurate version was just posted here…

I have the same problem of depreciated, and tried the toEpochSecond suggestion above, which errored and didn’t work.(I’m using OH 2.2 release version).

The depreciated line is the first one, and the second (commented out) is what i tried but was wrong. Can anyone please tell me what I need to use instead? Thanks.

		var DateTime LastTagged = new DateTime((iTagDateTime.state as DateTimeType).calendar.timeInMillis)
//		var DateTime LastTagged = new DateTime((iTagDateTime.state as DateTimeType).toEpochSecond * 1000)

Check the link right above your post.

var DateTime LastTagged = new DateTime((iTagDateTime.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
1 Like

I have it this way:

old:
val lastMillis = (lastTime.state as DateTimeType).calendar.timeInMillis

new:
val lastMillis = (lastTime.state as DateTimeType).getZonedDateTime.toInstant.toEpochMilli

I think you forgot the “get” in “getZonedDateTime”? Or is both working?

thank you 5iver, that worked.

I still have the following few lines of code I need to convert too, if anyone could please say? Thanks.

	val calendar = java.util.Calendar::getInstance
	calendar.timeInMillis = now.millis
	val dtt = new DateTimeType(calendar)

I don´t know what you want to say to me with this???

Is getZonedDateTime also depricated?

Or is it right / wrong? Or are both versions working?

Sorry… this shows that getZonedDateTime is actually derived from zonedDateTime. But they both will work and are equivalent.

1 Like

It looks like you are getting the current time as DateTime, probably to compare to a DateTime item. Try this…

val DateTime dtt = new DateTimeType(now.toString)

hi 5iver,

thanks. It gets used to postUpdate to a datetime item.

This is another area that I’m not the biggest fan of the Xtend language. The short of it is you do not have to provide the “get” part of a call to any method that starts with “get”.

val DateTime dtt = new DateTimeType()

is sufficient. With no parameters it defaults to now.

1 Like