Can't figure out calculation with "previousState()"

I have an item the gives me the power consumptionTotal (accumulated consumption since power loss on Shelly Device) and i’d like to store power consumption on every update of this item.

approach: Shelly_EM3_consumption = Shelly_EM3_accTotal - Shelly_EM3_accTotal.previousState

Here’s some info on my setup

  • Platform information:
    • Hardware: Rpi 4/4GB
    • OS: raspian (buster) / openhabianpi
    • openHAB version: 2.5-10

and here’s my code:

Number      Shelly_EM3_accTotal     "Shelly em3 Gesamtverbrauch"  (gShelly)   {channel="shelly:shellyem3:xxx:device#accumulatedWTotal"}
Number      Shelly_EM3_consumption                                (gShelly)
rule "Power Consumption EM3"
    Item Shelly_EM3_accTotal changed
/// some logs to check the previous state
    logInfo("NEW", Shelly_EM3_accTotal.state.toString)
    logInfo("PREVIOUS MAPDB", Shelly_EM3_accTotal.previousState(false,"mapdb").state.toString)
    logInfo("PREVIOUS INFLUXDB", Shelly_EM3_accTotal.previousState(false,"influxdb").state.toString)
    Shelly_EM3_consumption.postUpdate((Shelly_EM3_accTotal.state as Number) - (Shelly_EM3_accTotal.previousState(false,"mapdb").state as Number))


apparently there’s something wrong with my code because:

2020-12-23 15:18:01.081 [vent.ItemStateChangedEvent] - Shelly_EM3_accTotal changed from 225.478 to 225.501
2020-12-23 15:18:01.659 [INFO ] [g.eclipse.smarthome.model.script.NEW] - 225.501
2020-12-23 15:18:01.665 [INFO ] [marthome.model.script.PREVIOUS MAPDB] - 225.501
2020-12-23 15:18:01.684 [INFO ] [thome.model.script.PREVIOUS INFLUXDB] - 225.501

shouldn’t previousstate be 225.478?
tried different presistence services… but mapdb should be ok, right?
mapdb: * : strategy = everyChange,restoreOnStartup
influxdb: gShelly* : strategy = everyChange, everyMinute

later, unchanged config:

2020-12-23 15:20:30.880 [vent.ItemStateChangedEvent] - Shelly_EM3_accTotal changed from 225.524 to 225.547
2020-12-23 15:20:30.890 [INFO ] [g.eclipse.smarthome.model.script.NEW] - 225.547
2020-12-23 15:20:30.901 [INFO ] [marthome.model.script.PREVIOUS MAPDB] - 225.547
2020-12-23 15:20:30.927 [INFO ] [thome.model.script.PREVIOUS INFLUXDB] - 225.524

influxdb this time gives back the previous state, mapdb doesn’t?
Shelly_EM3_consumption is not calculated as it should be according to my rule.

later again, same config:

2020-12-23 15:22:03.045 [vent.ItemStateChangedEvent] - Shelly_EM3_accTotal changed from 225.569 to 225.592
2020-12-23 15:22:03.064 [INFO ] [g.eclipse.smarthome.model.script.NEW] - 225.592
2020-12-23 15:22:03.073 [INFO ] [marthome.model.script.PREVIOUS MAPDB] - 225.592
2020-12-23 15:22:03.094 [INFO ] [thome.model.script.PREVIOUS INFLUXDB] - 225.569
2020-12-23 15:22:03.131 [vent.ItemStateChangedEvent] - Shelly_EM3_consumption changed from 0.000 to 0.023

influxdb has the right “previous” state (mapdb still doesn’t) and the calculation is done according to the rule…

now i don’t even know where to begin as there seem to be 2 problems:

  1. i’m not able to get the correct previousstate of my persisted item.
  2. there’s something wrong with my calculation.

any help would be appriciated because i’ve already lost (invested?) 3 hours for this (apparently not so) simple math problem…

best regards

Only if somehow your rule ran before MapDB managed to save the current state. Remember, MapDB only stores one value per Item. When your Item changed, it stored that state. That means in a rule you will almost always getting the current state of the Item when requesting any data from MapDB in the rule.

You don’t need persistence at all for this. When a rule triggers from a changed trigger, there is a previousState implicit variable that lets you see what the Item changed from.

ok, so previousState() (with persistence) doesn’t really make sense in rules, right?

i’ve tried with previousState, first i got i wrong:
logInfo("POWER CONSUMPTION", Shelly_EM3_accTotal.previousState.state.toString)

it’s much easier :slightly_smiling_face:
logInfo("POWER CONSUMPTION", previousState)

thank you rich!

just to be sure, this rule should do the trick (?):

rule "Power Consumption new"
    Item Shelly_EM3_accTotal changed
    Shelly_EM3_consumption.postUpdate((Shelly_EM3_accTotal.state as Number) - (previousState as Number))

with influxdb.persist
Shelly_EM3_consumption : strategy = everyUpdate

so everytime the value of Shelly_EM3_accTotal gets bigger presistence should write the delta to influxdb, (even if the delta is the same as before).

If using a database other than MapDB, when you pass true in the call to lastUpdate it will retrieve the last update for when the Item was different from it’s current state which could be useful in many circumstances.

Try it and find out. Looks reasonable.

1 Like