Decimal Item is shown as Float, why?

Hello, i have a decimal item, defined in a .item file. Since my last update it worked and could be read via REST-API as dec. Since the update last night ( openHAB 4.2.0 Release Build) i read a float instead. now all my external displays run out of space as now they have to show more information…like instead of 78% its now 78.0%. Also the information itself is only DEC, so its not worth any additional information.

Here is my item:

Number VeBatSoc "LiFePo4 SoC [%d %%]" <battery> (VE) { channel="mqtt:topic:mivenusgx:victron:VeBatSoc" }

Here is what is stored based on an REST.API Request…
image

Any idea what has changed from the latest milestone to the final release so that an untouched item now presents itself as FLOAT…but defined as %d.
Any idea how to fix this/force to be stored as dec and not float?

Kind Regards
Norbert

I can’t answer the first part but for the second part…

You don’t. It is stored as a Number. The %d only controls how that Number is displayed in the UIs and even then, in case of MainUI, it only controls how it’s displayed in some places. For example, the Settings → Items page only shows the raw Item state, not the formatted state. If you have custom widgets, you need to use the items.MyItem.displayState or @MyItem or else it defaults to the unformatted state.

@rlkoshak thanks for the clarification! Its not about OH internal widgets that are taking these values. Its external reading devices that call the http get request…via RESTFUL.API

similar to: http://192.168.1.11:8080/rest/items/VeBatSoc/state

the result you know… its a float and not a decimal number. i get that the %d only refers to the presentation. But is there a way to make the values stored in this VeBatSoc item be handled directly as only decimals. This item is fed by MQTT.

There has been some changes to that part of OH in OH 4.2. But it has always been the case that the actual state of the Item is returned by the REST API, not the formatted state. I’m not sure why this would have changed.

Do you integer? A decimal number is a float. Or to be more correct, a float is one type of decimal number.

If your values are always integers and always between 0 and 100 you can use a Dimmer Item. Dimmer Items carry a PercentType which can only be an integer between 0 and 100. Beyoind that, a Number type Item always carries a DecimalType which itself represents the state using a BigDecimal. A Number Item’s state is never a float nor an int.

If this value is being consumed by some web UI outside of OH’s, you might need to adjust those to modify the value as desired. Note that the state description pattern as well as the state is available at the /items/{item name} endpoint.

sorry for all this confusion.
its a house battery state-of-charge…integer value 0…100.

I spent some time and manged via Number:dimensionless.

Only - one for me - hard to understand phenomena is the following labelling artifact.

if i do the item labelling the follwing way:

[%d %%]…i receive a 5600 % in BasicUI
if i do the same without a “space” between d and % [%d%%] it shows like this 56%.
It looks a little weird compared to the rest as now the number sticks so close to the unit.
But even more, why does this space ruin it all ??

Kind Regards, Thanks
Norbert

Number:Dimensionless is a number between 0 and 1. When formatted as percentage, it gets multiplied by 100. I assume you have set it to e.g. 56 instead of 0.56 (Decimal type) or a56 % (QuantityType).

The Problem is that the value comes in via MQTT and for whatever reason (even though its simple integer values) they are sent as 56.0 or 98.0 like float.

The thing line looks like this:

Type number : VeBatSoc "LiFePo4 SoC" [ stateTopic="N/0c1c57111e38/system/0/Dc/Battery/Soc", transformationPattern="JSONPATH:$.value" ]

Is there a way (e.g. via formatPattern?) to already change it at this point to int without the “comma zero”.

Kind Regards
Norbert

When you set the state description pattern as [%d %%] OH splits it on space and try to infer the unit from the second part. When this is set as percent (%) and the unit is one (the default unit for Number:Dimensionless) it converts it, which means multiplying with 100. Without the space, OH can’t infer a unit and the original state is returned.

The solution is to explicitly set the unit metadata to percent. Then OH will interpret any incoming unitless value as this unit and will handle conversions properly.

To elaborate a bit on what has laready been said here.

I really should just post a new tutorial I can refer back to since I’ve had to type this up so many times.

When you are dealing with UoM there are three places where the unit could be set. What it means to set the unit at each location is different and there is a default behavior when it’s not set.

So first of all, if you don’t want to use units at all, only use Number Items. Any unit from a value sent to such Items gets stripped off (note this is a different behavior from 3.4).

  1. At the Channel: This lets the binding indicate what unit the value it is publishing. MQTT lets you set the unit in the Channel Config. If not set, any value posted to an Item without a unit will assume the unit of the Item (see 2) without transformation.

  2. At the Item unit metadata: This defines the unit of the state the Item carries and what unit is used in persistence. If a value is posted to an Item that is different from unit, the value is converted to unit. If there is no unit on the value posted, unit is assumed. If there is no unit metadata, the system default unit for that UoM type is assummed. For Number:Dimensionless, as @maniac103 points out, the system default is one which is a simple ratio. n one == n*100 %.

  3. At the Item state description pattern: This defines how the Item’s state appears in UIs in most (but not all) places. If the pattern unit is different from the unit the value is transformed before display.

So, given the above described behavior your Channel doesn’t define the unit and your Item doesn’t define the unit metadata but does define the state description pattern. So the Channel publishes 56. The Item gets the 56 and appends the unit one to it as that’s the default. And your state description pattern converts 56 one to 5600 % for display.

If you want to use UoM, set the unit property on the Channel to % and the unit metadata on the Item to %. Then the value will be treated as a % through the whole chain of processing.

Since OH 4.2 when creating Items through the UI the unit metadata is always defined on the Number:<Type> Items so you’ll never have a case where you have to rely on the system default and you always know what unit the Item’s state is in.

Ultimately, as soon as any math is done on the state of the Item, it’s going to start using decimal palces in the Item’s state. It might be sufficient to set up all the UoM stuff like described above to avoid any conversions on the value. But ultimatly formatting decisions are usually left up to the thing displaying the value. Since this isn’t OH that is displaying it you ultimatly might need to do the work there, or go through some workaround in OH to create a proxy String Item or use a String Item in the first place or something like that.

An OH Number Item doesn’t have a concept of integer verses float. It stores a Number (a Java BigDecimal to be precise). You can’t force the state to be one or the other. You can only cause it to display as an integer, but that doesn’t change the state of the Item nor does it change what is returned by the REST API when you pull the state of the Item that way.

Usually though if you start out with an integer the BigDecimal won’t show the decimal places unless and until you do some math on it. However, there were some changes made to the default patterns that are applied when a State is rendered which might have made it such that all Number Items now shpow with a decimal place. I don’t know if that’s for sure but I do know that a number of Item types were addressed in that PR.