Javascript persistance totals off

I’ve just upgraded to openHAB version: v5.0 and just getting some odd values when I get the persistence totals. I’m getting some inconsistent output when I query history for this value vs SQL/db look up.
ie using JS persistence.sumSince I would expect this would return the sum of all from today same as from DB query.
Has anything changed with Javascript persistance?

what is the best way of getting midnight?
Javascript code:

 Energy_Mains_energy_interval = items.getItem("Energy_Mains_Total_interval")
var daySoFar = Energy_Mains_energy_interval.persistence.sumSince(time.toZDT("00:00")).numericState //sum since midnight 
console.log("Energy: this daily= " +  daySoFar);

output:

Energy: this daily= 124353240

SQL code:

select sum(value)  from energy_mains_total_interval_46
where time >=  '2025-07-27 00:00:00';

output:

34.57649999999999

No and ultimately all the persistence actions are implemented by core. JS just provides a wrapper around that Java implementation.

time.toZDT('00:00'), same as your are doing.

You should log it out to verify there isn’t something odd going on with timezones or something like that.

UoM shouldn’t be an issue either but it might be something to check on.

nope TZ look ok , this only started after the upgrade to OH 5.0 , is this a bug?

var midnight=time.toZDT("00:00");
var daySoFar = Energy_Mains_energy_interval.persistence.sumSince(midnight).numericState //sum since midnight 
console.log("Energy: this daily= " +  daySoFar + ' md: '+ midnight);

output

Energy: this daily= 82092600 md: 2025-07-28T00:00+10:00[Australia/Canberra]

I just output the state and its returning the following:

Energy: this daily= 3164219.9999999999812800000 Ws

what is “Ws” Watt Second? and how did was this unit type assigned ?

items:
  Energy_Mains_Total_interval:
    type: Number
    dimension: Energy
    label: Energy Mains Total watt minutes
    icon: energy
    groups:
      - Power_meter
    tags:
      - Sensor

If I divide this value by 3,600,000 I get pretty close to what I expect, how is persistence returning this unit

Probably.

Have you set the unit metadata for that Item?

Persistence saves the state of the Item as a number. During queries and restoreOnStartup it assumes the unit of the Item is the unit of the result.

If no unit metadata is on the Item, the system default is assumed. I thought the default for Energy was Wh but it might be Ws.

Regardless, the Item is using Ws as the unit so the Item’s state is always in Ws and therefore all the values in persistence are in Ws also.

Note that there is a UoM value saved in the Persisted state methods. So you could get the result and convert them to Wh with

var daySoFar = Energy_Mains_energy_interval.persistence.sumSince(midnight).quantityState.toUnit("Wh"); 

Or you can set the unit metadata on the Item to “Wh” and the Item’s state and therefore the persistence calls will all be in “Wh” by default. However, the changes are not retroactive. The values already stored in persistence will not be adjusted. Furthermore, those old values will be assumed to be in Wh so your calculations with be way off.

The only part I don’t quite understand is how the SQL query is returning the correct value in Wh. I don’t use SQL so it might be that those databases, which can be more flexible than rrd4j for example, do some unit conversions for you. I don’t know.

yep this worked :slight_smile:

var daySoFar = Energy_Mains_energy_interval.persistence.sumSince(midnight).quantityState.toUnit("kWh").float.toFixed(3);

how do I override default unit in the item ?
I have coded in UI:

Number:Energy Energy_Mains_Total_interval "Energy Mains Total watt " <energy> (Power_meter) [Sensor]

converted to file config:

Number:Energy Energy_Mains_Total_interval "Energy Mains Total interval" <energy> (Power_meter) [Sensor]  { unit="kWh" }

It looks like you already have the unit metadata set. You override it by setting the unit metadata as is shown in your file config:

I can’t say why that’s not working. The unit metadata is supposed to always take precedence over everything else.

Does the Thing call for a Number:Energy Item or just a Number Item?

Thanks fhz

I had similar issues with persistence actions, I have an Item connected to the Tibber binding for getting spot prices, and wanted to calculate the standard deviation for the last 14 days. The Item has unit set to SEK/kWh, but when using the deviationSince action returns the value as “SEK/(W·s)”. I thought this was due to the calculations done to get the deviation (and it is only when logging the value it’s noticeable, when updating an Item with correct unit, everything works as it should), so didn’t pay it much mind. But when I saw this thread I got curious and tested different actions:

sumBetween:  0.00002307075685555555736111111111111111295677165955555570 SEK/(W·s)
riemannSumBetween:  0.08305472468000000650000000000000000664437797440000052000000 SEK/W
averageBetween:  1.153537842777778 SEK/kWh
varianceBetween:  1.727235649434239E-14 SEK²/(W²·s²)
deviationBetween:  1.314243375267397E-7 SEK/(W·s)

The since deviation is based on variance, it’s as I thought not surprising that the unit gets mangled and uses the system defalut. Not sure how the riemannSumBetween gets calculated, but should be similar to an integral, in which case it’s logical that the temporal dimension is removed.

But I would expect at least the regular sumBetween to return the correct unit.

Again, all values are correct, and if using the value to update an Item that has the correct unit set there’s no issue. But if it’s expected of the persistence actions to use the unit metadata (provided the result is in the same dimension as the Item) it seems to be a bug somewhere.

@mherwege, could this be a core bug?

I would think so javascript team replied this functionality is core feature they just call.

sorry I haven’t yet raised ticket

I wouldn’t call it a bug, as the calculated results are correct. There may be room for improvement. All calculations are done in the base unit. It may not matter for most units, but it does for things like temperature where the base unit is K. Also, persistence services could return individual values with different units if they store the unit with persisted values (the typical ones don’t, just assume the configured unit).

What could be an option is to convert the result of the calculation to the (adjusted for dimensional calculation) configured unit in code.

The main issue for me is understanding what the base or default unit.

For me it must have changed in the last upgrade

There was never a guarantee the calculation would return a result in the base unit. The issue stems from the fact that you just drop the unit and make the assumption it is in the base unit. If you get a QuantityType back, you should convert it to the unit you want before dropping the unit, or never drop the unit at all and keep calculating with Quantities. And that’s a dangerous assumption. It might have worked in some cases in the past, but it would have created totally wrong results for dimensions like temperature, or for persistence services that had values stored with different units.

I do agree the outcome has probably changed and I am not against adjusting it, but there will always be cases where it is unexpected if you don’t consider the unit.

There’s at least a difference in how units are handled in the different aggregators:

maximum, minimum, average, median, delta and evolutionRate uses this variant (get the configured unit):

        Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
        Unit<?> unit = baseItem instanceof NumberItem numberItem ? numberItem.getUnit() : null;

Whereas variance, deviation, riemannSum and sum uses this (get the system default unit):

            Item baseItem = item instanceof GroupItem groupItem ? groupItem.getBaseItem() : item;
            Unit<?> unit = (baseItem instanceof NumberItem numberItem)
                    && (numberItem.getUnit() instanceof Unit<?> numberItemUnit) ? numberItemUnit.getSystemUnit() : null;

Variance and riemannSum do some additional calculations on the unit (square and multiply with second respectively), so in those cases it might be better to use the system default, but for deviation and sum I see no reason not to use the configured unit?

Is there a particular reason, or should I submit a PR to change them to the top variant?

@pacive Deviation is calculated internally as the squareroot of variance. It also has a time factor in it. So as variance is already using system unit in its calculation, it keeps on working with that.

If you don’t use system unit for sum, you run into trouble with temperatures. I honestly think the old sum methods are pretty stupid, as the time dimension is completely ignored (that’s why I added Riemann Sums). But still, to get mathematically and physically meaningful and correct results, you have to do the calculation in system unit.

In many cases, it would be an improvement to convert the result to the base unit after the calculation and before returning it in the method. That would most likely pretty much align the result with what it was before. I am open for such a change in the code.

I believe all methods where it returns base unit at the moment are methods where the calculation results in the same quantity (apart from unit conversion) whatever the unit is used for calculation. Where there could be a different (and I am specifically referring to temperatures), it uses system unit.

That is closer to what the caller expects I think. They set the unit on their Item. Everything else goes out of it’s way to keep the values in that unit, setting the expectation that in the rule, one will always get the value in that unit.

If it’s feasible to convert the result of the calculation back to the expected unit I think that would be better.

So persistence can convert everything to K (for temperatures) to do the calculation and then back to degrees C or F before returning.

I created a PR trying to address this as much as possible: Persistence extensions: preserve item unit in results by mherwege · Pull Request #4951 · openhab/openhab-core · GitHub

2 Likes