How to convert a number Thing into a string Item?

  • Platform information:
    • Hardware: RPi5
    • Java Runtime Environment: Temurin v21
    • openHAB version: 5.0.0

I am still new to openHAB.

I am struggling to convert a thing with a number output to a string item using the UI. The thing is a number representing a device status. I have configured the thing and a number item which works and shows e.g. 1026.

I even converted the number to a hex format with a pattern of 0x%04X in the state description pattern which shows the number as e.g. 0x0402. That makes it easier for decoding the status, since it is documented in this format.

Now I would like to decode the status number into a string of the status description. I figured I have to use the Value as Number channel of the thing and convert it somewhere into a string item. I tried using an ECMA Script as profile with the following Thing to Item Transformation:

| String.format(“0x%04H”, input)

The result is a time string like this 1970-01-01T01:17:06+01:00[Europe/Berlin]

With a Standard Profile it will show the same string.

I tried a Value to String channel but the output is empty.

Thing channels:

Result with Standard Profile:

Result with ECMA Script:

String channel with string item (no output):

The final goal would be to use the State Description of the string item to decode the status number in the options.

How can I achieve my goal?

This is a classic use of the Map transform:

You could technically chain transforms together if you want to base your map transform values off of the hex codes (0x0402=Some state), but since you’re getting the decimal codes it’ll be less brittle to just use those as the incoming values for the map (1026=Some state).

I struggle even before the map transform. I reckon I need an input string to use a map, right? Right now I have a number which I can’t convert to a string (my base data type is a a UInt16 out of a Modbus-Thing).

How do I make a string out of a number in the Thing to Item process?
Do I need a string as input to use the State Description?

I struggle to grasp where the type of data changes in the process. It would be logical if it is done in the Link of Thing Channel to Item.

I already use a Number Thing linked to a String Item in another case and it works. I use a ECMA Script in the Thing to Item Transformation of the UI to make the conversion in the Link of the Thing Channel to the Item.

The issue is, my Thing to Item Transformation | String.format(“0x%04H”, input) doesn’t work and I don’t know why.

Nope. The map transform will take care of that.

Here’s a map I use to transform a number channel into a Contact item:

23=CLOSED
22=OPEN
=UNDEF

I’m struggling to understand what you’re trying to achieve. Is it simply to output a number in hexadecimal format i.e. 0xNNNN (where NNNN are the hex digits) ?

javascript:

| '0x' + parseInt(input).toString(16).padStart(4, '0')

JRuby:

| "0x%04X" % input.to_i
1 Like

The problem seems to be somewhere else. It looks like I’m struggling with the UI. The results I get are very erratic.

I added several Items to the channel and I am getting strange results. I used the alternative Thing to Item Transformation | '0x' + parseInt(input).toString(16).padStart(4, '0') of @jimtng and got 98.8 as result and I’m not making that up!
Two other items with the same transformation show NULL as result

It seems like the transformation in the String Items just work once and after that stops working, except with the Number Item which reacts to changes in the configuration.

Maybe it’s a problem in the Modbus-Binding?

Let’s break things down because there are lots and lots of places where a value can be transformed.

  • Item’s label/State Description: This is what you’ve done with 0x%04X above but this only applies to the display of the state of the ITem. The Item’s state is still 1026. It only affects the UIs and not even everywhere you see the state of the Item in the UI (e.g. it doesn’t apply on the Items page and I think not in charts too).

  • Profile: This lives between the Item and the Channel on the Link. It intercepts the updates coming from the Channel to the Item and changes it in some way, and it intercepts commands coming from the Item to the Channel in some way. The changes can be as simple as creating a date time string for now to running a long and involved block of code.

  • Channel: Many (not all) bindings support transforming the raw data coming from the device on the Channel config itself. This mostly applies for low level bindings like MQTT, HTTP, and Modbus. When this is possible, there is usually a separate transformation for incoming and outgoing.

I have no experience with Modbus.

Is it possible to make this a String Channel to begin with? Under the covers OH normalizes pretty much everything to a String anyway so even though the value is a number, if you use a String Channel you’ll get the number as “1026” instead. Then it should be straight forward to apply the Map transformation as @JustinG described and link the Channel to a String Item. I know for sure this would work in MQTT and HTTP, I’m hoping it’s similar for Modbus.

If you keep it as a number Channel you have some options depending on whether you really want the state of the Item to be the humanreadable String, or if you just want to see the human readable String in the UI but keep the Item’s state a number (which might be easier to work with in rules, for example.

If the state of the Item needs to be a human readable string and to throw away the number and you can’t just use a String Channel to begin with, what you can do is either use the Map transformation on the Channel or apply it as a Profile.

One gotcha which might come to play here is OH might be preventing you from linking the Channel to any old Item and limiting it to just Number Items. It used to do that, and I don’t think the behavior has changed any. If that’s the case, this might be the root of the confusion.

You can cheat to work around this though. First create your Item as a Number Item. Link it to the Channel. Then change the type of the Item to a String. :smiling_face_with_horns: You’ll still need the Map transform either on the Channel or the Profile.

If you just want to see the nice text on the UI, just keep the Channel without a transformation. Do not add a profile to the Link and keep the Item as a Number Item. On the Item’s state description, apply the Map transformation to the pattern field.

MAP('mymapfile.map'):%s

I think I have the syntax for that right.

We need to see your actual configs

Also try this:

| output='0x' + parseInt(input).toString(16).padStart(4, '0'); console.log(input+'->'+output); output

I haven’t tested this, so if that doesn’t work, use return output at the end instead.

The profile will be executed whenever there’s a new data on the channel.

1 Like

Issue #1

I had a break-through!

The Modbus-Thing input must be transformed to an integer.

You have to make a Read Transform of

JS( | parseInt(input))

in the Modbus-Thing configuration. I did that before in other Modbus-Things but forgot about it.

After that, everything miraculously works as expected. Otherwise the input will be a float and this obviously breaks internals in the Channels and Links. Now I can have multiple working links to the Number Channel and the String Channel works as well including usage of a map in the State Description in all variants!

Issue #2

Formatting of the output still puzzles me a little. Here’s my configuration which still uses a float value of the Modbus-Thing.

Thing Number Channel Link. Value shows as 0x0402:

Link with Standard Profile. Value shows as 0x0402:

Item. Value shows as 0x0402:

State Description. Map is obviously ignored but pattern works:

Diagram. Value shown as raw integer 1026:

Main UI. Value shown as 0x0402:

Items list. Value shown as 1026.0:

The map in the State Description of the UI configuration is ignored, I guess because the value is a float and the map uses the ‘raw’ value.

The items list and diagrams show the raw value without a Pattern of the State Description. I assume Rules and Scripts will use that value also?

Using a single String Item linked to the Number Channel

In the Number Channel I unlinked the Number Item and linked to a single String Item. At first I got no output at all. The Thing to Item Transformation was not used at all, even with a constant output like | ‘Something’. Here I realised I hat to explicitly convert to an integer in the Modbus-Thing Read Transform, which I had left alone before and the input was transformed to a float value by default. This explains why it showed up as 1026.0 in the item list before with the Number Item.

I put in a Modbus-Thing Read Transform of

JS( | parseInt(input))

and then the Thing to Item Transformation would be executed.

Thanks to @jimtng the transformation

| '0x' + parseInt(input).toString(16).padStart(4, '0') :+1:

works, while

| String.format(‘0x%04X’, parseInt(input)) :-1:

does not.

Now the map in the State Description like

0x0402=Ok
=Undefined

works as well :partying_face: .

Using a String Item and a Number Item linked to the Number Channel

Now I was curious if a second Number Item beneath the String Item would work as well, and it did :partying_face: . The String Item shows as 1026 as expected and the Thing to Item Transformation to convert to hex display works as well as does the map in the State Description.

Using a String Item linked to the String Channel

After the Modbus-Thing Read Transform to integer this works as well as expected. I used the Thing to Item Transformation to format into hex display. I can now use the map in the State Description with the hex format values.

Thank you again @JustinG, @jimtng and @rlkoshak for your help!

I tried adding Items to other Modbus-Things with the default Read Transform and they worked fine :exploding_head:.
Must have been a problem with that specific Thing. I have the suspicion that the Main UI sometimes has issues during configuration, as the UI quite often freezes and you have to reload the page and I have seen some strange things where configurations of one Link showed up in another Link of the same Thing as if stuff got mixed up in the configuration.
I am heavily relying on the Main UI here for configuration since I am no HTML/Java expert.

If this is something you can reproduce or next time capture logs from the browser and file an issue.