How to get time since last update of an item?

Hi,
i have some items, which show me the datetime of the last update of the item.

Is there a way to show the timespan instead of the absolute time?

Now i get:

last update: 22.02.2017 / 11:20

And i want to have:

last Update: 23 minutes ago

This is my current rule:

rule "Xiaomi Temp-Sensoren State Changed"
when
		Item gXiaomiTemp received update // NOTE: the rule will trigger multiple times per event
then
		Thread::sleep(500) // give persistence time to catch up
		val haveHistory = gXiaomiTemp.members.filter[c|c.lastUpdate("mapdb") != null]
		val mostRecent = haveHistory.sortBy[lastUpdate("mapdb")].last
		if(mostRecent == null) logError("Test", "Failed to find most recent")
		else if(mostRecent.state != null){
				val dt = gXiaomiZeit.members.filter[dt|dt.name == mostRecent.name+"_last_connection").head
				if(dt == null) logError("Test", "Failed to find " + mostRecent.name+"_last_connection")
				else dt.postUpdate(new DateTimeType)
		}
end

Hm, i looked into your linked post, but there i only can get hardcoded time differences, maybe:

if 30 minutes gone since last update then do xxxxx

But not a continous counting of the time since the last event?

This part

var long last_change    = now.millis

rule "duration"
when
    Item item_which_duration_you_want_to_measure changed
then
    //duration as Number in minutes
    var Number min    = ((now.millis - last_change) / 60000)

shows a method to do what you asked, show the time since some previous event.
You can of course change it to use a DateTime Item instead of a variable, another post in the same thread shows how to get millis from that.

If you want an updating display, trigger a rule like that with cron every minute?

2 Likes

Oh, now i can see. It was my fault. If i only trigger the state of the item, it would not make sense… But with cronjob (every minute) it probably would work. I´ll give it a try.

Thanks for your help.

Sorry, but i don´t understand the rule…

I have an item with a value and i have a datetime-item with the time of the last change.

number item1
datetime item1_last_change

What do i have to change in the rule from your example?

The rule declares var long last_change —> when does the rule do this? What time is now.millis? Do i have to use a second rule which sets now.millis when the my item1 gets a new update?

now.millis represents the time now, in milliseconds. It’s just a single big number, a convenient way to represent date-times when you want to compare them. Which you do.
Every time you use now.millis, the result changes - it represents now when you use it.

If you want to compare it with some datetime Item that you previously stored (which you do), then you want to convert that previously stored datetime to the millis format too.

var Number lastthingy = (somedatetimeitem.state as DateTimeType).calendar.timeInMillis

Now you can do sums or comparisons

var number someperiod = now.millis - lastthingy

variable someperiod is in milliseconds, you can convert that to more common units with more arithmetic

var Number myminutes    = someperiod  / 60000)

That works great!

It is very simple, if someone explains the lines of the rule…


Can you help my with another datetime-problem too?

I have following lines in one of my rule:

        var SimpleDateFormat df = new SimpleDateFormat( "dd.MM., HH:mm" ) 
        var String timestamp = df.format( new Date() )

So i get the current time at execution of the rule into the var timestamp.

What do i have to do, when i want to get a time from a datetime-item into the var? The datetime-item is also stored in mapdb, if this would help.

And i need the var in a given format (HH:mm …) like the timestamp in my example above.

Since i switched to snapshot OH2 2.1 the rule doesn´t work anymore.

With OH2 stable 2.0 i got the minutes since last update. New updates about every 50 minutes. But since snapshot 2.1 the minutes are getting bigger and bigger and don´t come to 0 after an update.

Is there a change in snapshot version? What do i have to change to get the rule working again?

rule "Xiaomi Temp 1 time since"
when
        Time cron "0 * * * * ?"
then
        var Number lastthingy1 = (Xiaomi_Temp_1_last_connection.state as DateTimeType).calendar.timeInMillis
        var Number myminutes1 = ((now.millis - lastthingy1) / 60000)
        Xiaomi_Temp_1_time_since.postUpdate(myminutes1)
end

There are probably many changes in a snapshot version.
Have you considered the root cause may be Item Xiaomi_Temp_1_last_connection not actually getting updated when you expect? The period would grow and grow …

