previousState not available for Items

Hello, I’m little bit confused about my OH3 v3.3.0 stable.
I want to set an delta if an Item is updated. RRD4j is the default persistence, but influx DB is also installed and configured.

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: itmUHT230Total
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript
      script: >-
        var logger =
        Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' +
        ctx.ruleUID);

        var lstVal = itemRegistry.getItem('itmUHT230Total').previousState();
        var aktVal = itemRegistry.getItem('itmUHT230Total').getState();

        logger.info("lstVal: " + lstVal + ", aktVal: " + aktVal);

        var valDelta = aktVal - lstVal;
        logger.info("Set UHT 230 Delta to: " + valDelta);
        events.postUpdate('itmUHT230Delta', valDelta);
    type: script.ScriptAction

But I get that error:

2022-12-09 17:41:56.916 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '24aa95c501' failed: TypeError: itemRegistry.getItem("itmUHT230Total").previousState is not a function in <eval> at line number 3

Why? I also tried previousState(true) and historicState() nothing is available.
What do I miss there?

Thanks a lot!

ECMAScript 5.1 is not Rules DSL.

Rules DSL does a bunch of magic behind the scenes to make it look like stuff that is separate are actually a part of the Item. Persistence is one of these.

You’ll need to import the PersistenceExtensions and call previousState or historicState on that.

IIRC, it’ll be something like

actions.PersistenceExtensions.previousState(itemRegistry.getItem('itmUHT230Total')

But I’m going from memory. In JS Scripting which uses a much more up to date version of ECMAScript and comes with a helper library, it’s easier.

items.getItem('itmUHT230Total').history.previousState();

While there are lots of differences, it gives a much better experience closer to Rules DSL.

Ok,thanks, created now an Rule DSL:

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: itmUHT230Total
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >-
        logInfo("Update UHT 230 Delta", "Start")
        val lstVal = itmUHT230Total.previousState as Number
        val aktVal = itmUHT230Total.state as Number

        logInfo("Update UHT 230 Delta", "lstVal: " + lstVal + ", aktVal: " + aktVal)

        val valDelta = aktVal - lstVal

        logInfo("Update UHT 230 Delta", "Set UHT 230 Delta to: " + valDelta)

        //itmUHT230Delta.postUpdate(valDelta);
        logInfo("Update UHT 230 Delta", "End")
    type: script.ScriptAction

But get that Error now:

2022-12-10 11:05:39.305 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '24aa95c501' failed: Could not cast 10/12/2022, 11:05: itmUHT230Total -> 55451.0 to java.lang.Number; line 2, column 14, length 38

This is my Item:
grafik

Tried different things, read that Chapter: Rules-DSL, it should work, but it does not… :frowning:

Ok, managed it to run now, itmUHT230Total.previousState has also a state. :+1:
But get the same number for previous state as for the actual state.
Any Ideas why?

Why wouldn’t it? The recorded previous state say from a minute ago is likely to be the same as the state now.

So far as I know, previousState(true) doesn’t work very well with rrd4j, something about its aggregating/averaging archive strategy I expect.

As you have influxdb, use that by steering your query.

But you might think a bit about your rule strategy. It is triggered on update - that might mean there was no change.
Maybe trigger on change is better for you? I don’t know what you need.

1 Like

you’re right, that one worked:

val lstVal = itmUHT230Total.historicState(now.minusSeconds(1), "influxdb").state as Number

For the benefit of other readers, it is not usual to have an “every second” persistence strategy, so the results from this query probably will not be what first appears like.

There is hardly ever a persistence record at exactly the queried instant in time, so the persistence service deals with that by going back in time to the next-youngest record.
In the example above, that is likely from one, two, five minutes ago, etc., depending on the persistence strategy, possibly days.

You can find out by examining the timestamp that is part of the results returned.