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