Number item usage

I used temperature items of type number:temperature. This had the disadvantage of having to transform them before assigning or using them to a number like this.

temperatur = (TemperatureItem.state as Number).floatValue
SolltemperatureItem.sendCommand((TemperatureItem.state as Number).floatValue)

To make code easier I changed the type from number:temperature to number.
I thought this would work now:

temperatur = TemperatureItem.state
SolltemperatureItem.sendCommand(TemperatureItem.state)

But Visual Studio with the OH addon shows the following errors:
“Cannot convert from State to Number” and “Cannot convert from State to Command”

temperatur = TemperatureItem.state as Number
SolltemperatureItem.sendCommand(TemperatureItem.state as Number)

works.
Why is it necessary to convert a number item to a number?
Is there a why to avoid this?

Please use code fences (the second last icon in your editor menu). Probably very few peole here are going to help when there are no code fences.

I think that

temperatur = TemperatureItem.state

will be interpreted as string variable

Don’t. Maybe this will help -

States are not commands, even when they look alike. Sending xxxItem.state as a command is quite often problematic. You’ll find it does not work with a simple Switch type Item.

someSwitch.sendCommand(otherSwitch.state) // this will FAIL
// because state OFF is not command OFF

Although when it is a Number or a Quantity (number with units), it usually works.

The bomb-proof workaround is to send a string as command, because the command parser will always try to parse out the type of command it is looking for.

myItem.sendCommand(otherItem.state.toString)
2 Likes

No, it will be a State. In this case a DecimalType.

Because it’s not a number. It’s a State. It’s not until runtime that the rule will know what sort of subclass of State it really is. For a Number Item it can be UnDefType (i.e. NULL or UNDEF) or it can be a DecimalType. Or if it has units (e.g. Number:Temperature) it can be a QuantityType.

VSCode doesn’t even know that TemperatureItem is even a Number Item so as far as it’s concerned TemperatureItem.state can be any of the 15 subclasses of State, only two of which have a .floatValue method. You have to tell it that the state is one of those with a .floatValue because you know it’s a Number Item.

Notice how Number isn’t one of the State subclasses. But we can still cast the state to Number because DecimalType implements Number too so we can treat it like a regular old Java Number.

However, that rule will fail when you Item is NULL or UNDEF which can happen to any Item type.

As for why you have to cast the Item’s state to send it as a command, see @rossko57’s reply. sendCommand requires a Command, not a State. Not all States are also commands and the opposite as well, some Commands are not States (e.g. INCREASE is a Command, not a State).

Thanks Rich for your explanation.
I am looking for a kind of bullet proof generic conversion expression from any number type (no matter if it is integer, decimal with or without quantity subclasses) into integer or decimal.

My idea is to add that expression to every item.state statement in the future so that I do not need to take care in detail what type of number item is. I just want to care about what number type iI need to proceed with my rule code.

Do you have a suggestion for that expression. I have seen quite a few but do not know if they work „generically“

No such single expression exists.

First you have to distinguish between: short, int, long, float, double, Short, Long, Integer, Float, Double, Number, BigDecimal, DecimalType, and QuantityType. If you have a QuantityType you then have to pay attention to the units and make sure they are compatible which is another couple of dozen comparisons in the expression.

And even if you do have one expression that converts everything to a primitive into or float, you are likely to encounter cases where you get the wrong answer. For example, you may have a Number:Temperature that appears to be 20 °C but in actuality is holding 68 °F. If you just blindly strip the units from the Item in the rule, you’ll end up doing the math with °F when you expected °C.

Furthermore you have the problem that some functions and expressions expect a number of a certain type. For example, you must pass an int to now.plusSeconds(), for example.

There really is no way around it. You have to know what you are dealing with and code accordingly. TANSTAAFL.

1 Like

Hi Rich,
thank you - I was hoping that there is a kind of general conversion available such as .toString() for string conversion.
I somehow was expecting that answer.