OH2: add hours to DateTime (time zone conversation)

OHv2.latest on rPi3

I have an item updated with a UTC timestamp and like to have it show in local time, which is +1000

DateTime TeslaM3_since	"Last status change [%1$td/%1$tm %1$tH:%1$tM:%1$tS]"	<calendar2>	(gTeslaM3)	{mqtt="<[mymosquitto:teslamate/cars/1/since:state:default]"}

Which is the most straight forward way to achieve this in a rule or js transform?

I have seen similar queries, but solutions related to OHv1; writing rules every once in a year is also not conducive to find solutions. :frowning:

Have you tried just displaying it? openHAB frameworknormally converts to local timezone on display.

If that does not give you what you expect, it’s probably because you update your Item with no timezone given. The framework will assume that is local time.
Maybe you need to append text “+0000” to your update to declare it as UTC.

On the risk of sounding stupid: where do I add the +0000?

The item DateTime TeslaM3_since gets the date-time as a string {mqtt="<[mymosquitto:teslamate/cars/1/since:state:default]"}

I assume OH does not know which timezone it is given/assumed… which is what you seem to be eluding to.

I read the link you provided, but I am lost… it implies I need to work with a rule?!

I just noticed that the item has +1000 attached to it (when I hover over the item in VScode). But this is actually +0000. I want it to display plus 10 hours (which is my local time).

OH can only know if you tell it. Otherwise it will reasonably assume ‘local’ time. So it all depends on the mystery string that you are feeding in via MQTT, which is invisible to us here.

If you need to add a timezone on the end, that’s just string manipulation. I can’t recall how to do with OH1.x syntax, but I think you’re just looking to use REGEX to add a fixed string onto your input in the binding configuration.

OK, I read all the linked posts, w/o finding a solution.

I also tried the REGEX w/o luck… but think this is the way to add the +0000 to the MQTT message, which looks like this 2021-10-26T23:46:12.040463Z

This is not shown in local time, which is what I’d like to achieve.

Maybe the ‘Z’ at the end is unexpected and should be +0000 instead?

I have tried:
{mqtt="<[mymosquitto:teslamate/cars/1/since:state:REGEX(s/Z/+0000/g)]"}

But then get Regex errors, due to Regex not installed:

021-11-02 12:34:43.924 [ERROR] [core.karaf.internal.FeatureInstaller] - Failed installing 'openhab-transformation-regex': Error:
	Error downloading mvn:org.openhab.ui.bundles/org.openhab.ui.paper/[2.5.0,2.6)

So I gave up on this approach, using a rule instead.
with the help of this post:

I arrived at this rule:

