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
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?
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.
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
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 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…
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.
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.