Upgrade 2 to 3 strategy/planning

The host operating system has a clock - and a timezone.

The Java sub-system has a clock- and a timezone. When you install Java, it guesses timezone based on OS timezone, unless you tell it different. If you later amend the OS timezone, I do not think it changes Java. This is the clock the logger uses.

openHAB application has a clock and a timezone. When you install OH, it guesses timezone based on Java timezone, unless you tell it different. If you later amend the OH timezone, it does not change Java. If you did have to amend OH, it’s a good clue the Java timezone was not what you wanted.

Don’t forget we still do not know what timezone you think is wanted.


After you see timezone being set to EDT.
What is the output again for the other check I posted earlier ? Do they all show EDT related entries now ?

openhabian seems to use timesyncd instead of ntp. You can use the openhabian-config menu 33 entry to switch it on ( again ).

               Local time: Sun 2021-06-27 10:55:01 EDT
           Universal time: Sun 2021-06-27 14:55:01 UTC
                 RTC time: n/a
                Time zone: America/New_York (EDT, -0400)
System clock synchronized: yes
              NTP service: inactive
          RTC in local TZ: no

openhab-cli console -p habopen env gets:
user.timezone Europe/Berlin

The for any state change:

2021-06-27 16:53:00.968 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'vTimeOfDay' changed from 2021-06-27T10:52:00.961-0400 to 2021-06-27T10:53:00.963-0400```

I just noticed this in the log:
2021-06-27 16:55:01.197 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'ntp:ntp:local' changed from OFFLINE (COMMUNICATION_ERROR): The network connection to the timeserver 0.pool.ntp.org cannot be established -> returning current sytem time instead. to ONLINE

1 Like


To get the Java engine going right timezone, you need to pass extra java options parameter as environment variable for container like this:

I’m sure that this is obvious and how to accomplish it is also obvious…but, not to me.

  • there is a JAVA engine, and I knew OH is written in JAVA
  • there is a way (unknown to me) to pass environment variable to the JAVA engine
  • I have no idea where one defines the environment variable
    (is it in some JAVA environment?) (Is it a system environment variable?)
  • I don’t know if this happens dynamically or a reboot is needed, logout/in, restart OH?

10 minutes of web searching I found some posts here that imply it can be added to start.sh by adding this line to top of the file.

export EXTRA_JAVA_OPTS="-Duser.timezone=America/New_York

But, they all show openhab2 directories.

My system has:

$ cd /
$ find . -iname 'start.sh' 2>/dev/null

Sorry to be so thick headed.

It should be possible to add ( no export in front )


that file is sourced from within start.sh which is at /usr/share/openhab/start.sh.

That file already contains:

EXTRA_JAVA_OPTS="-Xms192m -Xmx320m"

So, I should make it?:

EXTRA_JAVA_OPTS="-Xms192m -Xmx320m -Duser.timezone=America/New_York"

Edit: that appears to be good.


1 Like

There is a lot going on here. It looks like you’ve had help with the timezone issue and the rrd4j issue. But I see two questions unanswered.

Probably but I can’t say for sure. That’s really an InfluxDB question about how to transition storage from one machine to another. Typically one would execute a dump of the database on the old instance and a restore on the other machine. But I haven’t used InfluxDB in quite some time so I can’t comment on more than that.

MapDB is very much still supported but it’s a separate add-on. I don’t think you can reuse the old mapdb files in OH 3. But you are now out much. MapDB only saves the most recent values for each Item.

Thanks for the reply.

the rrd4j appears to be working for my number items I want to persist, though it is apparently using whatever default is configured when it is activated.

At this point I still don’t know what I was persisting in mapdb… But, it is not on the addons website, at least I couldn’t find it yesterday.

So this is much like rrd4j, but can handle more than numbers?

I have the old influxdb .cfg file. and I’m wasn’t putting much into it, so ground zero wouldn’t be much of a problem (done that a lot with this…). But, the Graphana pages would be nice to migrate.

Is it best to install Influx from the openhab tool?

on a different note I saw a reference by you about Joda time in OH3.

I think I get the change to

With the Joda way this is 23:00 (I think)

val night_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(1)

and the equivalent would be:

val night_start = now.withHour(23).withMinute(0).withSecond(0)

Did I get that right?

Default strategies are a new thing in OH 3. For rrd4j it’s persist all supported Items on every change and every minute with restoreOnStartup. To change that you need to create an rrd4j.persist file with a different set of strategies.

Probably. I don’t know everything that it does but suspect it will create the DB user and database for you and if you install be hand you’ll have to do those things manually.

Looks like it should work. However, be careful with daylight savings days. You might convert now to a LocalDateTime which takes those things into account better.

val nighty_start = now.toLocalDateTime().withHour(23)...

Yeah, that makes sense…silly DST…

So I now have a astro thing:


In my old rules I reference:

  System started or // run at system start in case the time changed when OH was offline
  Channel 'astro:sun:home:rise#event'    triggered START or
  Channel 'astro:sun:home:set#event'     triggered START or
  Channel 'astro:sun:minus90:set#event'  triggered START or

I think I need to change this to:

  System started or // run at system start in case the time changed when OH was offline
  Channel 'astro:sun:local:rise#event'    triggered START or
  Channel 'astro:sun:local:set#event'     triggered START or
  Channel 'astro:sun:minus90:set#event'  triggered START or

Am I right in thinking the last line implies I need to add a sun thing called minus90 astro:sun:minus90 with set offset of 90 minutes?

Yes but only if you want to keep things the same. You could also pick on of the other channels on your astro:sun:home Thing, for example nauticalDusk or something like that and apply the offset to that one Channel.

Still debugging…

When the log says there was an error in play-12, I think this is supposed indicate the 12th rule in the file play.rules. In my case the error is being thrown from the 8th rule in the file. (If it was 1 off…I’d say it was a starts at 0 rather than 1 discrepancy…but, a delta of 4 I don’t get.)

Also the error in the log is:

Script execution of rule with UID 'play-12' failed: An error occurred during the script execution: null in play

Not sure how I ma that to a line in the file…

I have a good idea where it is because I’ve added log entries.

It has something to do with changing:

val morning_start = now.withTimeAtStartOfDay.plusDays(1).minusHours(18) 


val morning_start = now.toLocalDateTime().withHour(6).withMinute(0).withSecond(0)

Then subsequently the line:


I’m guessing the return type is different, but not being savy with JAVA, I’ll need to research that.

The major question of this post: is there a better way that adding loginfo() lines to narrow down errors like this?

Just add more and more log statements, perhaps to the point where they are every other line of code if you need to.

But I suspect you should not assume the error is lying to you. Add some logging to that 12th rule and see what that rule is doing. That error usually occurs when trying to use something that is incompatible with the operation you are trying to do. For example, if you cast the state of a Number Item to Number but the Item’s state is actually NULL or UNDEF will make an error like that.

I have worked past that, by, indeed, adding copious log statements.

I’m a bit confused about “now.” at this point.

val morning_start = now.toLocalDateTime().withHour(6).withMinute(0).withSecond(0)

This returns a ZonedDateTIme, right?

val day_start = new DateTimeType(vSunrise_Time.state.toString) 

This returns a ZonedDataTIme, right? vSunrise_Time is a DateTIme Item linked to an Astro thing.

case now.isAfter(morning_start)   && now.isBefore(day_start):       curr = "MORNING"

The error now is that it can’t invoke isAfter on morning_start.

No, you converted it to a LocalDateTime. But that should be compatible with most of the stuff you’d use a ZonedDateTime for. But maybe not because LocalDateTime strips the time zone information out and ZonedDateTime needs the timezone information.

No, that is a DateTimeType you are creating there. And that line is pretty redundant because vSunrise_Time.state already is a DateTimeType. You need a ZonedDateTime (or something compatible like LocalDateTime) to do comparisons like isAfter.

val day_start = (vSunrise_Time.state as DateTimeType).getZonedDateTime

This all looks like snippets from the Time of Day design pattern. Are you aware that I rewrote that code in a way that all you need to do is copy it and configure your Items? No more need to modify any code.

Also, there are several postings near the bottom of the thread that show what needs to change to make the old Rules DSL version work with OH 3.

Yes, that is the case.

I assume you mean this thread: Design Pattern: Time Of Day

That’s pretty much the only one.

In the very near future I’ll be able to distribute it as something that is installable through MainUI. In the mean time it takes some copying and pasting to install and use. But one “installed” all you need to do is create and configure some Items.

You asked a while back in this thread if I had any comments on what could be better in the docs…this is certainly not criticism (I help with the docs and support for another relatively popular opensource app and I also moderate one of it’s social media forums, so, I do get it, it ain’t a cake walk.)

I have now read the thread: Design Pattern: Time Of Day a few times. I grant, not every post and not every word.

To me this is a broad sweeping topic. There is much in the thread that I have no clue if it pertains to implementing the pattern or to what I need/want to do etc. The examples include things that seem superfluous to what I think I need, for example a custom dayset/Trash. I get it is an example/extension of the concept being discussed, but, it might be better handled in a section “Beyond the Basic Implementation” so as not to cloud the early discussion.

For some reason, if there is a graphic with the Concepts section, I can’t see it. It’s just a big empty space.

The Concepts might be modified to include a numbered list of one line each of the steps that need to be implemented to make the pattern work at it’s most basic level. Essentially an overview that allows a reader to determine what of the following voluminous comments may be ignored in the initial setup.

Then it jumps to a Simple Example. For me, because I don’t have the list mentioned in the previous paragraph, what of the things shown I need to do. The reader linked to a github and needs to refer to a later sentence to realize it’s the ephemTimeOfDay.yml. Then I notice a comment in the file that links to how to bootstrap items. Do I need to do that? Where did these items come from…the yml is a bunch rules, right?
(And, side question, once the yml is added, are the Things/channels defined by the yml available to rules written in a .rules file? So, If I put the yml in can my file just refer to vTimeOfDay now?

Then I see Python…that does the same thing the yml does. But, but, but…not clear why. Is it just an option in case I want to use Python?

Then we get Rules DSL. This topic appears to have the definition of the Astro things used in the previous yml and Python. (At least that’s what I’m reading.) Then the rules under this heading proceed to use the OH2 time classes.

Now maybe all this is because there are details I don’t know or understand at the moment, or maybe I just have trouble handling multi-faceted concepts until I’ve internalized all the sub-components. Or, maybe it’s just a galactic size onion and there is just no good way to attack it piecemeal.

At this point, if I do understand any of this: I go to the MainUI (I assume this is what I see from the browser at :8080), go to Rules, add the yml, chuck the rule I’ve got for setting vTimeOfDay, and refer to it (vTimeOfDay) in my .rules file. This can’t be right…hmmm.