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:

Date.parse(lastUpdate.toInstant())

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")
if(lastUpdate.isBefore(now.minusSeconds(10)){
}

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.

2 Likes

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.

see
https://www.openhab.org/javadoc/latest/org/openhab/core/persistence/extensions/persistenceextensions#changedSince(org.openhab.core.items.Item,java.time.ZonedDateTime)

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.

1 Like

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

Hello,

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
Armin

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.

I am using OH 4.2.2 and I have 2 PIR sensors near the house main entry door:

  • The first is outside near the main entry door (MainEntry_Door_Out_Motion_Alarm)
  • The second is in-house near the main entry door (MainEntry_Door_In_Motion_Alarm)
    I am using the first sensor to turn on lights when someone is near the door after sunset (there is a dedicated rule for that).
    The second sensor is used for OH as a home alarm system (there is a dedicated rule for that, too) - it checks if someone is at the entrance patio once the alarm function is on.
    I decided to add another function of checking if someone came in or out of that door (I know there is a door/window sensor for that but this is only a backup).
    Here is my working rule:
var Timer Timer_SomeOne_Went_In

when
    Item MainEntry_Door_In_Motion_Alarm changed to ON
then
    if (MainEntry_Door_Out_Motion_Alarm.changedSince(now.minusMinutes(5)))
    {
        SomeOne_Went_In.sendCommand(ON)
        Timer_SomeOne_Went_In = createTimer(now.plusSeconds(5), [|   
        SomeOne_Went_In.sendCommand(OFF) 
        logInfo("Entry_Door_Automation", "Some One Went In- 5 min in between")
        ])    
    }
end

P.S
You can use the expire function to make the rule look nicer:
The “SomeOne_Went_In” item would look like:

Switch SomeOne_Went_In {expire = "5s, command=OFF"}

The rule would be:

when
    Item MainEntry_Door_In_Motion_Alarm changed to ON
then
    if (MainEntry_Door_Out_Motion_Alarm.changedSince(now.minusMinutes(5)))
    {
        SomeOne_Went_In.sendCommand(ON)
        logInfo(“Entry_Door_Automation”, “Some One Went In - 5 min in between”)
    }
end