Finally switching to UoM: HowTo?

My openHAB installation is over 10 years old and I’ve got loads of items. Many of them contain measurements, I still use for comparison or I’d like to have also in long-term charts.

So, if I switch existing items with no UoM information to ones with UoM, it almost always messes with current persistences. e.g. percentages of batterylevels or lengths, … almost never do I use the standard unit in these cases and therefore persisted values are off like factor 100 or 1000 or whatever the difference is.
of course I also have to adjust my rules, which presently mostly strip units, but I want to use the “automatic” unit conversions coming also with JS-Scripting and all. but that’s another thing, I guess.

Is there a best practise approach to tackle this? I can change all values in my MariaDB for each item manually or via scripts. Can something similar be done with rrd, also? is there anything already here to help me migrating values? or do I have to do all of that “on foot”, as we say in Germany… :wink:

Imho you just have to set the metadata “unit” to your currently persisted unit and you should be good to go.
The metadata unit describes how the values will be persisted or reported to external systems so you should always set it, even if it’s not mandatory.
If you do this no further migration should be necessary.

e.g.

Number:Length   MyItem   {channel="MyChannel", unit="cm"}

sorry, forgot to include that in the initial post, but I’ll get information from outside openHAB in specific formats, mostly out of my control.
e.g. distances in kilometer, but the default unit for “length” is meter. So, even if I changed the item’s unit to “length - km”, the moment there’s a new value, it’s interpreted as meter and therefore is persisted in the “wrong” unit.

To elaborate the example on the odometer-item of my car:

  1. node-red plugin reads out the data of my EV6, sends values (here in kilometer) via mqtt
  2. openHAB receives the mqtt-data:4.
UID: mqtt:topic:synology:kiaEV6
label: MQTT Kia EV6
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:synology
channels:
  - id: odometer
    channelTypeUID: mqtt:number
    label: odometer
    description: Kilometer
    configuration:
      stateTopic: devices/KiaEV6/odometer
  1. the item “EV6_odometer” follows the channel via Standard-Profile

so up until now, the item did have a type “number”, but not have a dimension. Now I’d like to change that:

  1. I change the Dimension to “Length (m)”
  2. I change the Unit to “km”

What happens is, that from the value “23535.6” of the MQTT-topic, openHAB now persists the value as “23.535”, which is (roughly) 1/1000th of the value.

So, now I could make nodeRed send the value in meter instead of km, and l’d be fine. But there’s other items, which I don’t have any control over in which unit they’re being sent. And I do have the same problem there. Sometimes is ct versus €uro or Watt versus kiloWatts, …

So I think I need a more comprehensive approach, whichin I don’t lose my items’ persistences.

No - you need to read up on UoM a bit more. :wink:

The unit metadata is how it will be persisted.
So it’s clear how you have to set that and you should set that for every item.
E.g. if you want to persist in meters the metadata unit has to be set to meters!
That’s plain and easy and you won’t loose persisted values.

If the value you receive through mqtt is not in the unit you want you can explicitly set the value unit in the channel configuration of the mqtt thing.
I tried to push for a profile that explicitly sets the unit on a channel which would have been an easier solution but it was never implemented and I’m not making the mistake of trying again.


All in all I played around with UoM quite a lot but I’ve never found that the additional complexity is worth the gain especially since most of the time the units are fixed and don’t change and there are still edge cases which are very clunky.

So my advice is just continue with your working setup and invest your time in better automations or new features.

I know and I would say the same. But first off my inner Monk won’t back down, unless I tried and I also see some more easy way to handle different units. e.g. I’m working a lot with energy in rules. Sometimes I’d like to just compare Watts with kiloWatts, without having to multiply one of the variables by 1000, but just use the neat features JS-Scripting got within openHAB to do that regardless the units. I’m thinking, done correctly and consequently the code structure in the rules would benefit from it and the overall understanding would grow…

having said that, I cannot confirm that it works as you described. I’d have to setup a seperate installation and play a bit around with that, but my observation was, that openHAB expects values in the default-configuration and not the actual configuration of a item. But I’ll check that.

If no unit is provided the configured unit is assumed. If a different unit is provided it is normalized to the configured unit. Or at least that’s the way it should be.
Note that you have to modify both the mqtt thing configuration and the item configuration.

Please do and report back. :slight_smile:

hmmm. I guess, there was the problem. The MQTT-channel’s “advanced” configuration allows for a UoM. So if I do insert “km” there and on the item, it works for that item. If the channel configuration is default, then it doesn’t look on the item’s configuration. Which I get makes sense, as you could in theory have multiple items linked to a channel with different UoMs…

I’d have to check all the bindings, because most automatically send their UoM, but I’ll guess if I changed an UoM of an item to Wh and the channel sends kWh, it’ll get converted automatically then.

the problem with persistence still exists. Because if I change an battery level item to %, then the persistence has like “60” als an historic value without UoM, and now has “0.6” as value in percentage.

