Gardena and OH 4 UoM Issue

I just migrated from OH v3.4.x to OH v4 and Gardena is one of the very few bindings where I encountered issues due to the new OH4 treatment of UoM. In particular I had issues where soilHumidity and batteryLevel values were 100x too large. In my case I could resolve it by adding unit="%" metadata to the items. However I think that probably the binding java or xml code needs to be adjusted. => @lsiepel ??

	<channel-type id="soilHumidity">
		<item-type>Number:Dimensionless</item-type>
		<label>Soil Humidity</label>
		<description>Soil humidity in percent</description>
		<state readOnly="true" pattern="%d %unit%"/>
	</channel-type>

No, you did what needs to be done. The default unit for Number:Dimensionless is ONE which represents a generic ratio. By defining the unit metadata you’ve told OH what units you want the Item to carry. Bindings can supply the units used to display the Item’s state in MainUI but they cannot control the unit that the Item actually stores (and gets stored to persistence. That’s why you need to define the unit metadata.

@rlkoshak of course I fixed it, but yet the <state readOnly="true" pattern="%d %unit%"/> in the binding xml still makes me wonder – I think perhaps this should be changed to <state readOnly="true" pattern="%d %%"/> so that the default unit is set in the binding. And/or the Java code should explicitly output a QuantityType rather than a DecimalType…

The unit for the Item’s state is defined in the following ways now.

  1. if unit metadata is defined on the Item. that is the unit that is used
    a. if the state update includes a unit, the value is converted to the unit
    b. if the state update does not include a unit, the value is assumed to be unit

  2. If no unit metadata is defined on the Item, the system defualt is used.
    a. if the state update includes a unit, the value is converted to the system default.
    b. if the state update does not include a unit, the value is assumed to be in the system default unit.

The state description pattern only affects what unit the value is shown in MainUI.

The binding has no ability to set the unit metadata.

The system default unit for Number:Dimensionless is ONE.

Given all those combined, I’ll repost a table I just made on another thread.

Published State Unit Metadata Item’s State
12 12 ONE
12 % 12 %
12 % 1200 ONE
12 % % 12 %

Because the unit metadata isn’t set on the first row, the unit ONE is applied. Because the unit metadata isn’t set on the third row, the % is converted to ONE and that becomes the state of the Item. And there is nothing the binding can do to set the unit metadata.

However, by setting the pattern to %% instead of %unit%, the state of the Item will appear in MainUI as a percent. But even there it’s tricky.

Published State Unit Metadata State Description Pattern Item State What you see in MainUI
12 absent or %unit% 12 ONE 12 ONE
12 % absent or %unit% 12 % 12 %
12 % 12 ONE 0.12 %
12 % % 12 % 12 %
12 % absent or %unit% 1200 ONE 1200 ONE
12 % % absent or %unit% 12 % 12 %
12 % % 1200 ONE 12 %
12 % % % 12 % 12 %

The only time that the Item state and what you see in MainUI match is when the Unit Metadata is defined. The binding can push %% as the state description pattern and it will appear correct in MainUI, but it won’t be right in rules and won’t be saved correctly in persistence. And until charts become unit aware, the charts will not look correct either.

When the unit metadata is not defined, the state of the Item uses the system default unit of ONE. The state description pattern will convert between ONE and % but it won’t change the Item’s state. There had to be a strict separation between determining the Item’s state and how it’s displayed. And there was a deliberate decision made to not provide a way for bindings to set the unit metadata.

Many thanks @rlkoshak – I will look at the binding code, and probably make a PR.

@rlkoshak when you talk about ‘published state’ in your table (e.g. 12 %) it seems to me that the binding code could deliver one of several data types PercentType(12) / DecimalType(12) / DecimalType(0.12) / QuantityType(0.12) or possibly other combinations. I would imagine that an explicit QuantityType would be the best practice. Or??

I’m not sure best practice has changes along those lines. If it’s going to support units, it should update with a QuantityType. None of the other types handle units.

If the Channel is linked to a plain old Number, the QuantityType will be converted to a DecimalType in core. The binding doesn’t have to worry about that.