Spirious changes of numeric item states when openhab.log file is switched

Running OpenHAB 5.1 on a RPI5 I face a strange problem with numeric item states I use to aggregate e.g. the power consumption or the sunlight power over a day.

I’m using a rule that is triggert whenever the currently consumed power changes.
It fetches the value at the previous change and the time since then and adds it to the aggreation value.

Sometimes the numeric state of these aggregation items jump up or down without adding any value.

Example from openhab.log:

The lines are output by the rule and show the previous aggregated value, the added value since the last change and the resulting aggregated value.
Zeile 122683: 2026-01-24 07:36:30.337 [INFO ] [org.openhab.rule.EnergyPerDay ] - **** Rule EnergyPerDay: 5426.4196743919265+0.4048275711362445=5426.824501963063
Here the current logfile is closed and a new one is started
Zeile 293: 2026-01-24 07:37:26.160 [INFO ] [org.openhab.rule.EnergyPerDay ] - **** Rule EnergyPerDay: 8602.557559848325+0.5689869805416=8603.126546828866

It shows that the aggregated value of 5426.x jumpes to 8602.x between two calls of the rule.

The same happens in the opposite direction:
    Zeile 52543: 2026-01-23 14:20:27.748 [INFO ] [org.openhab.rule.EnergyPerDay       ] - **** Rule EnergyPerDay: Oldsum 18042.868846731715 plus 0.19076630318360002 gives 18043.0596130349
Here the current logfile is closed and a new one is started (unfortunately there are some lines missing but the effect is clear anyway)
    Zeile    291: 2026-01-23 14:49:39.883 [INFO ] [org.openhab.rule.EnergyPerDay       ] - **** Rule EnergyPerDay: Oldsum 8602.557559848325 plus 0.6033289642431222 gives 8603.160888812568

This time the value of 18042.x drops to 8602.x although the added values are all positive.

I’ve got 3 persistance services
MapDB
RRD4J
InfluxDB
The items keeping the current value of power consumption and the accumulated value is configured in InfluxDB
everyChange, restoreOnStartup
They are excluded in the other persistance services.

I’ve no idea what is wrong here and would apreciate any hint what to change to make it work properly.

Thanks a lot,

Norbert

As of 5.1 events.log allows the source of the events on the Items. If you look there you will see where all the changes made to the Item come from. If you see sources that are not your role you found where the unexpected changes came from. If it’s only your role changing the Item, there’s a problem with your rule.

Thank you Rich for the immediate answer!

Today in the morning the same problem reappeared and I gathered all information from the log files.

First from the events log file the power consumption got from the three phases of a ShellyEM3 sensor (item ShellyEM3_EnergyTotal).

	Zeile 40821: 2026-01-26 08:23:39.171 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 281.15 W to 280.06 W through ShellyEM3_StromverbrauchB
	Zeile 40825: 2026-01-26 08:23:39.175 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 280.06 W to 302.39 W through ShellyEM3_StromverbrauchC
	Zeile 40876: 2026-01-26 08:23:42.205 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 302.39 W to 301.83 W through ShellyEM3_StromverbrauchA
	Zeile 40878: 2026-01-26 08:23:42.222 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 301.83 W to 303.34 W through ShellyEM3_StromverbrauchB
	Zeile 40885: 2026-01-26 08:23:42.261 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 303.34 W to 279 W through ShellyEM3_StromverbrauchC

Here the events.log file is changed:

	Zeile   219: 2026-01-26 08:24:38.919 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 153.27 W to 146.81 W through ShellyEM3_StromverbrauchA
	Zeile   224: 2026-01-26 08:24:38.990 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 146.81 W to 147.78 W through ShellyEM3_StromverbrauchB
	Zeile   229: 2026-01-26 08:24:39.012 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 147.78 W to 300.1 W through ShellyEM3_StromverbrauchC
	Zeile   236: 2026-01-26 08:24:39.193 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 300.1 W to 299.89 W through ShellyEM3_StromverbrauchA
	Zeile   238: 2026-01-26 08:24:39.222 [INFO ] [hab.event.GroupItemStateChangedEvent] - Item 'ShellyEM3_EnergyTotal' changed from 299.89 W to 301.63 W through ShellyEM3_StromverbrauchB

The rule is triggered by changes of this item.

