Rule calculation with UnitOfMeasurement in kWh leaves to unexpected result. Why is recalculation via Joule necessary?

Hi,
my environment is running since openhab2. For openhab4 I decided to transfer my rules to UoM and encountered a problem, when using items (with default unit kWh) and multiplying with a dimensionless number. The result is weird and I do not know why openhab is calculating in Joule (instead of kWh).

I defined the following items:

// Test Switch
Switch 		TestingActive 	"Testschalter"
Number:Energy   SomeValueInkWh  "Number in kWh [%.3f %unit%]"
Number:Energy   SomeValueInJ    "Number in J [%.3f %unit%]"
Number:Dimensionless  weatherActClouds            "Bewölkung: [%.0f %%]"          {channel="openweathermap:weather-and-forecast:api:local:current#cloudiness"}

In my rule I do the following calculation:

rule "ShowCase"
when
    Item TestingActive changed to ON
then
    SomeValueInJ.sendCommand(5)
    SomeValueInkWh.sendCommand(5)
    logInfo("Show case", "Wrong UoM J vs kWh :{}", SomeValueInJ.state)
    logInfo("Show case", "Part 1.1 of multiplication :{}", SomeValueInkWh.state)
    logInfo("Show case", "Part 1.2 as Number of multiplication :{}", SomeValueInkWh.state as Number)
    logInfo("Show case", "Part 1.3 as Number with 'J-recalc' of multiplication :{}", SomeValueInkWh.state as Number/3600000) // 3.600J * 1000
    logInfo("Show case", "Part 2.1 of multiplication :{}", weatherActClouds.state)
    logInfo("Show case", "Part 2.2 as Number of multiplication :{}", weatherActClouds.state as Number)
    val Number result1 = (SomeValueInkWh.state as Number) * (weatherActClouds.state as Number)
    val Number result2 = (SomeValueInkWh.state as Number/3600000) * (weatherActClouds.state as Number)
    logInfo("Show case", "Result 1 (Part 1.2 * Part 2.2) :{}", result1)
    logInfo("Show case", "Result 2 (Part 1.3 * Part 2.2) :{}", result2)
end

The result in the log is as follows:

2024-01-28 20:51:13.426 [INFO ] [.openhab.core.model.script.Show case] - Wrong UoM J vs kWh :5 kWh

2024-01-28 20:51:13.430 [INFO ] [.openhab.core.model.script.Show case] - Part 1.1 of multiplication :5 kWh

2024-01-28 20:51:13.433 [INFO ] [.openhab.core.model.script.Show case] - Part 1.2 as Number of multiplication :5 kWh

2024-01-28 20:51:13.439 [INFO ] [.openhab.core.model.script.Show case] - Part 1.3 as Number with 'J-recalc' of multiplication :5.00000000

2024-01-28 20:51:13.442 [INFO ] [.openhab.core.model.script.Show case] - Part 2.1 of multiplication :0.05

2024-01-28 20:51:13.445 [INFO ] [.openhab.core.model.script.Show case] - Part 2.2 as Number of multiplication :0.05

2024-01-28 20:51:13.457 [INFO ] [.openhab.core.model.script.Show case] - Result 1 (Part 1.2 * Part 2.2) :900000.00

2024-01-28 20:51:13.459 [INFO ] [.openhab.core.model.script.Show case] - Result 2 (Part 1.3 * Part 2.2) :0.2500000000

As one can see the passed “5” leads in any case to 5 kWh (even if I give as name Joule; expected).
But when I multiply this number with any dimensionless number openhab is transfering the kWh to Joule.
Where is my mistake? Which other UoMs are transfered to the “non-default unit”?
All manuals and discussions tell, I can put whatever I put, but calculation is done in “default unit”.

Try


Number:Energy   SomeValueInkWh  "Number in kWh [%.3f %unit%]" { unit="kWh" }
Number:Energy   SomeValueInJ    "Number in J [%.3f %unit%]" { unit="J" }

Hi Jim,

thanks for your support. By adding the “unit” metadata I can fix the unit. The “Joule”-value results now in Joule.

Let me rephrase my problem:
The value of 5kWh multiplied with (today 79; for 79% of clouds) should result in 395 kWh.
But this calculation (in kWh):

val Number result1 = (SomeValueInkWh.state as Number) * (weatherActClouds.state as Number)

results ind 1422000000 (probably J). For the correct result I have to divide it by 3600J * 1000 (J–>kWh)
Why is the conversion from kWh to Joule happening?
The openhab help is stating the default unit is kWh (the storage and calculation should run in kWh). In reality the calculation is done in Joule. I think the help text is wrong…

val result1 = (SomeValueInkWh.state as QuantityType).multiply(weatherActClouds.state as Number).divide(100)

Thanks Jim.

This solves my problem…
Even if I have to get used to a “number” being a different value than a “QuantityType”.

Take a look at JRuby. You can run both at the same time and slowly convert things one at a time.

You will do a lot less type casting, and that’s just the start. It saves you from having to write a lot of tedious and repetitive boiler plate code.

result = SomeValueInkWh.state * weatherActClouds.state / 100

That is what I wanted to do first… but multiplication without type casting to “number” is somehow not possible for state (at least for my items defined).

val Number result0 = SomeValueInkWh.state * weatherActClouds.state

leads to this error (there is no method “multiply” for “state”; already the VisualCode plugin is telling):

That last code is in jruby just to show you how writing rules could be so much easier