# OH3 ==> OH4: multiplication in rule fails

Dear community!

I recently upgraded from OH 3 to OH4.2, and I have a problem with one of my rules:
A mathematical operation (multiplication), which worked in OH3 now fails, and I don’t really know why:

I have a powermeter, and it stores its Energy counter values in influx. This works, the database gets filled.

For the mathematical operation I take the value of the items and store them in variables:

``````var Enow=item.state
var Edelta=item.deltaSince(now.minusMinutes(20),"influxdb")
``````

This works:
`logInfo("rule","Energy now {}",Enow)`
==>:
`Energy now: 469.0841 kWh`

and
`logInfo("rule","Energy change {}",Edelta)`
==>
`Energy change: 0.058 kWh`

so, this looks good, and Energy carries the correct unit, kWh.
Given, the deltasince should carry something like Watts, but but let’s not be so picky…

Now, I run a rather simple calculation on Edelta, and this fails:

``````var Number a

a = Edelta * 60 / 20 * 1000
``````

I get:
`Script execution of rule with UID 'cafemaschine-10' failed: Unknown variable or command '*';`

can it be the units?
In OH3 this worked without problems.

Thanx,
Sulla

It was indeed the units: OH4 does not like multiplication of `item.state` with a number.

I solved it like this in my rule:

``````val Number Edelta = item.deltaSince(now.minusMinutes(20),"influxdb")  // energy in kWh
val Number dE = Edelta * 1       // this converts kWh to Ws (Joules) consumed within 20 minutes
val Number P = dE / ( 20 * 60 )  // dimensionless, but is Watts

item2.postUpdate(P)  // item explicitly defined to be in Watts, so it accepts P and assumes Watts
``````

note that the direct multiplication with 1 did not work:
`val Number Edelta = item.deltaSince(now.minusMinutes(20),"influxdb") * 1`
produced the same error:
`Script execution of rule ... failed: Unknown variable or command '*'`
I first had to put the item state into a number variable, then the multiplication worked.

Mathematical operations are notoriously difficult when units are involved…

Edit: I had the “|” symbl in the wrong place, edited to correct the error.

In OH 4 a lot of that has become aleviated. It also helps to remain within units when doing the math. But Rules DSL often still has problems doing the automatical type detection and casting without some hints and help. And the main problem you are running into here is you are trying to strip off the units without casting before doing your math.

If you stay working within the UoM…

``````val P = (item.deltaSince(now.minusMinutes(20), "influxdb").toUnit('mWh') / 20|min).toUnit('W')
``````

If that works P will be a `QuantityType<Power>` with default units of `W`. Though that doesn’t really matter as what ever is sent to `item2` will be converted to that Item’s `unit` metadata or the default for that Item type. So even this is over done, but I like that it’s self documenting. The minimum would be

``````val P = item.deltaSince(now.minuteMinutes(20), "influxdb") / 20|min
``````

OH will convert the units as necessary.

If that doesn’t work, we may need to help OH know what type we want from the deltaSince.

``````val P = (item.deltaSince(now.minusMinutes(20), "influxdb") as QuantityType<Energy>) / 20|min
``````

Again, what ever the units are that result from that calculation will be converted to what `item2` is defined to use automatically. You don’t need to worry about that.

Or, if you really don’t want to mess with units at all, you should probably just use `Number` Items in the first place. The units will be stripped from the states of the Items automatically and you’ll just have plain old numbers.

Of, if you want to keep the units in the Item states but don’t want to mess with them in rules (not something I recommend but it can be done):

``````val P = (item.deltaSince(now.minuteMinutes(20), "influxdb") as QuantityType<Energy>).toUnit('Ws').floatValue / (20 * 60)
``````

Given your original calculation doesn’t actually convert to `Ws` maybe you don’t need the `toUnit`.

Note that in jRuby and JS Scripting working with QuantityTypes is a bit more straight forward since casting isn’t required and there are lots of help built into the languages. Blockly has a set of blocks for working with QuantityTypes but it’s also very straight forward.

In JS Scripting:

``````var P = item.persistence.deltaSince(time.toZDT('PT20M'), 'influxdb').divide('20 min');
``````
1 Like

Wow. Rlkoshak, it is always inspiring what you are posting.
I’ve never seen an operation like
`/ | 20 min`
I’ve only ever used the vertical dash operator to specify units, but never with a number to it.
I have to think a bit more about that.

Besides, I am the type of person that you think does something you don’t recommend: keep units in items, but make calculations on bare numbers…
I’m just not good enough for all this `as QuantityType`, `as Number`, `toUnit` and `floatValue`… stuff, let alone combinations of it.

That two operations.

`/` is a simple divide.

`| <number> <unit>` `<number>|<unit>` is the short hand in Rules DSL to create a number with units. So `| 20 min` `20|min` means “20 minutes”.

This is documented at Textual Rules | openHAB.

Well, if the Items have units you have to deal with that stuff in your rule. So if you don’t think you are good enough to deal with it the only way to avoid it is to use plain `Number` Items instead of using Numbers with units. You will always have to do something to get the number out of the plane number out of the `QuantityType` (`as Number`, `floatValue`, etc.).

Since you always have to do something when you have units, you may as well take advantage of what the units provide. Otherwise all you are really doing is making things harder on yourself.

Note, in Blockly there are blocks that make working with units pretty straight forward. In JS Scripting the Item has `items.MyItem.numericState` and `items.MyItem.quantityState` which makes it easier.

Isn’t it “<number> | <unit>” ? That’s what is shown as examples on the documentation mentioned.

You are correct. The pipe goes between the number and the unit, not before. I’ll update my replies above.

Thanks for noticing!