From the same event log files the changes of the aggregated value (item ShellyEM3_EnergyPerDay).

	Zeile 40890: 2026-01-26 08:23:42.272 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'ShellyEM3_EnergyPerDay' received command 6001.38774384872 (source: org.openhab.core.automation.module.script)
	Zeile 40892: 2026-01-26 08:23:42.273 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'ShellyEM3_EnergyPerDay' received command 6001.996028869268 (source: org.openhab.core.automation.module.script)
	Zeile 40894: 2026-01-26 08:23:42.278 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 6001.385864549719 Wh to 6001.38774384872 Wh (source: org.openhab.core.autoupdate)
	Zeile 40896: 2026-01-26 08:23:42.290 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 6001.38774384872 Wh to 6001.996028869268 Wh (source: org.openhab.core.autoupdate)

Here the events.log file is changed:

	Zeile   272: 2026-01-26 08:24:42.417 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'ShellyEM3_EnergyPerDay' received command 8603.173737069443 (source: org.openhab.core.automation.module.script)
	Zeile   274: 2026-01-26 08:24:42.429 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8602.557559848325 Wh to 8603.173737069443 Wh (source: org.openhab.core.autoupdate)
	Zeile   276: 2026-01-26 08:24:42.463 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'ShellyEM3_EnergyPerDay' received command 8603.79907504651 (source: org.openhab.core.automation.module.script)
	Zeile   277: 2026-01-26 08:24:42.468 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8603.173737069443 Wh to 8603.79907504651 Wh (source: org.openhab.core.autoupdate)

There is a jump of the value from 6001.996028869268 to 8603.173737069443!

Finally the output of my rule from the openhab log file that shows the value at the previous change, the periode since then and the calculation done in the rule to accumulate the value.

	Zeile 90749: 2026-01-26 08:23:42.264 [INFO ] [org.openhab.rule.EnergyPerDay       ] - **** Rule EnergyPerDay: Energy 302.39 for 0.0020178058783333333(S)
	Zeile 90750: 2026-01-26 08:23:42.264 [INFO ] [org.openhab.rule.EnergyPerDay       ] - **** Rule EnergyPerDay: 6001.385864549719+0.6101643195492166=6001.996028869268

Here the events.log file is changed:

	Zeile  296: 2026-01-26 08:24:42.389 [INFO ] [org.openhab.rule.EnergyPerDay       ] - **** Rule EnergyPerDay: Energy 302.26 for 0.0020385668666666667(S)
	Zeile  298: 2026-01-26 08:24:42.401 [INFO ] [org.openhab.rule.EnergyPerDay       ] - **** Rule EnergyPerDay: 8602.557559848325+0.6161772211186667=8603.173737069443

Finally the rule that does the accumulation:

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

var EnergyItem = itemRegistry.getItem("ShellyEM3_EnergyTotal");
var EnergyPerDayItem = itemRegistry.getItem("ShellyEM3_EnergyPerDay");
var EnergyPerDayTotalItem = itemRegistry.getItem("ShellyEM3_EnergyPerDay_Total");

// rule code energy per day
// logger.info("**** >>>>>>>>>> " + ctx.ruleUID + " >>>>>>>>>>");

// Sum per Day
var EnergyPerDay = new Number(0.);
if (EnergyPerDayItem.getState() == NULL)
  events.sendCommand(EnergyPerDayItem.getName(), EnergyPerDay);
else
  EnergyPerDay = parseFloat(EnergyPerDayItem.getState());

var CurrentEnergy = parseFloat(EnergyItem.getState());
var EnergyPreviousState = PersistenceExtensions.previousState(EnergyItem);
var EnergyPreviousItem = EnergyPreviousState.getState();
var EnergyPrevious = parseFloat(EnergyPreviousItem);

