Transformation Problem JS, Inline Transformation, division by 10

Hi everyone, I have a problem with the transformation of an item.
I am getting weather data from the (quite) undocumented DWD Weather API that spits out JSON formatted Data. I am trying to extract the predicted minimum and maximum temperatures and the rainfall of today and tomorrow. These values are in 0.1°C and 0.1 mm, so a value of for example 150 in the JSON corresponds to 15.0°C. I would like to transform these values by dividing them by 10 to have the correct values in the Items.
My http.things file to get the values:

Thing http:url:DWDWetterHGW	"Wetterdaten aus der DWD API" [
	baseURL="https://dwd.api.proxy.bund.dev/v30/stationOverviewExtended?stationIds=10184",
	refresh=300
	]{
	Channels:
	[stateTransformation="JSONPATH:$.10184.forecast1.precipitationTotal"]
		Type string : VorhersageHeuteTempMin    "Vorhersage heutige Minimaltemperatur in °C"			[stateTransformation="JSONPATH:$.10184.days.[0].temperatureMin"]
		Type number : VorhersageHeuteTempMax	"Vorhersage heutige Maximaltemperatur in °C"			[stateTransformation="JSONPATH:$.10184.days.[0].temperatureMax"]
		Type number : VorhersageHeuteNiederschl	"Vorhersage heutiger Niederschlag in 0,1mm/d"			[stateTransformation="JSONPATH:$.10184.days.[0].precipitation"]
		Type number : VorhersageMorgenTempMin	"Vorhersage morgige Minimaltemperatur in °C"			[stateTransformation="JSONPATH:$.10184.days.[1].temperatureMin"]
		Type number : VorhersageMorgenTempMax	"Vorhersage morgige Maximaltemperatur in °C"			[stateTransformation="JSONPATH:$.10184.days.[1].temperatureMax"]
		Type number : VorhersageMorgenNiederschl	"Vorhersage morgiger Niederschlag in 0,1mm/d"		[stateTransformation="JSONPATH:$.10184.days.[1].precipitation"]
}

My http.intems:

Number:Temperature	DWDWetter_HGW_VorhersageHeuteTempMin	"heutige Min Temp [%.1f °C]"        {channel="http:url:DWDWetterHGW:VorhersageHeuteTempMin"[profile="transform:JS", function="| input / 10"]}
Number:Temperature	DWDWetter_HGW_VorhersageHeuteTempMax	"heutige Max Temp [%.1f °C]"        {channel="http:url:DWDWetterHGW:VorhersageHeuteTempMax"[profile="transform:JS", function="| input / 10"]}
Number:Speed		DWDWetter_HGW_VorhersageHeuteNiederschl	"heutiger Niederschlag [%.1f mm/d]"	{channel="http:url:http:url:DWDWetterHGW:VorhersageHeuteNiederschl"[profile="transform:JS", function="| input / 10"], unit="mm/d"}
Number:Temperature	DWDWetter_HGW_VorhersageMorgenTempMin	"morgige Min Temp [%.1f °C]"        {channel="http:url:DWDWetterHGW:VorhersageMorgenTempMin"[profile="transform:JS", function="| input / 10"]}
Number:Temperature	DWDWetter_HGW_VorhersageMorgenTempMax	"morgige Max Temp [%.1f °C]"        {channel="http:url:DWDWetterHGW:VorhersageMorgenTempMax"[profile="transform:JS", function="| input / 10"]}
Number:Speed		DWDWetter_HGW_VorhersageMorgenNiederschl  "morgiger Niederschlag [%.1f mm/d]" {channel="http:url:DWDWetterHGW:VorhersageMorgenNiederschl"[profile="transform:JS", function="| input / 10"], unit="mm/d"}

The transformation with JavaScript I copied from a posting from Rich Koshak in another Topic
In my case it does not work though. I get the following Error:

[.module.script.profile.ScriptProfile] - Neither 'toItemScript' nor 'toHandlerScript' defined in Link 'DWDWetter_HGW_VorhersageHeuteTempMax -> http:url:DWDWetterHGW:VorhersageHeuteTempMax'. Profile will discard all states and commands.

When searching for the Error message, I found this thread. Here the transformation is handled in a .js file, which I would like to skip to keep things simple, because there seems to be the inline transformation that Rich suggested.

