Units of measurement/Quantity Types have been around since before OH 3. I think they were introduced in the 2.2, 2.3 time range so they’ve been around a long time.
What’s changed in OH 4 is that the end user has much more control over what units get applied to their Items.
The general order of precedence for pre-OH 4.0 was:
- units in the State Description Pattern
- units of the Item as delivered by the binding
- system default units for that UoM (e.g. if it was a Number:Length and no other units are provided, meters is assumed if SI is selected for default or feet is the default if imperial units are selected).
But it gets complicated because bindings can stealthily set the state description pattern for you and that setting didn’t show up. There was even a bug where the binding set units took precedence over the units set by the user by overriding the State Description pattern. Plain old Number
Items could end up with a QuantityType state. The State Description pattern could be overridden by the end user (once that bug is fixed) but that didn’t change the actual state carried by the Item meaning that the value persisted may be different units from what the State Description says. The problem there is that the State Description was the only hint to Persistence to tell it what units to restoreOnStartup leading to a missmatch.
Overall it was a nightmare to use and to support.
In OH 4 the order of precedence is now:
- the unit defined in the
unit
Item metadata
- the unit in the QuantityType posted to the Item
- the system default
If you send a QuantityType to a plain old Number Item, the unit is stripped and the State will be a DecimalType.
If you send a DecimalType to a Number:X
Item, the unit will be derived based on the order of precedence above.
If the unit
metadata is defined and the binding posts a QuantityType with a different unit, OH will convert it to the user’s unit
so the Item’s state will always be in the user defined units. This means restoreOnStartup and the REST API users can trust that the units are correct.
Only end users can set the unit
metadata and that unit
is the one used to control the State of the Item.
The State Description pattern now only changes how the Item appears in the UIs and is no longer used to make decisions like what unit a value restored from persistence is in or how to handle a number posted without units.
As a result, what unit gets applied to the Item’s state is fully controllable by the end users, as it should be. Conversions from what the binding publishes when necessary are handled automatically. And you can choose different units for the Item to hold from what is shown in the UI if needed. I believe bindings can also offer State Description metadata still but they cannot offer unit
metadata.
If a user chooses not to use UoM, they can define their Items as Number
and have them stripped. If they want to use units even if the binding doesn’t offer one, they can define the unit
metadata