Gain-Offset is not working

Hello,

I’m having a frustrating time with a simple problem.
There is a Zigbee smart plug reporting multiple values. It must be reporting electric current in “mA”

	DEBUG	org.openhab.binding.zigbee.internal.converter.ZigBeeConverterMeasurementRmsCurrent	A4C1386FD8EED17F: ZigBee attribute reports ZclAttribute [cluster=Electrical Measurement, id=1288, name=RMS Current, dataType=UNSIGNED_16_BIT_INTEGER, lastValue=861, lastReportTime=Wed Apr 09 15:55:55 EEST 2025, implemented=true]

I’m trying to adjust current value dividing by a thousand. This is typically done by applying a gain factor of “0.001 A”, however I get UNDEF result instead

WARN	org.openhab.binding.modbus.internal.profiles.ModbusGainOffsetProfile	Profile can only process plain numbers from handler. Got unit A. Returning UNDEF

Testing with Offset it seems to work as expected:

I don’t know where else to look at on dealing this issue. I tried to mix and match multiple combinations of gain factor, measurement units, etc., but nothing seemed to help.

Point configuration:

label: Current
type: Number:ElectricCurrent
category: Energy
groupNames:
  - Zigbee_Smart_Plug_1
tags:
  - Point

Thing configuration:

UID: zigbee:device:a1b2cab251:a4c1386fd8eed17f
label: Zigbee Smart Plug 1
thingTypeUID: zigbee:device
configuration:
  zigbee_macaddress: A4C1386FD8EED17F
bridgeUID: zigbee:coordinator_ember:a1b2cab251
channels:
  - id: A4C1386FD8EED17F_1_voltage
    channelTypeUID: zigbee:electrical_rmsvoltage
    label: Voltage
    configuration:
      zigbee_reporting_polling: 7200
  - id: A4C1386FD8EED17F_1_meteringsumdelivered
    channelTypeUID: zigbee:metering_sumdelivered
    label: Metering Summation Delivered
    configuration:
      zigbee_reporting_polling: 7200
  - id: A4C1386FD8EED17F_1_activepower
    channelTypeUID: zigbee:electrical_activepower
    label: Total Active Power
    configuration:
      zigbee_reporting_polling: 7200
  - id: A4C1386FD8EED17F_1_switch
    channelTypeUID: zigbee:switch_onoff
    label: "SMART_PLUG: Switch"
    configuration:
      zigbee_reporting_polling: 900
  - id: A4C1386FD8EED17F_1_current
    channelTypeUID: zigbee:electrical_rmscurrent
    label: Current
    configuration:
      zigbee_reporting_polling: 7200

There was similar need to adjust reported energy meter values, like below, but all worked as expected

If the unit reported by the binding is incorrect, then ultimately this is a bug in the add-on and you should file an issue to have it fixed.

My understanding of the Gain/Offset profile is it expects the value from the Channel to not have a unit already. Modbus doesn’t supply one and the profile is a part of the modbus add-on.

So you’ll have to use a script transformation. Luckily this would be just a one liner. For JS it would be something like the following for the Thing to Item transform:

JS: | Quantity(Quantity(input).float/1000, "mA")

That parses and pulls the unit off of the value from the Channel, divides by 1000, then rebuilds the Quantity with the correct units.

It may be a stupid question, but how do you add these one liners to OH?

Same place where you set the Gain/Offset profile, select ECMAScript instead. You’ll have three fields, one to translate the value from the thing to the Item, one to translate commands from the item to the thing and another to transform states from the item to the thing.

You just put the one-liner in the field for the thing to item field.

See Transformations | openHAB

I must be doing something wrong with syntax.
Tried to copy-paste:

ERROR	org.openhab.core.automation.module.script.profile.ScriptProfile	Failed to process script 'JS: | Quantity(Quantity(input).float/1000, "mA")': Could not get script for UID 'JS: | Quantity(Quantity(input).float/1000, "mA")'.

Tried couple of other options quickly reviewing other sources.

ERROR	org.openhab.core.automation.module.script.profile.ScriptProfile	Failed to process script 'Quantity(Quantity(input).float/1000, "mA")': Could not get script for UID 'Quantity(Quantity(input).float/1000, "mA")'.
ERROR	org.openhab.core.automation.module.script.profile.ScriptProfile	Failed to process script 'JS(|Quantity(Quantity(input).float/1000, "mA"))': Could not get script for UID 'JS(|Quantity(Quantity(input).float/1000, "mA"))'.

The JS part may not be required since you’ve already selected it in the UI. Try it without the “JS:” part:

| Quantity(Quantity(input).float/1000, "mA")

Trying this | Quantity(Quantity(input).float/1000, "mA") gave me new error and a hope moving somewhere :slight_smile:

ERROR	org.openhab.core.automation.module.script.profile.ScriptProfile	Failed to process script '| Quantity(Quantity(input).float/1000, "mA")': org.graalvm.polyglot.PolyglotException: TypeError: Argument of wrong type provided, required Item, string or Quantity.

I then tried concatenate as if parameters were strings
| Quantity(Quantity(input).float/1000 + "mA")
but that gave me no errors, no warnings at all, as if there were no issue.

As the item seemed to work ok with “A” dimension from my previous tries I jumped back on other similar topic (Modbus binding: gain-offset correction doesn't work - #10 by FranzS) for some ideas.
I gave a try for this adjusted script
| input.replace("A", "mA") and got this item finally working as intended.

Is there a way for a noob like me to see a raw data that is going straight to the item? Not sure whether it would have helped me, but still.

Fiddled a little bit more and got this transformation working as well

| Quantity(input).float + 'mA'

I learned something new today :slight_smile: Thanks for being here and helping me out

That’s an even better approach I think. It just fixes the unit without needing to do the math.

have you tried to just use
0.000 [A]
in the gain field?

You could just use regex to do this replacement and avoid using script completely

s/ A/ mA/

However, the root of the problem is why does it give you this wrong unit in the first place

No, I haven’t tried to put A into brackets, like “0.001 [A]”. What it supposed to do?

Sorry for noob questio, JS is not my filed. How would you use mentioned regex in this case?

Install regex transformation add-on then select regex in profile and enter that expression.

this is the correct syntax for the unit in the gain-offset field (but I didn’t read everything to check if you get the value with a unit)