OH 3 to OH 4 : most percentage values are now divided by 100

I have just migrated from OH 3.4.5 to OH 4.1.1 and while most things went fine, I have noticed a very disturbing issue with almost all “percent” items in that their value is now divided by 100.
The display still shows a valid percentage value but if I go to the Analyze graph, it’s all squeezed down between 0 and 1.
And the rules I wrote now receive this 0…1 value instead of the full 0…100 they were receiving before.
Here is an example with a humidity channel:

The percentage is nice, but if I show the graph, I get this:

The sudden drop is right at the time I migrated to OH4.

I could fix it for the only “Generic MQTT thing” that I have by editing its channel definition from this:

configuration:
  stateTopic: rtl/433/Cotech-367959/238
  transformationPattern: JSONPATH:$.humidity
  unit: "%"

to this:

configuration:
  stateTopic: rtl/433/Cotech-367959/238
  transformationPattern: JS:| JSON.parse(input).humidity * 100
  unit: "%"

But I can’t do this for all other channels as they are not editable at all, as the one shown above which is a “HomeAssistant MQTT Component” thing.

How can I then fix the current situation and get back to a situation where history is properly displayed like it was in OH3?

Add the % unit to the item instead of the thing channel

But I have no control on the Thing channel for most things as they are handled by the binding they come from!

That’s why you should not do it at the thing, but at the item

ok, but why do I have to do anything to begin with?
Shouldn’t the item be properly created with everything working “out of the box”?
And what should be done? Adding a “unit = %” metadata on the item?

That’s really cumbersome when migrating but it’s even less logical when working with an empty 4.1.1 system. The end user should not have to care about this.

The item is correctly created

Because you want to change the ootb behavior, therefore you need to apply configuration

No it’s not. Maybe a different user will use the number:dimensionless type for something else then % number, then the ootb settings will work perfectly

For number: dimensionless the default unit is # not %

If you want to change the unit of an item, you need to add unit metadata to an item.

But what if the binding knows about the “percentage” nature of the channel?
Why would I, as a user, need to add the unit metadata to an item? Shouldn’t it be propagated from the channel to the item?

Feel free to create an issue for this enhancement or even contribute code to build that feature.
It’s an voluntary open source project

I had exactly the same issue. By adding the unit the problem is solved…
The reason: The binding does not send the “%” but just a raw value. This value is transformed to [0-1].

If you have 2 items (one with and another without unit) getting the data from the same channel:

Number:Dimensionless weatherActClouds      {channel="openweathermap:weather-and-forecast:api:local:current#cloudiness", unit="%"}
Number:Dimensionless weatherActCloudsOld   {channel="openweathermap:weather-and-forecast:api:local:current#cloudiness"}

you get this result:

Feel free to create an issue for this enhancement or even contribute code to build that feature.

Well, thing is, I already have: PercentageType displays as decimal (less than 1) - #5 by obones

And despite using the right quantity type which worked just fine in 4.0 I had to add the unit metadata to the item in a fresh 4.1 instance.

I must have missed something in the announcements here, but I must say that the current situation with percentages is very confusing, even when knowing (parts of) the internal code.

Maybe the misunderstanding is, that number:dimensionless is not only used for percentage number, but also for other numbers, their is not % per default.

You maybe get more attention to this if you log it in github

Actually, there was an issue on a very similar subject so I posted a comment in it:

First section of breaking changes listed for OH 4.

A deliberate decision was to not allow this. The Thing can push State Description patterns to the Item which controls how it appears, but to control the unit of the actual state of the Item is 100% in the end user’s control. If the user chooses to not define the unit, the system default is used.

With or without the unit, the actual state of the Item will be converted to the unit defined for the Item.

In the case of Dimensionless, the system default is a simple ratio, not percent. So any update sent to such an Item will be converted to a simple ratio.

Since OH 4.1, every place you can create an Item in MainUI, you have the option to set the unit right when you create the Item. If you are using .items files, well you know what you are doing. The field gets pre-populated with the system default so you know what it will be if you choose not to set it.

It’s primarily confusing because the way UoM worked in OH 3 and before was not well defined nor well structured. Sometimes the unit comes from the binding. Other times it comes from the State Description pattern which should be only for formatting the display of the state, not controlling the unit of the Item’s actual state. You could end up with a plain Number Item that is carrying a unit. restoreOnStartup behavior was, to put it bluntly, indeterminate.