rule "Convert UTC timestamp to local date-time"
    when
        Item TeslaM3_since changed
    then
        var Number EpochFromDateTime = (TeslaM3_since.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
        EpochFromDateTime = EpochFromDateTime + (10 * 60 * 60 * 1000)
        val DateTimeType MyDateTimeFromEpoch = new DateTimeType(new DateTime(EpochFromDateTime).toString)
        TeslaM3_since.postUpdate(MyDateTimeFromEpoch)
        logInfo(logPrefix + "1.01", "Updated time stamp")
end

However, it raised this error:

2021-11-02 14:25:00.109 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Convert UTC timestamp to local date-time': No instant converter found for type: java.math.BigDecimal

I am really peeved… what an effort to add four zeros and a plus sign to a MQTT string to get the proper timestamp. :nauseated_face:

[edit1]
added log entries to rule:

rule "Convert UTC timestamp to local date-time"
    when
        Item TeslaM3_since changed or
		//         s m h D M DoW Y
		Time cron "0 0/5 * * * ?"
		// here: 10 seconds past midnight; use http://www.cronmaker.com/
    then
        var Number EpochFromDateTime = (TeslaM3_since.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
        logInfo(logPrefix + "1.01", "Updated time stamp")
        EpochFromDateTime = EpochFromDateTime + (10 * 60 * 60 * 1000)
        logInfo(logPrefix + "1.02", "Updated time stamp")
        val DateTimeType MyDateTimeFromEpoch = new DateTimeType(new DateTime(EpochFromDateTime).toString)
        logInfo(logPrefix + "1.03", "Updated time stamp")
        TeslaM3_since.postUpdate(MyDateTimeFromEpoch)
        logInfo(logPrefix + "1.04", "Updated time stamp")
end

result…

2021-11-02 14:39:43.761 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'tesla.rules'
2021-11-02 14:39:49.982 [INFO ] [.smarthome.model.script.TeslaM3.0.01] - System Start: Tesla rules
2021-11-02 14:40:00.013 [INFO ] [.smarthome.model.script.TeslaM3.1.01] - Updated time stamp
2021-11-02 14:40:00.022 [INFO ] [.smarthome.model.script.TeslaM3.1.02] - Updated time stamp
2021-11-02 14:40:00.025 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Convert UTC timestamp to local date-time': No instant converter found for type: java.math.BigDecimal

The rule is now:

rule "Convert UTC timestamp to local date-time"
    when
        Item TeslaM3_since changed
    then
        val tzDiff = (10 * 60 * 60 * 1000)
        val Number EpochFromDateTime = (TeslaM3_since.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
        logInfo(logPrefix + "1.01", "EpochFromDateTime.......: {}", EpochFromDateTime)
        logInfo(logPrefix + "1.01", "tzDiff..................: {}", tzDiff)

        UpdatedEpochFromDateTime = EpochFromDateTime + tzDiff
        logInfo(logPrefix + "1.02", "UpdatedEpochFromDateTime: {}", UpdatedEpochFromDateTime)

        //val DateTimeType DateTimeFromEpoch = new DateTimeType(new DateTime(EpochFromDateTime).toString)
        val DateTimeFromEpoch = new DateTimeType(UpdatedEpochFromDateTime)
        logInfo(logPrefix + "1.03", "Updated time stamp")

        TeslaM3_since.postUpdate(DateTimeFromEpoch)
        logInfo(logPrefix + "1.04", "Updated time stamp")
end

going by this post:

but it results in:

2021-11-02 17:06:29.078 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'tesla.rules'
2021-11-02 17:06:35.524 [INFO ] [.smarthome.model.script.TeslaM3.0.01] - System Start: Tesla rules
2021-11-02 17:09:00.013 [INFO ] [.smarthome.model.script.TeslaM3.1.01] - EpochFromDateTime.......: 1635778427000
2021-11-02 17:09:00.017 [INFO ] [.smarthome.model.script.TeslaM3.1.01] - tzDiff..................: 36000000
2021-11-02 17:09:00.020 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Convert UTC timestamp to local date-time': An error occurred during the script execution: Couldn't invoke 'assignValueTo' for feature JvmVoid:  (eProxyURI: tesla.rules#|::0.2.1.2.0.4::0::/1)

… spent hours on this one time conversion… :frowning:

Well, I ended up with a work-around.
I created a proxy item TeslaM3_status_changed_since and update it with now() when TeslaM3_since changed.

Works.

A caution, unrelated to your time troubles; the remote repository for OH2 has changed. Which means an existing set-up will not be able to add new features. Worse, in the case of some minor disaster OH2 could attempt to refresh all add-ons. Then you will be in deep trouble, because it can’t.

If I were you I’d get ahead of that disaster before it bites you

Okay, that’s good. This is in ISO8601 format which is accepted to update an openHAB Datetime Item.
The Z at the end instructs openHAB that this timestamp is in UTC.

What I would expect to happen here -
OH Item state holds the UTC value (from MQTT)
So that’s what you see in logs, rules etc. together with the Z 0000 zone.

But when you display via sitemap, OH framework autoconverts to local timezone before formatting.
So if your local zone was +1 you’d see 00:46 in Basic UI

which should all do as you asked here, without further work.

Thanks… what I have right now is the least elegant solution, but it works.

The UTC timestamp via MQTT is displayed as UTC and not corrected for local time (here +1000). The type conversions always did my head in, and based on my post, I am copying other solutions and hope they work for me.
I tried a few things, which did not work, as in throwing errors.

Given the work-around I have (time is not critical to the second or minute for my purpose) is providing a sufficient result.

Thanks for the hint on the OH repository… I will leave the paperUI alone, rarely work in karaf, hence, so far so good.

I will eventually set up a new OH3 environment, and recreate my 961 items plus associated rules.

To verify this in an OH2 instance …

Items

DateTime testtimeA "test time A [%s]"
DateTime testtimeB "test time B [%s]"

test rule to post updates

// post UTC in ISO8601
testtimeA.postUpdate("2021-10-26T23:46:12.040463Z")
// post some offset zone
testtimeB.postUpdate("2021-10-26T23:46:12.040463+10:00")

As expected, the datetime with zone is stored in Item state

2021-11-02 22:32:36.837 [vent.ItemStateChangedEvent] - testtimeA changed from NULL to 2021-10-26T23:46:12.040463+0000
2021-11-02 22:32:36.839 [vent.ItemStateChangedEvent] - testtimeB changed from NULL to 2021-10-26T23:46:12.040463+1000

So we got A in UTC and B in Vladivostok time :smiley:
But we don’t care about that, want them displayed in local time

Now to the sitemap…
(to show both default and formatted times)

		Text item=testtimeA
		Text item=testtimeA label="A hh mm [%1$tH:%1$tM]"
		Text item=testtimeB
		Text item=testtimeB label="B hh mm [%1$tH:%1$tM]"

and visible result in BasicUI

where we can see in action “Never mind the stored timezone, display in local time

You might get different results in non-sitemap UI like HABpanel, I’ve no idea.


Now here’s a funny thing … despite the BasicUI display for +01:00 I am actually today in +00:00 UK time - we changed a couple of days ago. Looks like some legacy of summer time, even though OH2 has been rebooted since.
This is going to be a Java thing - raises the important point, I’m sure the local timezone used for display will be taken from Java locale, which may be different to openHAB settings. Unless it’s being really clever, and using browser locale?!
I’d never have noticed this other than doing the default display; my logging stamps, ‘now’ in rules etc. are all correct for +00:00 GMT

Try a default unformatted display of your DateTime, find out what OH thinks is your ‘local’.

1 Like