if (EnergyPrevious > 0)
{  
  var PreviousStateSince = Duration.between(EnergyPreviousState.getTimestamp(), ZonedDateTime.now()).toString();
  var CurrentPeriode = parseFloat(PreviousStateSince.substring(2));
  var Unit = PreviousStateSince.substring(PreviousStateSince.length() - 1);

  switch (Unit)
  {
    case "S":
      CurrentPeriode /= 3600;
      break;
    case "M":
      CurrentPeriode /= 60;
      break;
  }
  var AdditionalEnergy = CurrentPeriode * EnergyPrevious;

  var NextEnergyPerDay = EnergyPerDay + AdditionalEnergy;
  var bError = NextEnergyPerDay < EnergyPerDay || NextEnergyPerDay - EnergyPerDay > 100;

  logger.info("**** Rule " + ctx.ruleUID + (bError ? " ERROR" : "") + ": Energy " + EnergyPrevious + " for " + CurrentPeriode + "(" + Unit + ")");
  logger.info("**** Rule " + ctx.ruleUID + (bError ? " ERROR" : "") + ": " + EnergyPerDay + "+" + AdditionalEnergy + "=" + NextEnergyPerDay);
  
  EnergyPerDay += AdditionalEnergy;
}

events.sendCommand(EnergyPerDayItem.getName(), EnergyPerDay);

That is all information I can give you. I really have no idea what the reason for this behaviour is.

Thanks for your answer!

Yours, Norbert

One of your rules commanded the Item with that value.

2026-01-26 08:24:42.417 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'ShellyEM3_EnergyPerDay' received command 8603.173737069443 (source: org.openhab.core.automation.module.script)

All the autoupdate stuff is just responding to the command.

Note: if this is the sum of sensor values, this Item should be updated, not commanded. Only use commands when you are asking a device to do something.

You can give me the full rule. Click on the code tab. This doesn’t tell me all triggers of the rule or whether there are any rule conditions and what those might be.

You can give me the states of all the relevant Items

Is this Nashorn JS or is it supposed to be JS Scripting? Or is this an AI generated rule (in which case it’s likely trying to be both).

All I can say is your rule ran at 08:23:42 and commanded the Item with the 6001 value (probably in response to the five changes to the Group Item at that time), but why did the rule only run once? And then it ran again at 08:24:42 (again because of new changes) and commanded the Item with the 8603 value.

There’s no logging from the rule itself.

The rule as implemented is overly complex so it’s a little challenging to analyze. And there are some lines which look down right erroneous to me and show signs it was generated by AI.

But all I can say is your rule is executed twice because the Item that triggers it changes twice. The value it commands (should be updates) to the EnergyPerDayItem is what ever the rule calculated each time the rule was run.

You need to add logging and analyze what the rule is doing each time it runs to calculate this value. If you’ve written this rule yourself or have a desire to learn how to code rules like this yourself I can help make this rule more reasonable. If you used AI to generate this rule and are not willing to expand beyond that I’m going to bow out. I’m not interested if fixing AI slop if no one is going to learn from it.

Dear Rich,

I wrote this Rule myself, but I commit as experienced C++ programmer I’m really struggeling with this sctipting language. It’s Nashorn JS as it initially was written for aprior version of OpenHAB.

I’ll change the Commands to Updates, thanks for the hit.

In my post I added only the last openhab.log of the rule in the first log file and the first log of the rule in the following openhab.log file.

The first line the rule logs shows the value after the previos change and the time since then.

The second line shows the previous aggregation value, the added value calculated from the value and period in the first line an the resulting aggregation value sent to the item.

These values correspond with the values you find in the event.log lines.