UoM in OH 3 and before was just one step short of a disaster.

Now in OH 4 you can always know what unit the Item is carrying and you have full control over it. There is a clear separation between what the user wants and what the binding delivers. An no more is it ever unclear where the unit comes from or what unit is being used.

The main confusion here stems from the fact that the default unit for Number:Dimensionless is ONE and not %. So if you don’t set the unit metadata, any update sent to this Item will be converted to ONE.

1 Like

And that’s where the life of users would be much simpler if all humidity channels defaulted to % and %0.f%% because remembering this is a real pain point. I’m not even sure all users took the time to fix this but simply went “meh, it’s not working”.
Sure, openHAB cannot know that automatically but tools should be given to binding developers to provide the information to the system, hence the importance of the issue mentioned above.

I can see an argument for changing the default unit for Number:Dimensionless to % but it seems like way too little gain to invent yet another API for binding authors to inject more stuff into Items, then you have to provide a way for end users to override it, etc.

But it’s also the case that end users don’t have to remember to change it. They would have to actively ignore it when creating their Items.

It’s presented as an option same as name, label, et. al. in all the places where the Item can be created in MainUI. And it’s given a more prominent position than the category or even the semantic model and Group membership.

Changing the default value to % would most likely cause issues with other bindings using dimensionless for other purposes and we would be back to the start.
That being said, I can’t see any use case where “one” is a sensible default value, let alone that it confuses non native speakers like me who wonder “one what?” as one is most exclusively associated with the number and not anything else.

However, I maintain that the suggested “unit-hint” seems quite sensible to me, as it would provide the default value I’m looking for while leaving the current UI untouched where the user can change the “hinted” value.
The same would be needed for the state description pattern and I’d be sorted.

Or, another idea “out of the hat” is that there might be a need for a Number:Percentage specifically for things like Humidity, Battery Level… But this one would require quite a change in a lot of places and so might be out of the realm of possibilities.

Not just non-native speakers. There really isn’t such a unit called ONE but they needed to call a simple ration something. I think calling it ONE is what the upstream library choose to call it. The upstream library is also who chose this as the default unit. I think OH though does have some ability to change that.

Bindings can already push State Description patterns. And frankly I causes as much if not more problems than the default for Number:Dimensionless not being %. There are all sorts of weird interactions when the binding silently (there’s no evidence in the UI that the binding has supplied a state description) pushes options or command options or readonly or the like. Suddenly I’ll change the state description pattern and nothing happens because there are hidden options there that are taking over. And don’t even try to change the type of the Item through a profile. If you try to use the timestamp profile on a link from a binding that pushes state description all sorts of interesting and wrong stuff happens. And because it’s all hidden the user is left stumped and the solution is to open the code tab and enter a space for options (or what ever else is a problem) to override the stuff silently pushed from the bindings.

You see all this stuff as helping save users work. In my experience it causes all sorts of problems.

Probably less changes that creating a whole new API to provide a path for bindings to suggest a default unit and show it in the UI when creating an Item.

And it should be a simple matter to search to see if any binding is using the ONE unit at all. I’d be astonished if there is a single case. Changing the default unit for Number:Dimensionless to % would probably be the least amount of work over all. Bindings using other Number:Dimensionless units like db already have to deal with the default not matching so this wouldn’t change anything for those.

I am having the same (or a similar?) problem in OH4, but even although I have added the unit tag:

Number:Dimensionless battery_level "Battery Level" <oh:batterylevel> (batteryInformation,eBattery) ["Measurement", "Level"] {channel="modbus:sungrow-inverter:sungrowBridge:sungrowInverter:sg-battery-information#sg-battery-level", unit="%"}

The output I see is 1%, not 100%:


What am I missing?

You have unit defined so that’s good. I didn’t use items files though. Maybe you need to escape the unit: i.e. %% ?

Also, double check if this is just a display issue or the Item’s actual state is wrong. You can really see this in events.log.

No using %% does not seem right, then it also shows up that way in the UI.

My events.log shows entries such as:
Item 'battery_level' changed from 1 % to 0.978 %

But are these values before or after OH has processed them?