Convert Wh to kWh (divide by 1000)

Hello,

I get Wh energy counter over mqtt.

However I would like to display kWh (divide Wh by 1000), as the Wh number would be quite large.

I tried Incoming Value Transformations in Advanced Channel configuration (I added “/1000”), which leads to the right value, but I get a “EROOR:Config” on the Gerneric MQTT Thing.

How do I divide a value by 1000?

thanks
Daniel

“/1000” isn’t a transformation. You won’t see it listed under “Data Transformation” as an add-on to install.

You need to use an actually supported transformation. The only transformation that can handle changing a numeric value is the JS transformation. JavaScript - Transformation Services | openHAB

I believe mqtt supports “unit” parameter. You can use it to declare the origin unit Wh. Link the channel with UoM aware Number item.

You can then use item state pattern and let the UI do the wanted unit conversions.

This way there would be no need for transformations at all. At least this is my understanding of the functionality.

Generally speaking I myself prefer the units to avoid any unit errors and focus on the core calculations.

It does but it’s kind of broken right now when you want to convert from one unit to a different one. The problem is no matter what you put into the Channel, the State Description will override it so instead of converting the 1000 Wh to 1 kWh you’ll end up with 1000 kWh.

Because of this bug the only way to actually change the units of the value coming from MQTT is through a JS Transformation.

1 Like

Right! It seems to be this very very lengthy discussion [mqtt] Faulty display of an linked item using Units of Measurement. · Issue #10338 · openhab/openhab-addons · GitHub

Ok, I installed the JavaScript Transformation Service, however I am at a loss as to what to put in the fiield.

The linked Documentation mentions JS(| input / 10) as an Inline Java example.

However JS(| input / 1000) only removes the 3 decimal places.
The same as JS(| parseFloat(i) / 10000), JS(| i / 10000) and JS(| %i / 10000)

What is the right Syntax here?

Thanks
Daniel

I didn’t know that was possible!

Yes. So, what do you need to happen?

Is your Item of Number type? Then you must pass it a number from MQTT, divided by 1000. You can add text “kWh” in your Item pattern metadata for display.

Is your Item of Number:Energy type? Then you must pass it a value with units. You can give Item a default unit text “kWh” in your Item pattern metadata. You can transform the number coming from MQTT by appending the text " Wh" to it. No need to divide, if you use the proper units then openHAB takes care of conversions.

I didn’t either. That’s cool! I should follow my own advice and reread the docs periodically. NOTE: that’s a new feature in OH 3.2 and not available in OH 3.1. And I don’t know when that feature was added during OH 3.2 development. So @Daniel_Hermann1, which version of OH are you running?

It must be a recent enough 3.2 if it’s not exploding on the expression and it appears to be doing the math at least and removing the decimal places. And I’m guessing you have the syntax right there as well.

So what is the type of the Item now and what is the State Description on that Item? Do you want to just show that Item as kWh but let it remain stored as Wh? Do you want it stored as kWh too? This has implications to things like charting and the like.

Feature was merged just a couple of days ago, so it’s only available in latest 3.2 snapshots.

1 Like

That inline transformation is really neat!

Thanks to javascript “sloppines” with types, you can just have expressions like input/100 + " Wh" as the transformation – and as a result you have number-with-units coming out, suitable for UoM-aware Number item. No need to even to convert the string input to javascript number!

Of course if you want to handle UNDEFs etc, it might get more tricky…

EDIT: added missing whitespace

Don’t forget the space between the number and the units though. " Wh".

We should be able to manage UNDEFS and NULLs using a structure like the following.

(input == "UNDEF" || input == "NULL") ? input : input / 100 + " Wh"

That will just pass the UNDEF/NULL through unchanged. You’ll want to do that anyway if there is any chance that the Channel will return anything that cannot be parsed into a Number.

But now that I think about it, an MQTT Channel is unlikely to ever return UNDEF or NULL anyway so that check would probably better be something like

(isNaN(input)) ? input : input/100 + " Wh"

That will just pass through any value that isn’t a number and do the math when the value is a number.

Edit: fixed the first example which was totally wrong.

2 Likes

Thanks for the correction regarding the whitespace, will correct the above post for posterity.

Nice trick with isNaN, once again good example of javascript “sloppiness” when it comes to typing, examples of “nan” according to isNaN include "foobar", "NULL" :slight_smile: Unlike I expected, I thought only javascript literal NaN or 0.0/0.0 would be considered NaN.

Hi,

Using openHAB 3.2.0.M4

I want to save it as kWh.

So i Tried (isNaN(input)) ? input : input/1000 + " kWh" as Transformation, leaving the field “Unit of Measurement” as kWh. Unfortunately I get 645.898 kWh as an answer (or just 645.898 if i leave the Unit of Measurement, even thogh I have the + "kWh " in the JS command).
The right answer would be 0.65… kWh.

In the Log I get the message

2021-12-17 09:02:49.545 [WARN ] [t.generic.ChannelStateTransformation] - Transformation service (ISNAN(INPUT)) ? INPUT for pattern input/1000 + " kWh" not found! .

By the way, using a file works.

1 Like

There should be a pipe character | as well there if you read the docs carefully… Above examples are therefore slightly incomplete

Example from the docs JavaScript - Transformation Services | openHAB

JS(| input / 10)

ok, I tried

JS:(|(isNaN(input)) ? input : input/1000 + " kWh")

Is that the correct syntax?

I get the following error:

2021-12-17 09:33:08.554 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JS-transformation failed: Illegal filename syntax

Don’t forget, nobody else knows if your Item is currently Number or Number:Energy type, it will make a difference one you get transforms going.

There is an extra colon now :

How about JS(| isNaN(input) ? input : input/1000 + " kWh")

I also removed the unnecessary but harmless parentheses around the isNaN call

2021-12-17 11:54:28.526 [WARN ] [t.generic.ChannelStateTransformation] - Transformation service JS(| ISNAN(INPUT) ? INPUT  for pattern  input/1000 + " kWh") not found!
2021-12-17 11:54:28.530 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JS-transformation failed: Illegal filename syntax

I think the colon would need escaping in this context. Try just the simple version.

EDIT -

That’s the important thing :smiley:

Inline JavaScript support is not available in 3.2.0.M4, but in latest snapshot.

1 Like