Changing the sign of a number coming from a thing channel

  • Platform information:
    • Hardware: Intel® Celeron® J4025, 4GB RAM
    • OS: Docker
    • openHAB version: 4.0.2
  • Issue of the topic: Changing the sign of a number coming from a thing channel
    Hello, I got a Shelly EM that sends me back my energy production, I’d like to have positive watts instead of negative that Shelly sends. How can I transform a number coming from channel to a thing? I’ve read something about profiles but I never used this openHAB part and examples didn’t help.
    Thank you

Yes, you’ll want to use a transform profile. How you do that depends on how you’ve configured your Items and what your preferred rules language is. It also matters whether this Item has units or not.

Assuming managed Items and Things using JS Scripting and the Item has units in Power:

  1. Navigate to Things → the shelly Thing → Channels → the energy production Channel → the Item linked to that Channel. This brings up the Link configuration.

  2. At the bottom you’ll see a “Profile” section, select “SCRIPT ECMAScript (ECMAScript 262 Edition 11)”

  3. This is a sensor reading so we only need to worry about the Thing to Item Transformation

  4. Because this is a simple multiply by -1 we can do an inline transformation.

    JS(|Quantity(input).multiply(‘-1 W’))

Thanks for your reply, I did everything but it seems that if ECMAScript profile is enabled channel is not updating the item anymore, also if both transformations are empty. This channel sends a floating point number, so I Created an Item Number:Power type. I’ve also tried with a Number and a String (String returns null anyway so it’s not the right type I think) but it does not work.

You need to show the channel I think. You can’t just willy nilly change between using units and not using units when it comes to profiles. Profiles see the actual value sent from the Channel before it gets to the Item. So the transformation needs to know.

Did you notice all those assumptions I listed? If any of those are not true for this case the transform will not work.

I do see an error in my code though. I forgot to convert the -1 W to a Quantity.

JS(|Quantity(input).multiply(Quantity('-1 W')))

If that doesn’t work, you’ll probably have to create a full JS transform where you can log out what input is and intermediate steps and such.

Nope.


As you see in this screenshot the first item is the “direct” thing->item, the second one with NULL value is with profile JS(|Quantity(input).multiply(Quantity(‘-1 W’))). Channel in the first item is updating, not in the second one. I’ll try to do a .js file but from the examples I only see String inputs, does it support also Number inputs?

You’ll have to parse the String in the transform.

Can you take a screenshot of your item profile configuration?

I suspect it is: JS(|Quantity(input).multiply(Quantity('-1 W')))

Instead it should be: |Quantity(input).multiply(Quantity('-1 W'))
Do not enclose it with JS(....)

Result is the same, Item is not updating anymore. I’ve tried with a JS rule and a temp item, it works:

items.ShellyEM_Bilancio_TEST.postUpdate(items.ShellyEM_Bilancio.quantityState.multiply(-1));

So… I have to create a file sign.js with a function inside and, according to manual, I suppose to write this inside:

(function(data) {
  return Quantity(data).multiply(-1);
})(input);

Maybe logging something like this:

console.log("Before return")

And call this file with this:

JS(sign.js):%s

Am I right with this code?

Post a screenshot! There could be two different places to enter this, and depending on that, the syntax is slightly different

Sorry, this is the position… With or without JS() enclose the item is not updating anymore.

You need to remove the JS()

Just |Quantity(input).multiply(-1)

Note the previous advice had a bug. Don’t multiply with Quantity -1 W because you’ll end up with W squared as the unit.

Nope. Still the same issue: if I enable the ECMAScript as profile the channel stops updating my power, no metter what I write on it. It stops updating also if the field is empty and that sounds weird.

I can confirm this.

I’m not familiar with JS Scripting, I suspect there’s a syntax issue there.

If you tried using JRuby scripting (have to install the addon first), you can try this:
|QuantityType.new(input) * -1 - I tried this and it worked.

Having both fields empty will result in nothing getting updated indeed.

According to manual it seems JS syntax is right. Probably there is an issue during String->Quantity conversion because the rule with item.quantityState.multiply(-1) was working properly.
Anyway, I’ll use JRuby.
Thank you for help

I found out what’s wrong with the jsscripting syntax.

It should be |Quantity(input).multiply(-1).toString()

Yes, it works.
Manual says “The script return a value that supports toString() or null”, so Quantity type should be fine because it supports toString() method. In JRuby QuantityType type return works so probably there is a bug on JS transformations.