The rule is not triggered in between but the one logfile is closed and the next one is opened.

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: ShellyEM3_EnergyTotal
    type: core.ItemStateChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript;version=ECMAScript-5.1
      script: |
        var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
        var PersistenceExtensions = Java.type("org.openhab.core.persistence.extensions.PersistenceExtensions");
        var ZonedDateTime = Java.type('java.time.ZonedDateTime');

        var EnergyItem = itemRegistry.getItem("ShellyEM3_EnergyTotal");
        var EnergyPerDayItem = itemRegistry.getItem("ShellyEM3_EnergyPerDay");
        var EnergyPerDayTotalItem = itemRegistry.getItem("ShellyEM3_EnergyPerDay_Total");
        var EnergyTotalItem = itemRegistry.getItem("ShellyEM3_EnergyGrandTotal");

        // rule code energy per day
        // logger.info("**** >>>>>>>>>> " + ctx.ruleUID + " >>>>>>>>>>");

        // Total Energy
        var EnergyTotal = new Number(0.);
        if (EnergyTotalItem.getState() == NULL)
          events.sendCommand(EnergyTotalItem.getName(), EnergyTotal);
        else
          EnergyTotal = parseFloat(EnergyTotalItem.getState());

        // Sum per Day
        var EnergyPerDay = new Number(0.);
        if (EnergyPerDayItem.getState() == NULL)
          events.sendCommand(EnergyPerDayItem.getName(), EnergyPerDay);
        else
          EnergyPerDay = parseFloat(EnergyPerDayItem.getState());

        var CurrentEnergy = parseFloat(EnergyItem.getState());
        var EnergyPreviousState = PersistenceExtensions.previousState(EnergyItem);
        var EnergyPreviousItem = EnergyPreviousState.getState();
        var EnergyPrevious = parseFloat(EnergyPreviousItem);

        if (EnergyPrevious > 0)
        {  
          var PreviousStateSince = Duration.between(EnergyPreviousState.getTimestamp(), ZonedDateTime.now()).toString();
          var CurrentPeriode = parseFloat(PreviousStateSince.substring(2));
          var Unit = PreviousStateSince.substring(PreviousStateSince.length() - 1);

          switch (Unit)
          {
            case "S":
              CurrentPeriode /= 3600;
              break;
            case "M":
              CurrentPeriode /= 60;
              break;
          }
          var AdditionalEnergy = CurrentPeriode * EnergyPrevious;
          var AdditionalTotalEnergy = AdditionalEnergy;

          var NextEnergyPerDay = EnergyPerDay + AdditionalEnergy;
          var bError = NextEnergyPerDay < EnergyPerDay || NextEnergyPerDay - EnergyPerDay > 100;

          logger.info("**** Rule " + ctx.ruleUID + (bError ? " ERROR" : "") + ": Energy " + EnergyPrevious + " for " + CurrentPeriode + "(" + Unit + ")");
          logger.info("**** Rule " + ctx.ruleUID + (bError ? " ERROR" : "") + ": " + EnergyPerDay + "+" + AdditionalEnergy + "=" + NextEnergyPerDay);
          
          EnergyPerDay += AdditionalEnergy;
          EnergyTotal += AdditionalTotalEnergy / 1000;

          if (AdditionalEnergy >= 1)
            logger.info("**** Rule EnergyPerDay " + EnergyPerDay);
        }

        events.sendCommand(EnergyPerDayItem.getName(), EnergyPerDay);
        events.sendCommand(EnergyTotalItem.getName(), EnergyTotal);

        // logger.info("**** <<<<<<<<<< " + ctx.ruleUID + " <<<<<<<<<<");
    type: script.ScriptAction

I would appreciate for tips how to simplify the rule.

Thanks a lot!

Norbert

I recommend considering using JS Scripting instead as it makes the code much more concise and easy to understand.

Doing a line for line translation this rule would be something like the following in JS Scripting.

let energyPerDay = (items.EnergyPerDayItem.isUninitialized) ? Quantity("0 kWh") : items.EnergyPerDayItem.quantityState; // assumes this is a Number:Energy Item

const currEnergy = items.EnergyItem.quantityState;
const energyPrevious = items.EnergyItem.previousQuantityState; // the previous state is now a property on the Item, you don't need persistence

if(energyPrevious.greaterThan("0 W")) {
  const delta = time.Duration.between(items.EnergyItem.lastStateChangeTimestamp, time.toZDT());
  const additionalEnergy = energyPrevious.multiply(delta.toSeconds() + ' s');
  const nextEnergyPerDay = energyPerDay + additionalEnergy
  const bError = nextEnergyPerDay.lessThan(energyPerDay) || nextEnergyPerDay.subtract(energyPerDay).greaterThan("100 kWh") // it's unclear to me if I have the units on the greaterThan correct

  console.info("**** Rule "+ (bError ? " ERROR" : "") + ": Energy " + energyPrevious + " for " + delta.toSeconds() + "(s)") // the rule id is already logged 
  console.info("**** Rule " + (bError ? " ERROR" : "") + ": " + energyPerDay + "+" + additionalEnergy + "=" + nextEnergyPerDay);

  energyPerDay.addition(additionalEnergy);
}

items.EnergyPerDayItem.postUpdate(energyPerDay);