The unit doesn’t have to match, one can be m and the other km. It just has to be of type length. The unit configuration on the mqtt binding just defines what shall be used if nothing is provided.
If you configure km on the item and the mqtt value is in km the configuration on the mqtt channel can be omitted.

Interesting. Could you share your item configuration and what is persisted?

ok. I can confirm now. I did the following:

  1. create the channel without UoM
  2. create the item without UoM and link it to the channel
  3. send “40338.7” to the MQTT-topic
  4. the item changes to “40338.7”

then I changed to UoM:

  1. changing the item’s UoM to length - km
  2. the item changes to “40.338” [1]

I then stopped, but(!)
3. send “40338.7” to the MQTT-topic
4. the item changes to “40338.7”

So it did what you said, but i just aborted a bit too early! :wink:

[1] in my tests, the item did not get persisted with 40.3, but always with 40338.7:
grafik

Default length is m so always manually specify the unit when creating a UoM item.

Probably because it was not a proper item state update but an item update.

I don’t think so, at least not easily. I think what you’d need to do is dump rrd4j through the REST API for the Item. Then save off that JSON somewhere and adjust the values. Finally, you’d need to set the unit of the Item to match the unit of the values saved in your JSON file, stop OH, remove the rrd file for the Item, and push the edited JSON through the REST API.

I’m not positive that would work but I think it might.

But over all it’s probably best to just set the unit metadata on the Item to match the unit the old data is already saved in as @Spaceman_Spiff suggests. Then no conversions are necessary.

If you want to see it in some other unit in the UIs set the state description partern to show some other unit (e.g. if you’ve saved W and want to see kW set the state description pattern to %.3f kW). In your rule you can force the unit of the state of an Item. In JS for example items.MyWatts.quantityState.toUnit('kW'). Or not as you can do all comparisons and math with any units so long as they are compatible.

With the lack of such a profile, an inline script transformation should work:

JS: | input + " kW"

That will append a unit to what ever the Channel is publishing. It doesn’t have to be JS. The code should be pretty much identical in all the rules languages

Let’s say MyWatts is in W.

if(items.MyWatts.quantityState.lessThan(Quantity('100 kW')) {

No, @Spaceman_Spiff is right. Anything will be converted to the unit of the Item. If you set the unit metadata, anything sent to the Item will be converted to that unit. If you do not set the unit metadata, the system default is used.

If the Item has a unit (either the default or set in the unit metadata) and it’s sent a value without units, the Item unit is assumed. For example, if you have an Item with a unit of kW, and you send 100 to the Item as an update, OH assumes it’s 100 kW.

For MQTT, you must set the unit of the Channel so that MQTT will update the Item with a unit and OH will do the conversion instead of just assuming the Item’s unit.

Set the unit to one and set the state description display state to %d %%. The Item will continue to carry a value between 0 and 1 but show 0 to 100 in the UIs.

Update Item Unit Item State
1000 W W 1000 W
1 kW W 1000 W
1000 W kW 1 kW
1 kW kW 1 kW
1000 W 1000 W
1 W 1 W
1000 kW 1000 kW
1 kW 1 kW
1 Like

no. I cannot reproduce it with MariaDB. Perhaps it was some kind of glitch with rrd4j:


there’s an 8500 value, what should have been 85%. but it did not affect the MariaDB persistence:
grafik

So, I’ll keep digging.

That would be a lot of effort for a few items. Perhaps I’ll just switch to JDBC as standard persistence, I can change the values there more easily.

But for the rest thanks for your explanations again. I’ll just keep working around. And yes, perhaps it’s best to use the “assumed” UoM on items, so all persistences have the “correct” values. And do conversions in graphs or in rules as described.

What do you mean by that?
I’ve made about five posts now which basically say “don’t used the assumed unit but explicitly configure it on the item”.
If you take the essence of this thread your statement is the opposite. :rofl:


I am still under the impression you don’t have a proper understanding how UoM works so might I suggest you carefully reread this thread, the UoM docs and especially the table in richs post?

1 Like

This. :point_up_2:

Set the unit metadata on the Item to whatever unit is already being saved in your persistence.

No conversions of persistence data is necessary. OH will do what ever conversions you need. Job done.

As a bonus you can set the unit on the MQTT Channels to set you up to make changes easier in the future. But if you set the unit of the Item to whatever MQTT is already publishing, you don’t have to set the unit on the MQTT Channel.

For your percentages, the unit you are already saving/using is one.

I forgot a case which I’ll add in after hitting reply on this.

1 Like

sorry, if it was not clear. “Assumed” unit meant exactly what you wrote. As of now I don’t have an unit on “old” items. Meaning the ones added to my openHAB since years now. Most of them I already use in my preferred unit (for example W, even if the default is kW). so “assumed” would be to use “W” as an unit, even if the default is different and kW.

1 Like