OH3 ECMA: get lastupdate time of an item?

Is there a way to read the lastchanged timestmap of a persisted item in openHAB3 in ECMA-script?

My use case is to avoid a proxy “lastchanged” item! :wink:
and being able to see how long a state hasn’t changed.

Should be something like this:

var PersistenceExtensions = Java.type("org.openhab.core.persistence.extensions.PersistenceExtensions");
var lastUpdate = PersistenceExtensions.lastUpdate(ir.getItem("ItemName"), "persistence service");

PersistenceExtensions (openHAB Core 3.1.0-SNAPSHOT API) has all the methods you can call. They correspond with the functions you can call on an Item in Rules DSL.

1 Like

That’s great as usual! Thanks:

the “lastupdate”-variable then spits out like this:

2021-01-14 08:59:00.676 [INFO ] [org.openhab.rule.a84df3bfff         ] - Event: 2021-01-14T08:37:32.750+01:00[Europe/Berlin]

Yes, it’s a ZonedDateTime which, unfortunately, does not provide an ISO8601 formatted string by default and instead tacks on that [Europe/Berlin] timezone instead.

but which can dealt with, easily if you only like to use the lastUpdate for comparisons:


so, like this:

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var PersistenceExtensions = Java.type("org.openhab.core.persistence.extensions.PersistenceExtensions");

var lastUpdate = Date.parse(PersistenceExtensions.lastUpdate(ir.getItem("BalboaIPUnit_CurrentTemperature"), "jdbc").toInstant());
var ago10secs = new Date(new Date() - 10000).getTime();

logger.info("lastUpdate: " + lastUpdate + "; ago10secs: " + ago10secs);

so now you can make comparisons as you like.

Actually I think that’s a little more complicated than necessary. ZonedDateTime has most of the same features and methods that Joda DateTime did. You don’t need to convert it to a Date to make comparisons.

var PersistenceExtensions = Java.type("org.openhab.core.persistence.extensions.PersistenceExtensions");

var lastUpdate = PersistenceExtensions.lastUpdate(ir.getItem("BalboaIPUnit_CurrentTemperature"), "jdbc")

The only problem with the way if formats the toString by default is some older code where the toString of a Joda DateTime was used to initialize a DateTimeType won’t work any more.


Just a short heads-up:

  • lastUpdate: is difficult, if your persistence strategy updates everyHour or so, that’s NOT the lastchanged then!
  • changedSince would give you true/false for a given timestamp.


my use case was to check, if my door was open for more then 5mins, so I would go for lastUpdate, but if the door was opened like 16:56, then I’d not get the alert on time, as on 17:00 the item would be updated regardless of a change.
I do this with all my items, because some states won’t show in a graph, if they don’t change for a longer period. With everyHour in the persistence, they show up.

This is a perennial problem. Optimizing for charting often works against the way you’d want to use persistence in rules.

However there is a way to work around this. Use previousState(true). This will return the most recent entry in the database that is different from the Item’s current state. It returns a HistoricState which has both the state and a timestamp so instead of lastUpdate you can use that timestamp to get when the Item changed to its current state (assuming your strategy include saving on change in addition to periodically).

1 Like


in my rule on openHAB 4.0.1 the command

var PersistenceExtensions = Java.type("org.openhab.core.persistence.extensions.PersistenceExtensions");

results in an error in /var/log/openhab/openhab.log

1. The method or field Java is undefined; line 5, column 108, length 4

Did I miss to include something to make this work.

Best regards

If you are using JS Scripting ECMAScript 11 then you don’t need to import anything.

items['MyItem"].history.lastUpdate(); // for example

The whole point of the library that comes with the add-on is so you don’t have to mess with imports and stuff like that.

Beyond that, we’d need to see the whole rule/file in context to understand the error.

Given that this thread is over a year old, it would have been best to open a new thread than resurrect such an old thread.