Note that the above makes use of units of measurement. For example, multiplying a Quantity of unit W by a Quantity that is a unit of time (e.g. s) the result will be Ws. We don’t really care what the units are though becuase by creating your EnergyPerDayItem as a Number:Power with a unit metadata of kWh (for example, the Ws will be converted to kWh automatically.

You can convert the values to your prefered unit in the log statements using toUnit('kWh') (for example).

The Quantity math methods all support Strings so you can pass a parsable string (i.e. <number> <unit>) and it will parse and convert it to a Quantity for you.

And as of OH 5.0 all Items carry the previousState and timestamp for the last change and the last update as a property of the Item instead of requiring a call to persistence.

time.toZDT() is a shorthand for now. time.toZDT() will convert anything that it remotely makes sense to convert to a date time (e.g. pass it a number and it adds that number as msec to now, passs it “08:00” or “8:00 am” and it will create a timestamp of 08:00 today in your default timezone, etc).

Note, I just typed in the above, there is likely mistakes. I post it mainly to show what’s possible.

If you stay with Nashorn I can point out a bunch of simplifications too.

Based on this trigger, the rule should trigger ten times between 08:23:349 and 08:24:39 according to the events.log posted above.

What’s the definition of this Item? In particular what’s the aggregation function?

Dear Rich,

thank you very much for your valuable hinte. It took me some time to get it work properly.

Two facts caused some try and error. First I want to sum up the solar energy I get per day on one m2. But the Quantity Wh/m2 is not supported.

A more serious problem is that previousQuantityState and lastStateChangeTimestamp are two values that do not fit together. previousQuantityState gives the state before the latest change, but lastStateChangeTimestamp is the timestamp of the latest change. I could not figure out if there is something liek previousStateChangeTimestamp. Thus I used a rule instance variable to store the previous triggering of the rule.

Now the aggregation values I get seem reasonable. But unfortunately this rewriting of the rules in ECMA11 did not fix the initial problem. I’ve creted the new rules for calculating the power consumption during a day and for the caculation of the solar energy for the day. The two screenshots show the problem. This screenshot shows the current solar intensity (green) and the accumulated value (blue). At 9:22 the accumulated value jumpes up while the measurment of the current intensity is zero.

The next screenshot shows the accumulated power consumption and at the same moment at 9:22 it does a jump too.

To keep it simple I’ll only further document the power consumption accumulation, First her are the entries in the event.log files filtered for the ShellyEM3_EnergyPerDay from 9:19 to 9:24. You can see there is a change of the state between 09:22:11.635 ‘to value’ (event.log.6) and 09:23:20.581 ‘from value’ (event.log.7).

events.log.5
	Zeile 82085: 2026-02-04 09:19:01.252 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2822.6172319243196 Wh to 2824.0937597020975 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82139: 2026-02-04 09:19:10.872 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2824.0937597020975 Wh to 2825.5973725574786 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82233: 2026-02-04 09:19:20.897 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2825.5973725574786 Wh to 2827.0970293917953 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82319: 2026-02-04 09:19:31.075 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2827.0970293917953 Wh to 2828.5741215159164 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82423: 2026-02-04 09:19:41.181 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2828.5741215159164 Wh to 2830.057464264975 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82494: 2026-02-04 09:19:50.892 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2830.057464264975 Wh to 2831.5584309960796 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82551: 2026-02-04 09:20:00.894 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2831.5584309960796 Wh to 2833.0570287418604 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82662: 2026-02-04 09:20:11.061 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2833.0570287418604 Wh to 2834.26939994262 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82759: 2026-02-04 09:20:20.897 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2834.26939994262 Wh to 2835.4906570002477 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82848: 2026-02-04 09:20:31.045 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2835.4906570002477 Wh to 2836.702805968684 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82928: 2026-02-04 09:20:40.876 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2836.702805968684 Wh to 2837.936322648681 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 82983: 2026-02-04 09:20:50.868 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2837.936322648681 Wh to 2839.2034059820144 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 83043: 2026-02-04 09:21:00.919 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2839.2034059820144 Wh to 2840.473822648681 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 83134: 2026-02-04 09:21:11.080 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2840.473822648681 Wh to 2841.6775818894234 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 83195: 2026-02-04 09:21:21.510 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2841.6775818894234 Wh to 2842.950609667201 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 83262: 2026-02-04 09:21:30.869 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2842.950609667201 Wh to 2844.154755683155 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 83334: 2026-02-04 09:21:40.887 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2844.154755683155 Wh to 2845.3803179324855 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 83419: 2026-02-04 09:21:50.895 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2845.3803179324855 Wh to 2846.609514498728 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile 83482: 2026-02-04 09:22:01.025 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2846.609514498728 Wh to 2847.8143756098393 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
events.log.6
	Zeile 4: 2026-02-04 09:22:11.635 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2847.8143756098393 Wh to 2849.0180978320614 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
events.log.7
	Zeile   366: 2026-02-04 09:23:20.581 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8602.557559848325 Wh to 8603.647282467531 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile   455: 2026-02-04 09:23:30.424 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8603.647282467531 Wh to 8604.73723713391 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile   540: 2026-02-04 09:23:40.458 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8604.73723713391 Wh to 8605.818717189894 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile   630: 2026-02-04 09:23:50.427 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8605.818717189894 Wh to 8606.894972830432 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile   692: 2026-02-04 09:24:00.416 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8606.894972830432 Wh to 8607.980374322357 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile   777: 2026-02-04 09:24:10.419 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8607.980374322357 Wh to 8609.066437103522 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile   856: 2026-02-04 09:24:20.427 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8609.066437103522 Wh to 8610.184992659077 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile   903: 2026-02-04 09:24:30.411 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8610.184992659077 Wh to 8611.298242659077 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile   946: 2026-02-04 09:24:40.402 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8611.298242659077 Wh to 8612.419242659076 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile  1015: 2026-02-04 09:24:50.417 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8612.419242659076 Wh to 8613.53493710352 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile  1080: 2026-02-04 09:25:00.405 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8613.53493710352 Wh to 8614.65024304511 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile  1142: 2026-02-04 09:25:10.408 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8614.65024304511 Wh to 8615.731140334257 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile  1230: 2026-02-04 09:25:20.415 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8615.731140334257 Wh to 8616.846474045255 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile  1303: 2026-02-04 09:25:30.400 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8616.846474045255 Wh to 8617.927793473036 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile  1375: 2026-02-04 09:25:40.441 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8617.927793473036 Wh to 8619.049293473036 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
	Zeile  1441: 2026-02-04 09:25:50.455 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8619.049293473036 Wh to 8620.162877020215 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)

There is no ItemStateChangedEvent in between that represents this change. Finally here the new rule doing the calculation:

configuration: {}
triggers:
  - id: "1"
    configuration:
      cronExpression: 0/10 * * * * * *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "4"
    configuration:
      type: application/javascript
      script: >+
        //console.info("---------------------------")

        //console.info("Triggered", time.toZDT())


        let energyPerDay = (items.ShellyEM3_EnergyPerDay.isUninitialized) ?
        Quantity("0 Wh") : items.ShellyEM3_EnergyPerDay.quantityState;

        //console.info("energyPerDay", energyPerDay)


        var itemEnergyTotal = items.ShellyEM3_EnergyTotal;


        var last10Seconds = time.ZonedDateTime.now().minusSeconds(10);

        const energyLast10Seconds =
        itemEnergyTotal.persistence.averageSince(last10Seconds).quantityState;

        console.info("energyLast10Seconds", energyLast10Seconds)
          
        const additionalEnergy = energyLast10Seconds.divide(360).multiply('1
        h');

        //console.info("additionalEnergy ", additionalEnergy)


        energyPerDay = energyPerDay.add(additionalEnergy);

        //console.info("new energyPerDay", energyPerDay)

        items.ShellyEM3_EnergyPerDay.postUpdate(energyPerDay);

    type: script.ScriptAction

This rule differs from the suggestion you’ve given due to the fact that lastStateChangeTimestamp does not return the timesamp of the previous change. I decided to call the rule every 10 seconds and multiply the average over the last 10 seconds with 10 to get the power consumed diring this periode.

Sorry that my post is again so long, but I hope I gave you all necessary information to analyse the problem.

Thanks a lot for your kindness to listen to my problem.

Kind regards,

Norbert

It should be. Did you try it and it didn’t work? Though you have to use a superscript. 1 m², not 1 m2.

I just tried this:

 console.info(Quantity('20 Wh').divide('1 m²'));

which logged

2026-02-04 12:15:15.497 [INFO ] [tomation.jsscripting.rule.scratchpad] - 20 Wh/m²

Always look to the docs.

Item : object

  • .rawItem ⇒ HostItem
  • .state ⇒ string
  • .numericState ⇒ number|null: State as number, if state can be represented as number, or null if that’s not the case
  • .quantityState ⇒ Quantity|null: Item state as Quantity or null if state is not Quantity-compatible or without unit
  • .boolState ⇒ boolean|null: Item state as boolean or null if not boolean-compatible or is NULL or UNDEF, see below for mapping of state to boolean
  • .rawState ⇒ HostState
  • .previousState ⇒ string|null: Previous state as string, or null if not available
  • .previousNumericState ⇒ number|null: Previous state as number, if state can be represented as number, or null if that’s not the case or not available
  • .previousQuantityState ⇒ Quantity|null: Previous item state as Quantity or null if state is not Quantity-compatible, without unit, or not available
  • .previousRawState ⇒ HostState
  • .lastStateUpdateTimestamp ⇒ time.ZonedDateTime: The time the state was last updated as ZonedDateTime or null if not available
  • .lastStateUpdateInstant ⇒ time.Instant: The time the state was last updated as Instant or null if not available
  • .lastStateChangeTimestamp ⇒ time.ZonedDateTime: The time the state was last changed as ZonedDateTime or null if not available
  • .lastStateChangeInstant ⇒ time.Instant: The time the state was last changed as Instant or null if not available

Indeed, we do not have the timestamp that corresponds with the previous state methods. So persistence would need to be used there, or it needs to be recorded elsewhere (e.g. another Item, Item metadata, shared cache, etc). You chose a rule variable but there are other options.

Were I to do this, I’d create a DateTime Item linked to the same Channel as the Item you are tracking with the timestamp profile. Then in the rule you can use that Item’s previousState. It saves some coding.

I didn’t think it would. The original problem appears to be caused by the way the rule is triggered and the aggregation of the Group Item. Changing the code won’t change that problem.

There is some sort of fundamental assumption made here which is wrong.

events.log.6
	Zeile 4: 2026-02-04 09:22:11.635 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 2847.8143756098393 Wh to 2849.0180978320614 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)
