MQTT sensor offset in item def

I have a bunch of sensors with the mqtt binding that would need a certain offset. I’m now doing this with separate items and rules (many), but I’m wondering if I could do this in the item definition with a transformation.

Basically I just need to add or subtract a certain value from the value I get through mqtt.

Thank you.

If the data is XML, you can do some simple math inside of an XSLT transform. You can also do some simple math with regular expressions. I don’t know if you can do the same for JSON.

Of course, this assumes that the libraries openHAB uses for these transforms support these operations which is not guaranteed. Personally I try to go out of my way to avoid doing transforms. :smile:

If the offset is the same for all Items, you can add your items to the same group and write a single rule to add the offset to the most recently changed Item. I’m not sure how well this works if you have lots of items changing around the same time. It requires persistence to work.

rule "Add offset"
    Item ItemOne changed or
    Item ItemTwo changed or
    Thread::sleep(100) // give persistence time to catch up, experiment to find the minimum amount of time needed
    val mostRecent = gMyItems.members.sortBy[lastUpdate].last as NumberItem
    mostRecent.postUpdate((mostRecent.state as DecimalType) + offset)

NOTE: I don’t trigger on updates to the group because the group will receive multiple updates for each change to its member items which would cause the offset to be added more than once.

If it were me, I would replace the default at the end of binding string with JS(offset.js). Assuming the MQTT message is a number and you wanted 5 less that what MQTT reports, your offset.js file would look something like

(function(i){ return i - 5; })(input)

You would need a different .js file for each different offset value.

Forgot about JS transforms. That is absolutely the way to go.

Thank you.
The JS transform works great.

1 Like