opened 09:42PM - 19 Oct 23 UTC
enhancement
#3481 was quite a leap forward in terms of making UoM predictable and reliable.
…
Now that the smoke has cleared, I see a small opportunity to improve/fine-tune the user experience without changing anything in the UoM logic itself.
A few examples where user experience could improve:
- A binding integrating a washing machine or dishwasher provides water consumption for a `Number:Volume` channel. Default metric unit **m³** does not make much sense in this context. In most cases it should be either litres or gallons.
- A binding integrating a car provides distances for a `Number:Length` channel. Default metric unit **m** is not ideal. In most cases **km** would be preferred (similar for imperial).
- A binding provides relative humidity in percent for a `Number:Dimensionless` channel. Default unit **one** is not ideal, **%** would be expected.
- A binding provides loudness in decibel for a `Number:Dimensionless` channel. Default unit **one** is not ideal, **dB** would be expected.
Since the decision of which unit to use is (and should be) entirely up to the user, my only suggestion would be to add a possibility for bindings to give a **hint** about recommended units. The only usage of this hint would be for the UI to suggest reasonable default units when creating new items for channels.
In other words, this will not control or override anything, or make the inner UoM logic more complicated in any way. It would exist in parallel as something exposed by the relevant REST methods to be consumed by the UI in order to better assist the user. Additionally, it should be easy/light-weight for bindings to provide such hints, and the bindings should not have to deal with `LocaleProvider` etc. or duplicate any logic that could be implemented in core and webui.
The way I see this could be hinted by bindings would be to extend channel and channel-type definitions with an optional new tag. For example:
```xml
<channel-type id="humidity">
<item-type>Number:Dimensionless</item-type>
<label>Humidity</label>
<description>Relative humidity</description>
<category>Humidity</category>
<state readOnly="true"/>
<unit-hint>%</unit-hint>
</channel-type>
```
Or perhaps:
```xml
<channel-type id="humidity">
<item-type unitHint="%">Number:Dimensionless</item-type>
<label>Humidity</label>
<description>Relative humidity</description>
<category>Humidity</category>
<state readOnly="true"/>
</channel-type>
```
And likewise for channel:
```xml
<channel id="humidity" typeId="system.atmospheric-humidity">
<label>Humidity</label>
<description>Relative humidity</description>
<unit-hint>%</unit-hint>
</channel>
````
I'm not sure if it makes sense for channels. Perhaps it would be better to require a custom channel type in order to provide such hints, as being able to override at channel level will increase the complexity. I can't think of any use cases since channel types needing specialized hints are probably too generic anyway.
Now, a more complex example - the washing machine:
```xml
<channel-type id="water-consumption">
<item-type unitHint="l,gal">Number:Volume</item-type>
<label>Water Consumption</label>
<description>Water consumption by the currently running program on the appliance</description>
<category>Water</category>
<tags>
<tag>Measurement</tag>
<tag>Water</tag>
</tags>
<state readOnly="true" pattern="%.1f l"/>
</channel-type>
```
In this case two units are provided. This is because the hints should be interpreted in the context of the regional settings. So for a US user, **gal** should be suggested, and for a European user, **l** should be suggested. I think this distinction is important if we want to get it right. The hint doesn't dictate anything, but in order to be truly helpful, we should still respect those settings, like we also do when item unit is completely missing and must be defaulted.
Calling a method like this:
`http://openhab:8080/rest/channel-types/miele%3AwaterConsumption`
should then provide this hint (if this can be added while maintaining backwards compatibility):
```json
{
"parameters": [],
"parameterGroups": [],
"description": "Water consumption by the currently running program on the appliance",
"label": "Water Consumption",
"category": "Water",
"itemType": "Number:Volume",
"unitHint": "l,gal",
"kind": "STATE",
"stateDescription": {
"pattern": "%.1f l",
"readOnly": true,
"options": []
},
"tags": [
"Measurement",
"Water"
],
"UID": "miele:waterConsumption",
"advanced": false
}
```
I'm not sure where the processing of this list of units should happen. Ultimately, for regional settings in Europe, the unit to default would be "l". I'm not into the architecture here, just outlining my proposal as detailed as possible.
See also:
- https://community.openhab.org/t/oh-4-units/148410/1