I’m currently running OH 4.1.3. I have tried restarting the VM (Ubuntu 22.04) and restarting OH, neither of this fixes the problem. The Items get filled with the “correct” data (150 in the example case) if I delete the “[profile=“transform:JS”, function=”| input / 10"]". Other Items in the .items file function as they should.
What could be the problem here?

Short workaround for the Temperature (that I don’t intend to keep):
One can use the SI-prefix “deci” (d) also in addition to °C (somehow obvious but I have never encountered deci°C in the wild). This does not work for the rainfall because the next smaller si-prefix from mili (10^-3) is mikro (10^-6) but I would need 10^-4.

First, chain the transforms on the Channel. When using HTTP or MQTT bindings (some others too) you can chain transformations using the character. This keeps all the transformation stuff in the same spot.

Also be sure to add unit metadata to your Item to specify the unit of the Item’s state. You probably don’t want to rely on the system default for Speed which I think is meters, not millimeters.

Finally, that posting of mine I think was using Nashorn JS, not JS Scripting. In JS Scripting you have to parse the String input into a number before you can do math with it.

JSONPATH:$.10184.days.[0].temperatureMin∩JS:| parseFloat(input)/10
1 Like

Thank you Rich for the fast answer and the help. This works very well and as you stated, keeps the transformation all nice in one spot.
In the meantime, i tried the something from my second linked topic and substituted the

[profile="transform:JS", function="| input / 10"]

with

[profile="transform:JS", toItemScript="| input / 10"]

This works as well, but like you said, keeping this all in one place is much nicer in my case. In case anyone needs the transformation in the .items file, above mentioned code works there.

Hmm…
https://dwd.api.bund.dev/
In fact, its documentation seems very ok to me :slight_smile:

In question of the “easy” way to define the channels:

    Type number : tempMin0 "Temperatur Min heute" [stateTransformation="JSONPATH:$.10184.days[0].temperatureMin",unit="d°C"]

The unit “d°C” is “Deci Degree Celsius” :slight_smile: The Units of Measurement are quite powerful…

1 Like

That’s what I meant with the short workaround in the edit of my original post. But because deci°C is not a usual Unit, I chose to not use it and did the same transformation for all Channels as Rich suggested (as explained I needed the Javascript transformation to work for the mm rainfall anyways).
And yes, the API is ok documented, but this API is not documented by the DWD but rather by people from the Group zerforschung that found out, that the DWD Weather APP uses this API for the communication with the DWD Servers. The bund.dev page was created by Lilith Wittmann and only looks like it is from a state agency.
I just stumbeled on this documentation, looked at the data and added several lines to the GitHub page of the DWD-API regarding the UoM of the JSON Values. These are not documented on the dwd.api.bund.dev page.
I was looking for an alternative for the Openweathermap (I didn’t want to switch to the new onecall API and give them my payment info) so i was searching for an API from the DWD and found this “loophole”. I would love if there was a binding using this API but sadly I am not capable of programming one. So I went with using the http binding to manually create the things and items.

I think @Udo_Hartmann’s point though is that you could set the unit on the HTTP Channel to d°C and the unit metadata on the Item to °C and OH would convert the value for you without the transform. I didn’t know that d°C was a thing, let alone that OH UoM supports it. Had I know I would have suggested that approach to.

The point of setting the unit on the Channel is to indicate to OH what unit the value is being published as. The point of setting the unit metadata on the Item is to indicate what unit you want to use. And the point of the state description pattern unit is to indicate what unit you want to see in the UIs. These units need not all be the same and OH will convert as necessary between them automatically. There’s no need to write a transformation.

1 Like

Hey, for applying this divide-by-10 JS transform (SCRIPT ECMAScript) via a Thing Channel Profile in the UI, would it look like either of these under Thing to Item Transformation?

JS(| parseFloat(input)/10)

OR

parseFloat(input)/10

My initial Number reading of 2351 V doesn’t seem to be changing.

I’m not sure if the plug Voltage reading just hasn’t received an update yet to show the transformation, or if I’ve entered something incorrectly and it’s supposed to show immediately :thinking:

OpenHAB 4.3.3
Docker
Raspberry Pi 4B 8GB
Tuya Binding from 3rd-party Smartj

Let me know if any more info is needed :+1:

Neither.

Yo’ve already told it it’s a JS so you don’t need the “JS” part but you still need to tell it this is an inline script and not to go looking for a file. So you still need the “|”.

| parseFloat(input)/10

There should be errors in the log if something is wrong.

1 Like

but you still need to tell it this is an inline script and not to go looking for a file. So you still need the “|”.

That did the trick, thank you! :glowing_star:
And running the appliance attached to the outlet finally triggered an update :raised_hands: