Scaling of Voltage reading in MQTT reading

  • Platform information:
    • Hardware: x86_64 , 24GB RAM, enough disk
    • OS: Fedore FC36
    • Java Runtime Environment: java-17-openjdk
    • openHAB version:3.4.2
  • Issue of the topic:

Simple task:

  • Set up a SmartPlug that can read the supply voltage as a MQTT device, no problem
  • The voltage channel supplies a value that is scaled *10. That is for a supply voltage of 240 V I get a reading of 2400.
  • To be able to scale this value to the real voltage I obviously need to divide it by 10.
  • And this simple task seems to be impossible. Tried everything I could find online.

So questions:

  • Where is the best place to do this? In the channel specification or in the presenting widget ?
  • How do I do it through the GUI without editing any files? Setting the InputTransformation in the Channel setup is completely ignored (Nothing in the logs). The Value spec in the presentation widget (Gauge) talks about using a “function”, but never tells us which language or in which form that function should be entered. And couldn’t find a single example of this online.

This should be “a piece of cake” operation and IMHO not a very uncommon one??

You’ve missed a couple of options, in a profile or in a rule.

But in this case, if the binding supports it, and the MQTT binding doe, the best option is in the Channel configuration. You’ll need to use a SCRIPT transformation.

If you use a transformation you can’t. You need a SCRIPT transformation and that requires you to write the transformation in files. Inline SCRIPT transformations are not yet supported (will be supported in OH 4) and there isn’t a UI available yet to write these transformation scripts.

So if you insist on using the UI only, your only option is to create a proxy Item and a rule. When the Item linked to the channel changes, trigger a rule that divides it by 10 and post it as an update to the proxy Item. Put the proxy Item on your UI and use that in your rules.

Well, that depends on what you put there and whether the transformation you are trying to use is even installed. You don’t provide any details so :person_shrugging:

Do you mean “expression”?

Value, if the item is not set - between min & max (for instance, defined with an expression)
(oh-gauge - Gauge | openHAB)

As for docs and examples, there’s this in the Getting Started Tutorial, this and this in the main docs.

But that’s just going to change it as it displays it. You really want the Item to have the correct value in the first place.

If you decide to go down the transformation route, see Transformations | openHAB. But the actual “function” you write to do the math will have to be placed into a file.

Thanks a lot for explaining to me. I am a C and C++ programmer and a bit lost in the world of JSON, JS, SCRIPT and others… And getting a bit frustrated not to be able to do this in my opinion simple task after trying for a couple of days already :slight_smile:

I would be worth while making this work with the SCRIPT transformation instead of the JS transformation. The JS transformation is going away in OH 4 (which should be released in June).

Do you mean literally nothing happens, as in the Item doesn’t update at all, or that the Item is updated but not divided by 10?

It is possible to add logging to a JS transform and as well as a SCRIPT transform. In the JS transform add this to the top of your function

        var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.JS Transform"); 

And use it like'This is an info log statement);.

If you use the SCRIPT transform, it depends on what scripting language you choose as to how to log from the transformation.

The item is not updating any more at all

I chose JS to be a bit closer to my “C” comfort zone…
What would be a good SCRIPT language choice for a simple divide by 10 ?

I guess the syntax then would be SCRIPT:<langauge>:scriptfie ?

Actually tried a script file like this on Sunday:

var retval = input / 10


And a Input Transformation like SCRIPT:dsl:tuya-energy.script

but the result was the same: The value stopped updating with no log messages.

There might be an error in my dsl file though

As there seems to be some confusion between documentation and “opinions” online about the syntax of the transformation instruction I also “SCRIPT(dsl:tuya-energy.script):%s”. But still with the same result: nothing happens and no updates.
But now I get this in the openhab.log:
2023-03-14 15:17:16.074 [WARN ] [t.generic.ChannelStateTransformation] - Transformation service SCRIPT(DSL for pattern tuya-energy.script):%s not found!

Will try without the ending “:%s”

I can finally report success. The correct entry in “Incoming Value Transformations” was: SCRIPT:graaljs:divby10.script where the JS file was situated in /etc/openhab/transform and called divby10.script. The file is pretty much the same as my original JS file and looks like this now:

(function(i) {
      return parseFloat(i) / 10;

Thanks for the support! But it shouldn’t really be this difficult :wink:

Now off to see how I can do the same for a ZigBee device that also scales by 10*

You could also take a look at SmartHome/J math transformation.

Any of them. You can use JS, but note there are two different versions. The JS that comes with openHAB is ECMAScript 5.1 (code named Nashorn) which is nearing 10 years since it was released. This version comes with Java 11 but not with Java 17 which is why the JS Transformation is gone for OH 4.0+.

There is an add-on for OH 4.0 which installs the Nashorn JS support in OH 4.0 or for those who choose to run OH 3.4.2 on Java 17.

There is also the JS Scripting addon which provides ECMAScript 2022 and comes with a really good helper library to make interacting with OH much smoother and easier. If you are planning on using JavaScript and are just getting started, I recommend the JS Scripting add-on over Nashorn.

The best choice for the transformation is what ever language you plan on using for your rules.

Add some logging but I think I know what’s wrong. input is a String. You have to parse it into a number before you can divide it. That at least is probably the problem with the DSL transform you tried.

new Float(input) / 10

That should work. What ever value the last line evaluates to is what is returned. So you con’t really need to assign that to a variable first.

The problem is the syntax changes slightly based on where it’s used. Each binding gets to define their own way to define the transform, and Profiles have their own way and SCRIPT(dsl:tuya-energy.script):%s is what you would use in an Item’s label or an Item’s state description pattern. The tansform action you can call from a rule uses yet a different format (because it splits the parts into arguments to the function call).

For MQTT, I’m pretty sure SCRIPT:dsl:tuya-energy.script is correct for the MQTT and HTTP bindings.

I’m glad you got it working. In my own experiments some things that might be causing problems (for future reference):

  • file permissions on the .script file are such that the opnehab user can read it
  • script language add-on is installed and you are referencing the right one (graaljs is the JS Scripting addon, js is Nashorn)
  • it might require a restart of OH for OH to see the .script file (this is weird and shouldn’t be the case, I’m going to file an issue on that)
1 Like