How to change the raw state of an item in OH3

I am retrieving data through the gpstracker binding. Unfortunately that binding does not support to provide the “speed” of the object. Anyway I figured I can just just use one of the available fields like “accuracy” (which I don’t need) and put the speed into that field.
This has been working so far.

It turns out though that even though within the Android app speed is measured in km/h, the item actually retrieves the values in m/s.
I then figured I would use a profile + Javascript to transform the value.

So i added this to my item definition:

Number Andreas_Handy_Speed "Andreas Handy Geschwindigkeit" <speed>   {channel="gpstracker:tracker:XY:gpsAccuracy" [profile="transform:JS", function="speed.js"]}

My understanding was that by using such a profile I would actually change the underlying “raw” value instead of changing how to display this item. The reason I wanted to do that is that I also want to display a chart and charts don’t care about displayStates.

In the logfile I see the values without transformation.

In the API explorer, I see that a transformation is applied:

{
  "link": "https://192.168.178.140:8443/rest/items/Andreas_Handy_Speed",
  "state": "2",
  "transformedState": "7.2",
  "stateDescription": {
    "pattern": "JS(speed.js):%s",
    "readOnly": true,
    "options": []
  },
  "editable": false,
  "type": "Number",
  "name": "Andreas_Handy_Speed",
  "label": "Andreas Handy Geschwindigkeit",
  "category": "speed",
  "tags": [],
  "groupNames": []
}

But the chart in the BasicUI sitemap does not seem to pick up on this transformation. It still shows the non-transformed “raw” values.

I read in another thread that using profiles would actually do that, but not sure if that still applies in OH3.
So my question is how can I change the raw values of my item? Or maybe how can I make charts to consider the transformedState instead of the rawState?

OH 3.4

Thanks a lot!

That is somewhat correct. There isn’t really a “raw” value. There’s the value received by the binding and sent on to the Item as a state update. The Profile intercepts that state update and substitutes it’s own, in this case substituting it with the result of the speed.js script.

When it works, the Item never sees the “raw” state. Either the profile is working or it isn’t. That’s one thing you’ve not posted.

You’ve not told the whole story here.

First of all, what you are seeing is the Item’s record and you are seeing that you’ve applied the transform as the stateDescription pattern. That indeed only changes how the Item’s state is displayed, not what state the Item stores.

But Profiles don’t exists on the Item. They exist on the ItemChannelLink. That’s a wholly separate entity in OH with a separate API endpoint and wholly separate record. What does that record show?

At a minimum, you’ll have to remove the transform from the stateDescription pattern from the Item’s metadata.

Note that the transformedState that you see is what the Item will show on the UI after applying the stateDescription pattern. Assuming that 2 is m/s it does appear that your speed.js transform is working. But it’s not applied in the right place, or it’s being applied twice , once in the profile and again for the stateDescription.

You’ll have to be more specific. Which logs?

Hi Rich,
Thanks for the explanation so far. I guess I am not sure how to retrieve some of the information. You are talking about the ItemChannelLink. I retrieved the thing-types via the API (get /thing-types/thingTypeUID) and that gave me

{
      "description": "GPS-Genauigkeit",
      "id": "gpsAccuracy",
      "label": "Genauigkeit",
      "tags": [],
      "properties": {},
      "stateDescription": {
        "pattern": "%.1f %unit%",
        "readOnly": true,
        "options": []
      },
      "advanced": false,
      "typeUID": "gpstracker:gpsAccuracy"
    }

Doesn’t seem to me as if any transformation is applied at that level.
How do I even apply a transformation to the ItemChannelLink. Since I am doing everything file-based, do I define a custom channel in the .things file? I didn’t find much information on how to do that. Or do I have to modify the binding for this (I’m not the author of that binding)?

The logfile I was talking about is the events.log, which also shows the not transformed values.

BTW The profile seems to be working to some extent, since the value displayed in the sitemap shows the transformed value and I haven’t done anything that would do that in the sitemap configuration.

Thanks for your patience :slight_smile:

Look under the “links” API endpoint.

{channel="gpstracker:tracker:XY:gpsAccuracy" [profile="transform:JS", function="speed.js"]}

You did so right there. channel means you are defining an ItemChannelLink and the [profile... defines the profile on that ItemChannelLink.

Oh but you did. You defined the State Description metadata on the Item and set the pattern to use your transformation.

I guess I’m confused now.
I get this from the link API endpoint

{
  "editable": false,
  "channelUID": "gpstracker:tracker:XY:gpsAccuracy",
  "configuration": {
    "profile": "transform:JS",
    "function": "speed.js"
  },
  "itemName": "Andreas_Handy_Speed"
}

which suggests to me that the transformation is in place.
When the binding updates a value or I do a manual .postUpdate it still doesn’t behave as expected, but as described above. Values seem to be only transformed when displayed, not in the cart though. Also when I hover over the item in VSCode with the openhab extension it gives me the non-transformed value.
I just figured I might try to reboot openhab, which I did. Since then I am not able to get the transformation working at all.

While I am trying to figure out why that is, I am wondering if it’s even possible to debug this via .postUpdate. I am guessing that it’s not? I am asking because I don’t seem to be able to get the binding to update the value in question and I would still like to test this.
While I write this I realize that I can use another value from the binding for which I am still getting updates, which I will do. Still curious if a .postUpdate undergoes the transformation of the ItemChannelLink (I guess not).

Yes, that’s what I wanted to confirm.

And we have evidence that the speed.js transform is working because of the way it’s applied to the state description pattern.

Updating the Item is going to bypass that transform. A Profile only applies to the value as it flows from the Channel to the Item. That’s why it lives on the ItemChannelLink. When you update an Item, you are changing the Item directly, bypassing the Link and the Channel so no transform will take place.

There is no reason to transform it twice, so please, as I’ve asked at least twice now, remove the state description pattern. All it’s doing is confusing you and when the Profile starts working, it will show the wrong value in the UI.

Correct, it’s only going to show you the Item’s actual state. The “transformedState” only applies to how it appears in the UI.

Then you have something different and more serious going on. It’ll probably be best to open a separate issue for that.

No, like I said, a Profile only applies as the value passes from the Thing Channel to the Item. postUpdate bypasses that.

You will have to figure that out. I know of no other way to test a Profile like this.

I recommend the following course of action.

  1. Remove the State Description Pattern
  2. Add logging to your transform along these lines (this is notional and is not a full JS transform).
    var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.speed");
    logger.info("Speed input: " + input);
    // your transformation calculation
    logger.info("Speed output: " + rval);
    return(rval);
  1. Watch your logs for those two log statements. You should only see them when the binding updates the Item. The input line tells you what the binding is reporting. The output line tells you what the speed.js transformed the value to.

  2. Figure out how to cause the binding to send a value on that Channel. Again, postUpdate isn’t going to work. That bypasses the Profile.

Don’t know why I didn’t start to debug within the javascript file right away as I am already familiar with that.
The problem I found there was that the binding gave me not just a number but also the unit of measurement. My very basic arithmetic operation which tried to multiply with 3.6 failed and gave me NaN and therefore never updated the item value.
All the things I saw before were some sort of residue of my initial attemps to modify the visualisation in the sitemap. I know you asked me to remove those many times and I actually did, but for some reason it took a restart for those changes to become active.

Thanks for your patience and I hope that this may be helpful to others, be it the general explanation from Rich or the idea to debug through the logging within the Javascript.

Thanks again!