events.log.7 
	Zeile   366: 2026-02-04 09:23:20.581 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'ShellyEM3_EnergyPerDay' changed from 8602.557559848325 Wh to 8603.647282467531 Wh (source: org.openhab.automation.jsscripting$rule:EnergyPerDay)

Why three logs? Did you restart OH twice in these logs? OH will roll over the logs by default on a restart.

There is no event showing the Item becoming 8602.557559848325 in between the transition from event.log.6 and event.log.7. The only thing that can cause that I’m aware of is restoreOnStartup.

What’s in your persistence for this Item for restoreOnStartup Do you have more than one persistence set up (e.g. many use rrd4j for charting and mapdb for restoreOnStartup)?

Do you have ZRAM enabled? If so, is the RPi losing power when this Item jumps? When the machine loses power without being shut down properly, all the stuff in RAM (i.e. mapdb, rrd4j) do not get written out. So your Item gets restored to what ever state it had the last time the machine was properly shut down.

Based on this evidence I suspect what’s happening is you are restarting OH and an old value is being restored to the Item.

Dear Rich,
thanks and please excuse my sloppy description. Of course you are right, within the rule I could calculate with Wh/m2 but it is not possible to set Wh/m2 in the items Dimension and Unit.

But the important information is, that the RPis uptime is 47125 minutes, thus almost 33 days. I’ve got no information about the RPi power.

I’ve three persistance addons active here there are the definitions. MapDB, RRD4J and InfluxDB. Here the setting of the thre persistances:

InfluxDB:

configurations:
  - items:
      - ShellyEM3*
      - "!ShellyEM3_EnergyPerDay_Total"
    strategies:
      - everyChange
      - restoreOnStartup
    filters: []
  - items:
      - SunEnergy*
      - "!SunpowerPerDay_Total"
    strategies:
      - everyChange
      - restoreOnStartup
    filters: []
  - items:
      - RoomHumidity*
      - RoomTemperatures*
    strategies:
      - everyChange
      - restoreOnStartup
    filters: []
  - items:
      - Weather*
    strategies:
      - restoreOnStartup
      - everyChange
    filters: []
  - items:
      - ShellyEM3_EnergyPerDay_Total
      - SunpowerPerDay_Total
    strategies:
      - everyChange
      - restoreOnStartup
      - everyMinute
    filters: []
