Number:Energy in rules

In my OH3.x setup I had a lot of my items configured without UoM, so I thought to do it right in OH4.

I changed Number to Number:Energy and this is working fine: all values in kWh.

Number:Energy        mqtt_dsmr_electricityDeliveredDay   "electricity delivered day"

But my rule calculations are not working anymore.

In the past I used the following, but this is not working due the Quantity type:

var Number electricityDeliveredDay = mqtt_dsmr_electricityDeliveredNight.state as DecimalType

I found some info in the forum about QuantityType, so I tried it, but I get strange values as soon as a I do a sum of the value:

logInfo("Delivered", "state contains " + mqtt_dsmr_electricityDeliveredDay.state.toString)
var Number electricityDeliveredDay = mqtt_dsmr_electricityDeliveredDay.state as QuantityType<Energy>)
logInfo("Delivered", "QuantityType   " + electricityDeliveredDay.toString)
var Number test123 = electricityDeliveredDay + 1000
logInfo("Delivered", "SUM            " + test123.toString)

this gives as result:

state contains 618.534 kWh
QuantityType   618.534 kWh
SUM            2226723400

When I add .toBigDecimal I seems to be ok, but is this the correct approach? I found this info in this topic.

logInfo("Delivered", "state contains " + mqtt_dsmr_electricityDeliveredDay.state.toString)
var Number electricityDeliveredDay = (mqtt_dsmr_electricityDeliveredDay.state as QuantityType<Energy>).toBigDecimal
logInfo("Delivered", "QuantityType   " + electricityDeliveredDay.toString)
var Number test123 = electricityDeliveredDay + 1000
logInfo("Delivered", "SUM            " + test123.toString)
state contains 618.534 kWh
QuantityType   618.534
SUM            1618.534

I strongly recommend setting the unit metadata on these Items to exactly what units you want rather than relying on the system default. There are fewer surprises that way.

Well, yes. You’ve added a value without units to a value with units and explicitly stated you want a Number as the result.

In Rules DSL you are almost always best off if you never force the type of a variable unless you absolutely have to. Half the time it will simply ignore it and half the time it will change stuff behind the scenes to make it work.

When working with units, all the operands should define units.

logInfo("Delivered", "state contains " + mqtt_dsmr_electricityDeliveredDay.state.toString)
var electricityDeliveredDay = (mqtt_dsmr_electricityDeliveredDay.state as QuantityType<Energy>)
logInfo("Delivered", "QuantityType   " + electricityDeliveredDay.toString)
var test123 = electricityDeliveredDay + 1000 | kWh
logInfo("Delivered", "SUM            " + test123.toString)

See also this similar mistake I made:

I checked if I use all system default and if not I added the unit metadata, but if it’s safer to add it everywhere, I will do so :slight_smile:

I was indeed missing the part of |kWh and the declaration of my variable.

Thanks for helping me out!

I’m now setting an item with my calculated value, but is it normal that I need to convert this to a string? The item is a Number:Energy with the correct unit. If I just sent the variable, I get a stange error:

Ambiguous feature call.
The extension methods
	postUpdate(Item, State) in BusEvent and
	postUpdate(Item, Number) in BusEvent
both match.; line 16, column 767, length 10
var electricityDeliveredDay = mqtt_dsmr_electricityDeliveredDay.state as QuantityType<Energy>
var electricityDeliveredNight = mqtt_dsmr_electricityDeliveredNight.state as QuantityType<Energy>
var electricityDelivered = electricityDeliveredDay + electricityDeliveredNight
mqtt_dsmr_electricityDelivered.postUpdate(electricityDelivered.toString)

my item mqtt_dsmr_electricityDelivered is created like this:

Number:Energy        mqtt_dsmr_electricityDelivered      "electricity delivered"       (dsmr, Grp_db_every5min)    ["Status","Energy"]    {unit="kWh"}

I’ve never seen that error in JS Scripting but it comes from the fact that a QuantityType is both a State and a Number at the same time. And because there are two versions of postUpdate it doesn’t know which one it means. Converting to a String is the standard way to manage an error like that.