I have this item shown in my sitemap too. And there i can still see the right time of the last update. The time is never older then 50 minutes.

I made some logging:

rule "Xiaomi Temp 1 time since"
when
        Time cron "0 * * * * ?"
then
        logInfo("RULES", "Xiaomi Temp 1 - new minute - state: " + Xiaomi_Temp_1_last_connection.state as DateTimeType)
        var Number lastthingy1 = (Xiaomi_Temp_1_last_connection.state as DateTimeType).calendar.timeInMillis
        logInfo("RULES", "Xiaomi Temp 1 - new minute - state: " + lastthingy1)
        var Number myminutes1 = ((now.millis - lastthingy1) / 60000)
        logInfo("RULES", "Xiaomi Temp 1 - new minute - state: " + now.millis)
        logInfo("RULES", "Xiaomi Temp 1 - new minute - state: " + myminutes1)
        Xiaomi_Temp_1_time_since.postUpdate(myminutes1)
end
2017-03-05 00:07:00.528 [INFO ] [eclipse.smarthome.model.script.RULES] - Xiaomi Temp 1 - new minute - state: 2017-03-03T11:02:25.990+0100
2017-03-05 00:07:00.528 [INFO ] [eclipse.smarthome.model.script.RULES] - Xiaomi Temp 1 - new minute - state: 1488535345990
2017-03-05 00:07:00.529 [INFO ] [eclipse.smarthome.model.script.RULES] - Xiaomi Temp 1 - new minute - state: 1488668820529
2017-03-05 00:07:00.529 [INFO ] [eclipse.smarthome.model.script.RULES] - Xiaomi Temp 1 - new minute - state: 2224.57563333

Maybe this is helpful?

I can see the first date is still the date from 2 days ago… I have to check this, because it is shown in sitemap with the right date. I think i have two items which should show the same time (for testing), and one of them is not working properly…

That’s two days old … what Item is on your sitemap?
Ah, you’ve seen it.

This is my rule for the last time when an item changed, it worked with 2.0 stable:

rule "Xiaomi Temp-Sensoren State Changed"
when
        Item gXiaomiTemp received update // NOTE: the rule will trigger multiple times per event
then
        Thread::sleep(500) // give persistence time to catch up
        val haveHistory = gXiaomiTemp.members.filter[c|c.lastUpdate("mapdb") != null]
        val mostRecent = haveHistory.sortBy[lastUpdate("mapdb")].last
        if(mostRecent == null) logError("XiaomiTemp", "Failed to find most recent")
        else if(mostRecent.state != null){
                val dt = gXiaomiZeit.members.filter[dt|dt.name == mostRecent.name+"_last_connection"].head
                if(dt == null) logError("XiaomiTemp", "null Failed to find " + mostRecent.name+"_last_connection")
                else dt.postUpdate(new DateTimeType)
        }
end

What Item were you seeing on sitemap?
Add logInfo to see what gets upfated, maybe not what you expect.
As you are relying on persistence to update your Item, perhaps that is what has stopped working.

This rule with “timestamp” instead of “lastUpdate” is working for the same item:

rule "Xiaomi Temp 1 Status Changed"
when
        Item Xiaomi_Temp_1 received update
then
        var SimpleDateFormat df = new SimpleDateFormat( "dd.MM., HH:mm" )
        var String timestamp = df.format( new Date() )
        Xiaomi_Temp_1_komplett.postUpdate(String::format("%.1f", (Xiaomi_Temp_1.state as DecimalType).floatValue()) + " °C / " + String::format("%.0f", (Xiaomi_Humidity_1.state as DecimalType).floatValue()) + " % (" + timestamp + ")")
end

MapDB is working for other items. There is no problem.

EDIT:
Wrong rule, changed it.

I’m a bit confused now. Have you got any problems left? Your time-since item Xiaomi_Temp_1_time_since is too big … because the group-triggered rule is not updating Xiaomi_Temp_1_last_connection?

Add logInfo to your group rule to see if it gets triggered, and what gets updated, maybe not what you expect.

I´m a bit confused too. After an OH2 restart now it works again…

Thanks for your help.