aliases: {}
cronStrategies:
  - name: everyMinute
    cronExpression: 0 * * ? * *
  - name: everyHour
    cronExpression: 0 0 * * * ?
  - name: everyDay
    cronExpression: 0 0 0 * * ?
thresholdFilters: []
timeFilters: []
equalsFilters: []
includeFilters: []

RRD4J:

configurations:
  - items:
      - "*"
      - "!ShellyEM3*"
    strategies:
      - restoreOnStartup
      - everyChange
      - everyMinute
    filters: []
  - items:
      - "*"
      - "!SunEnergy*"
      - "!Weather*"
    strategies:
      - restoreOnStartup
      - everyChange
      - everyMinute
    filters: []
  - items:
      - "*"
      - "!RoomHumidity*"
      - "!RoomTemperatures*"
    strategies:
      - restoreOnStartup
      - everyChange
      - everyMinute
    filters: []
aliases: {}
cronStrategies:
  - name: everyMinute
    cronExpression: 0 * * ? * *
  - name: everyHour
    cronExpression: 0 0 * * * ?
  - name: everyDay
    cronExpression: 0 0 0 * * ?
thresholdFilters: []
timeFilters: []
equalsFilters: []
includeFilters: []

MapDB

configurations:
  - items:
      - "*"
      - "!ShellyEM3*"
    strategies:
      - restoreOnStartup
      - everyChange
    filters: []
  - items:
      - "*"
      - "!RoomHumidity*"
      - "!RoomTemperatures*"
    strategies:
      - restoreOnStartup
      - everyChange
    filters: []
  - items:
      - "*"
      - "!SunEnergy*"
      - "!Weather*"
    strategies:
      - restoreOnStartup
      - everyChange
    filters: []
aliases: {}
cronStrategies:
  - name: everyMinute
    cronExpression: 0 * * ? * *
  - name: everyHour
    cronExpression: 0 0 * * * ?
  - name: everyDay
    cronExpression: 0 0 0 * * ?
thresholdFilters: []
timeFilters: []
equalsFilters: []
includeFilters: []

I’ve got no ZRAM.

Concerning the event.log files this time there were two *.gz files (event.log.5.gz and event.log.7.gz) while event.log.6 was not zipped and contained only 4 lines.

I tried to do everything correctly and be grateful for any further help.

Norbert

The default logging config will only roll over the log files when they get to a certain size or when you restart OH. These files are small so the fact that the rule rolled over implies OH restarted in the time period. Otherwise it would have continued to write them to the same file.

The most recent file is event.log, then event.log.7.gz, then event.log.6.gz and so on.

OH can restart without the whole RPi restarting of course.

Why do you have restorOnStartup on everything? Each Item should only be restored from one database.

Why do you include * in every config? Looking at your MAPDB config you are literally configuring every Item three times. And then you do it again for rrd4j.

Here is where that can be a problem. If you’ve ever saved a value for any of the ShellyEM3 Items in mapdb, they will get restored by the second and third configurations. If you’ve ever saved a value for any of the ShellyEM3 Items in rrd4j, that value will get restored by second and third configuration of that persistence.

And because you have both of these persistence configs to not save to these databases any more that value can be very old.

You can confirm this by querying for the Shelly Item that jumps in value through the API explorer. I bet you’ll find that it’s 8602.557559848325 in MapDB or RRD4J or both.

I’d recommend changing your mapdb config to simply do everyChange and restoreOnStartup for all Items except members of RoomHumidity, RoomTemperatures, SunEnergy, and Weather in one single config. To be honest, I’d set mapdb to just save all Items on change and restoreonstartup.

Do the same for rrd4j but don’t use restoreOnStartup at all. That is now solely MapDB’s job. But definitely consolidate the config into one so you don’t have * undoing the previous configuration sections.

Finally, remove restoreOnStartup from the influxdb config entirely also. The separate configs are not causing problems here because you are not using *.

Make sure all your relevant Items had a chance to change state after making these changes before restarting OH.