Invert Channel Value

  • openHAB version: 4

I use a Shelly Plus PM to monitor generated solar power.
The provided power value from the thing is negative.
I would like to invert a channel value.
I belief a transformation profile should be best.
I didn’t manage to get examples from similar posts running.
I would prefer a DSL transformation.
Is there somewhere a full example available?
Thank you!

Transformations | openHAB has an Rules DSL example among the examples for a Script transform.

But what you’ve not provided is how you want to define this transformation: in a file, through the UI?

Note that for something simple like this an inline script is possible.

DSL(| Double.parseDouble(input).doubleValue * -1)

even simpler solution:

DSL(| -Double.parseDouble(input).doubleValue)
1 Like

In this case I’ve defined thing and item via GUI, but I’m open for files, too.
How may I apply an “inline script”? Does it require an item file?

No. You just put in the code above (either mine or @Udo_Hartmann’s example) in place where you’d put the transformation.

Where do you put the transformation? If the Thing’s Channel supports it you put it there. If not you put in in the transformation profile on the Link.

Hi Rich and Udo,
thanks for your replies. Sounds easy but in practice, I don’t get it.
The attempt from the following screenshot results in
" [ERROR] [n.module.script.profile.ScriptProfile] - Failed to process script ‘DSL(| Double.parseDouble(input).doubleValue * -1)’: Could not get script for UID ‘DSL(| Double.parseDouble(input).doubleValue * -1)’.
"

I also tried to put the code into a file and call the file via the GUI,
but I assume the code needs to be adjusted for a file.

I’m missing the simple GUI example to get it.

Right, when setting up via UI, you already passed the DSL information, so in the field
Thing to Item transformation set only

| -Double.parseDouble(input).doubleValue

or

| Double.parseDouble(input).doubleValue * -1

Hi Udo,

thanks for this hint.
I’m asking myself why this is not mentioned in the docu, or is it?

One hurdle done, at least one mor to take:
The inline scripts fails to parse the input string to double because the string includes a unit, see below:
Failed to process script '| -Double.parseDouble(input).doubleValue': For input string: "0 W"
Is there a simple solution, or do I need to implement some string magic to get parsing into double to work?
This thread seems to go into the right direction, will check tomorrow…

Hmm, that’s strange, because the function parseDouble should ignore anything other than the numeric part of the string. Maybe you can get away with this:

| -Double.parseDouble(input.toString.split(' ').get(0)).doubleValue

this: input.toString.split(' ').get(0) will only get the part before the first space within the input string. Maybe you don’t need the .toString (so input.split(' ').get(0) would suffice) , but it shouldn’t hurt.

It’s a struggle to keep the docs up to date with new features being added to OH.

That’s true for JS but not Java and therefore not DSL.

That should work but you’d want to add the unit back after multiplying by -1 to keep it consistent.

This is the shortest variant working for me:
| -Double.parseDouble(input.split(' ').get(0))
I don’t need to add the unit, since the item carries the unit within its metadata.
But why I don’t need to convert the double back to a string?
This seems to be done implicitly somewhere.


Thank you!

Another solution is discussed here:

Note that this is only true if the unit supplied by the Channel matches the unit in the Item metadata. If, for example, the Channel delivers W but the Item’s metadata is set to kW, then when you strip off the unit the W won’t be convert automatically to kW and it will just be treated as kW.

Common types like numbers get converted back to a String automatically by the SCRIPT transform.

If it were not for the initial requirement to use Rules DSL, I would have pointed you to this approach.