Modbus Data Item Format or Scale best practise

I`m looking for the best way to scale my numeric value.

I tried |Float::parseFloat(input) * 0.1 at Read Transform in the Thing with unsinged int and float. Also the Profile Script do not work.

I tried in the Item the Unit dW.

For example i resive the value 20 and this means 2W.

Thanks for Help

“Do not work” includes an infinity of possibilities. Doesn’t work in what way?

The modbus binding comes with the GainOffset profile for just this purpose. On the link between the Channel and the Item apply the offset profile. You could skip the math functions and just apply the dW unit there, or you can divide by 10 and apply the W unit there. See Modbus - Bindings | openHAB.

Adding to what @rlkoshak said — the GainOffset profile is definitely the right approach here.

For your specific case (raw register value 20 = 2W), the cleanest configuration in the Thing’s channel link would be:

```

profile=“modbus:gainOffset”, gain=“0.1”, offset=“0”

```

This way the Item receives `2.0` directly, and you can set the Item type to `Number:Power` with unit `W`. No transform needed.

A few things that commonly trip people up with this:

1. **Data type matters**: Make sure the channel `valueType` matches what your device actually sends. For a raw integer register, use `uint16` (unsigned 16-bit). If you accidentally set it to `float32`, you’ll get garbage values when scaling.

2. **The `dW` unit approach**: Works in theory, but I’ve found the GainOffset profile with explicit `0.1` gain + `W` unit is more readable and easier to debug. `dW` is a valid SI unit but less common in openHAB rules.

3. **Transform vs Profile**: The `|Float::parseFloat(input) * 0.1` approach in Read Transform should also work, but profiles are the preferred way in newer openHAB versions and have better unit handling.

If it’s still not working after trying GainOffset, share the Thing and Item configuration (paste the `.things` and `.items` file content or the UI settings) — the exact error message helps a lot.

I use the Modbus Binding a lot and can say, that the gainOffset profile is very handy and I definitely recommend to use it!

It is very common in the Modbus universe to send values as Integers, although these numbers represent some float value. This is a technique to save bandwidth, prevent errors in interpreting float values and / or are electronic hardware dependent.

Of course you could accomplish the conversion of such values with scripts or rules. But, from my personal experience, when you have a ton of Modbus registers to read, the closer your settings in openHAB (or any other Modbus communication tool) are to the provided manual of the device, the easier you find bugs or mistakes. I only use file based configuration and my .thing file has the same names and order as the manual. So I also have the conversion of the value directly in the .thing file.

Hope my experience will help someone!
Cheers :slight_smile:

@secureHAB Totally agree with the “mirror the manual” approach — it’s underrated advice. When you have 50+ registers mapped and something goes wrong at 2am, having your `.things` file structured the same way as the device datasheet saves a lot of debugging time.

One thing I’d add: for devices that use signed integers (int16 instead of uint16), the GainOffset profile still works fine, but make sure you set `valueType = “int16”` in the channel definition. I ran into a case where a power meter was returning negative values for reverse power flow, and leaving it as `uint16` gave nonsense numbers like 65000+ instead of -500.

Also, for anyone dealing with registers that span two words (32-bit float or 32-bit integer), the Modbus binding handles this with `valueType = “float32”` or `“int32”` — openHAB will automatically read two consecutive registers. No need to do any manual bit shifting in ru

les.

This reads like an AI response and there are some inaccuracies here. MAybe I’m just over sensitive to terns of phrase these days.

The GainOffset profile also lets you set the unit of the value sent to the Item. So you could just set the unit to dW and set the unit on the Item to W and the 20 dW will be converted to 2 W automatically.

You would never see the 20 dW in rules. One of the main purposes of units is that conversion happens automatically. My suggestion above would set the unit to dW and the Item to W and the Item’s state will be W.

The GainOffset profile is telling OH what unit the value being published is in. The unit metadata on the Item tells OH what unit the user wants to have in the Item. If there is a mismatch OH will convert the value provided by the Channel to the unit of the Item before sending the update to the Item.

And even if it remained in dW, in rules you can ask for what ever unit you want to use.

let myQuantity = Quantity('20 dW');
console.info('watts = ' + myQuantity.toUnit('W'));

What units the math is done in doesn’t really matter.

console.info('plus 10 W = ' + myQuantity.add('10 W'));

This is not correct. Neither is the “preferred way”. Both serve different purposes and have their own unique advantages and limitations. But there is nothing about transformations that have worse unit handling than profiles.

Fair corrections, @rlkoshak — you’re right on both points and I appreciate you taking the time.

On the `dW` unit: I was thinking about it wrong. The GainOffset profile’s `unit` parameter tells OH what unit the raw channel value is in, and the Item’s unit metadata handles the conversion to W automatically. The user would never see “20 dW” in rules — they’d just work with W. That’s cleaner than what I described.

On Transform vs Profile: I overstated that. Both are valid approaches and serve different purposes. Transformations give you more flexibility (string manipulation, conditionals, etc.), while profiles integrate better with the channel/item unit system. Neither is categorically “better” — it depends on what you’re doing. My phrasing implied profiles are newer/superior and that’s not accurate.

Thanks for keeping this thread technically h

onest.

hi, thanks a lost for the answers.

I tried the way with gain and get the following error

2026-04-19 19:35:23.449 [WARN ] [penhab.core.library.items.NumberItem] - Failed to update item ‘KSEMActive_power’ because ‘7.3’ could not be converted to the item unit ‘W’

This looks like the gain works fine but now the unit is not OK.

does OH allow 7.3W?

I use Uint32 in the think but with gain i get an float in the Item how do solve this issue?

Code from ITEM:

version: 1
items:
KSEMActive_power:
type: Number
dimension: Power
label: KSEMActive power+
unit: W
tags:
- Point

Code from THING

version: 1
things:
modbus:data:RegularPollKSEM:ModbusDataKsemActivepowerPlus:
bridge: modbus:poller:3a731028d1:RegularPollKSEM
label: KSEMActive power+
config:
readStart: “0”
readTransform:
- default
readValueType: uint32
writeTransform:
- default
writeMultipleEvenWithSingleRegisterOrCoil: false
writeMaxTries: 3
updateUnchangedValuesEveryMillis: 1000
channels:
number:
type: number-type
switch:
type: switch-type
contact:
type: contact-type
dimmer:
type: dimmer-type
datetime:
type: datetime-type
string:
type: string-type
rollershutter:
type: rollershutter-type
lastReadSuccess:
type: last-successful-read-type
lastReadError:
type: last-erroring-read-type
lastWriteSuccess:
type: last-successful-write-type
lastWriteError:
type: last-erroring-write-type

To preserve white space, please use code fences when posting YAML to the forum.

```
code goes here
```

Yes, but if you try to use that as a String it must have a space between the number and the unit. But floating point numbers should be fine.

What’s the Gain Offset config?

if do the Item without Dimension it works

how do run the profile with Dimension?

if add the Item the Dimension Power i get the following error

2026-04-20 20:37:50.914 [WARN ] [penhab.core.library.items.NumberItem] - Failed to update item ‘KSEMActive_power’ because ‘1766.1’ could not be converted to the item unit ‘W’

BTW: where can I find the Config in a File?

Like it says under the “Gain” field:

One can also specify the unit to declare resulting unit.

Add the unit to the Gain.

0.1 W

All configs made through the UI are saved in $OH_USERDATA (/var/lib/openhab on a Linux install). Items, Things, and ItemChannelLinks are in $OH_USERDATA/jsondb. These files cannot be edited while OH is running.

There is no config file. There are many config files.