Calculating with item values (e.g. x1000): Rules or JS transform or other?

I see that there are several methods to transform item values, for example x1000 to convert from kW to W.

  • Through rules
  • Through Javascript Transform
  • Maybe others that I don’t know about?

Which one should I use and what are advantages/disadvantages? Is one method preferred over the other? And what is the impact on persistence? If I use JS transform, is the transformed value persisted or the original value?

I think that depends on the required output.

If you want to change the state a rule is the right solution. If you just like to change the display a js tranformation is the right choice

This is a sensible question, and worth exploring because it influences the “where/what to do” question.

Persistence service like rrd4j store the raw numeric value of a Quantity Item state. That’s it, no units. It doesn’t care how you updated that state.
Upon retrieval of the number, persistence service gets the existing unit of the Item and applies that to the stored numeric to recreate the complete Quantity value.
(I think more accurately the “existing unit” is taken to be the system default unit, or the Item state presentation if it exists)

You’ll see the trap; if you change units of the Item state during operation, any historic data you look at (e.g. for charting) will be misrepresented.

So one good practice is to set up to do any transforms or scaling that you might want at the channel level, before data gets to the Item. And then leave that alone.

The answer to the actual question here is of course “it depends”. It depends where you do the transform.
If you transform for display presentation, this does not affect the raw Item quantity value and so does not affect persistence.
If you transform in a rule to process the value in some way, but do not update your Item with any new state, then persistence knows nothing about that either.
If you transform in channel or profile, before data is used for Item state, persistence just uses the Item state.

Here is a list of places where a “message” can be modified to, for example, change it’s units.

  1. At the device itself. When you have control over how the device sends messages it is often best to change it so it publishes the data so it doesn’t need to be transformed.

  2. In the binding. Many/most bindings will have the ability to apply a transformation to the incoming data before it is passed to the the Item (or transform the data going the other direction). Some bindings let you chain multiple transformations together which can be very powerful.

  3. Profiles. Profiles are little bits of capability that can be applied on the link between an Item and a Channel. In cases where the binding doesn’t support the type of transformation needed, there are a number of Profiles that might be able to handle it. For example, if you want to keep a timestamp for every time a device sends a value, you can link the Channel to a DateTime Item with the timestamp Profile. There are others like hysteresis, offset, and all of the transforms as well so you have a second chance at transforming the data before it gets to the Item.

All of the above occurs before the value gets to the Item. The remaining happens after the value gets to an Item. Pay attention to rossko57’s post regarding concerns with persistence and such.

  1. QuantityTypes (aka Units of Measurement). Certain Number Items can be enhanced with a unit of measurement. For example Number:Temperature tells openHAB not only that the Item holds a number, but a number that represents a temperature. With that knowledge, it can adjust between compatible units on the fly. So, for example, you can compare a °C to a °F and get the expected result without requiring you to do the math to convert from one units to the other. QuantityType Items can be converted between compatible units on the fly in rules and when displayed. But again, take heed of rossko57’s post as what you see may not be what the Item is actually storing because it might be converted for you on the fly.

  2. Rules and Proxy Items. Sometimes you need to fix the units in ways not supported by the above. In those cases you can trigger a rule, do the math, and update a proxy Item with the result.

  3. At display time. In this case you just leave the Item using what ever units it happens to be using and then when you display it on a sitemap or pages or what ever, you can apply a transformation so it looks like you want but leaves the underlying units unchanged.

There is no “correct” way or. The “best” way will largely depend on your specific use case and other constraints. Personally, I would recommend 1 where possible, and then 2 or 6 next depending on the specific use case.