How to do unit transformation using profile in OH4 GUI

  • Platform information:
    • Hardware: Raspberry pi 4
    • OS: openhabian
    • openHAB version: 4.0.0.M4
  • Issue of the topic:

I’m using the GUI for everything, and I would like to transform channel data from Ampere to Watt before it’s given to the item, and thought I’d make use of profile transformations.

I’ve read the following documentation, but I’ve not managed to find an example that includes units:

Basically it boils down to two questions:

  1. Can I use inline script as possible in text based configuration with ‘JS(|…)’? Which profile should I use in that case?
  2. How would a js script look like, that makes use of units to convert Ampere to Watt? See below for an obviously wrong starting point.
(function(data) {
  var returnValue = data*(230 as QuantityType("Volt"))
  return returnValue
})(input)

Thanks in advance!

If you can keep it a one-liner. I’m not certain that’s the case here though.

Which ever one you want to write the oneliner for. Given the function above I’m guessing you are using JS Scripting so that would be SCRIPT ECMAScript (ECMAScript 262 Edition 11). Look at the doc for JS Scripting for how to construct a one-liner.

I assume 230 is your voltage.

First, as documented here:

The input value is injected into the script context as a string variable input.

So you’re not going to do math with it.

Secondly you cannot simply cast a primitive number to make it into a QuantityType. In fact, QuantiyType isn’t really even a thing in JS Scripting. As documented here create a Quantity in JS Scripting:

var qty = Quantity('5.75 m');

Finally, as documented here you can’t do math with the regular operations.

What I don’t know is how Quantity handles incompatible units. Is it smart enough to convert a A * V calculation into W? I don’t know. Ampere and Volt are not the same type of unit. But the library is pretty flexible so it just might work. If you want to give it a try you’ll first need to parse data into a Quantity and parse 230 V into a Quantity and call multiply() to perform the operation.

You’ll also need to return it as a String as documented here:

The result of the transformation is provided by the script as its return value. It can be null , a string , or a value of a type that properly implements .toString() .

Note that since you are in a recent OH 4, you can create this transformation through MainUI under Settings → Transformations.

(function(ampStr) {
  if(ampStr == "NULL" || ampStr == "UNDEF") return ampStr;
  var amp = Quantity(ampStr);
  var volts = Quantity("230 V");
  return amp.multiply(volts).toString();
})(input)

If that doesn’t work, you’ll need to strip the unit from ampStr. Luckily, parseFloat will stop at the first character that isn’t a part of a floating point number instead of generating an error. Then append the new units on the return value.

(function(ampStr) {
  if(ampStr == "NULL" || ampStr == "UNDEF") return ampStr;
  var amp = parseFloat(ampStr);
  return amp * 230 + ' W';
})(input)
1 Like

Your first example works! Seems it’s smart enough. Thanks!

Regarding inline script, in my version of openhab 4 the script options are limited to a list of scripts, as seen in the screenshot below. I’m pretty sure it was a text field in previous openhab 4 milestones though. Does that mean inline scripts are no longer supported through the GUI?

At least for the transformation profile. Inline will work on Channel transformations and state description patterns though for sure.

It wouldn’t be a bad idea to file an issue on the openhab-webuis repo asking for support for inline SCRIPT transformations. There is nothing technically preventing it. The UI just doesn’t appear to support it at the moment.

Are you saying that “channel transformations” is something else than “channel transformation profiles”? And that it can be accessed through the GUI? Where can I find it in that case?

Will do!

Created an issue:

Yes of course. Some bindings have support for applying transformations on the Channel. HTTP, MQTT, Exec are just a few of the noteworthy ones. If the binding supports it, there will be a field to enter a transform in the Channel config and it will be mentioned in the docs.

The transform profile applies a transformation at the link between the Channel and the Item. For SCRIPT transformations, you can define a separate transformation depending on the direction of the event (Channel to Item, Item to Channel).

You can apply a transformation at the label of the Item in the State Description Pattern Item metadata.

You can apply a transformation in a rule using the transform action.

Ah, got it. Thanks for the clarification.