# Conversion form HEX string to Float32 and Signed Int16

**URL:** <https://community.openhab.org/t/conversion-form-hex-string-to-float32-and-signed-int16/118327>\
**Category:** Scripts & Rules\
**Tags:** rules, binding, http\
**Created:** [March 4, 2021, 2:42pm UTC](https://community.openhab.org/t/conversion-form-hex-string-to-float32-and-signed-int16/118327 "2021-03-04T14:42:38Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![vselitsky](https://community.openhab.org/user_avatar/community.openhab.org/vselitsky/32/69631_2.png) [@vselitsky](https://community.openhab.org/u/vselitsky)\
**Post date:** [March 4, 2021, 2:42pm UTC](https://community.openhab.org/t/conversion-form-hex-string-to-float32-and-signed-int16/118327/1 "2021-03-04T14:42:38Z")

</div>

- Platform information:

- Issue of the topic: I am currently implementing into my openHAB configuration industrial flowmeter IFM SM8100 ([SM8100 - Magnetic-inductive flow meter - ifm](https://www.ifm.com/gb/en/product/SM8100)). I am getting data with http binding using JSONPATH trasformation. The transformed data are a hex string of 16 bytes like “42C3DC29FFDE060D”. First 8 bytes represent Totalizer in Float32 format. Next 4 bytes stand for Flow (signed int16) and last 4 bytes represent Temperature (signed int16). Unfortunately both cases - HEX-to-Float32 and HEX-to-Int16 - are missing in the great tutorial [Type Conversions](https://community.openhab.org/t/type-conversions/32684) of @rlkoshak.  
I’m not a java programmer and did some research. I found simple and effective solution for both convertions, but only HEX-to-Float32 works at the moment. Here are the code parts.

- Items:

```auto
String Port2 "Port2 Process Data [%s]" {http="<[iolinlkmasterPort2:1000:JSONPATH($.data.value)]"}

Number:Volume Port2_Totalizer "Totalizer Volume: [%.2f L]" <cistern> 

Number:VolumetricFlowRate Port2_Flow "Flow Rate: [%.1f L/min]" <flow> 

Number:Temperature Port2_Temperature "Temperature [%.1f °C]" <temperature>

```

- Sitemap:

```auto
sitemap IFM label="IFM Devices" {

Text item=Port2 label="Port2 Raw Process Data [%s]"

Text item=Port2_Totalizer

Text item=Port2_Flow

Text item=Port2_Temperature

}

```

- Rules:

```auto
import org.apache.commons.lang.StringUtils

rule "Port2 Temperature" 

when     

    Item Port2 received update or

    System started

then

    val Port2AsString = Port2.state.toString

    //Right 4 bytes represent Temperature

    val Port2_Temp_Bytes = StringUtils.right(Port2AsString, 4)

    //Left 8 Bytes represent Totalizer

    val Port2_Totalizer_Bytes = StringUtils.left(Port2AsString, 8)

    //Next 4 Bytes to right contain Flow

    val Port2_Flow_Bytes = StringUtils.substring(Port2AsString,8,12)

    logInfo(">>> Port2 Temperature Raw<<<", Port2AsString)

    logInfo(">>> Port2 Temperature Bytes<<<", Port2_Temp_Bytes)

    logInfo(">>> Port2 Flow Bytes<<<", Port2_Flow_Bytes)

    logInfo(">>> Port2 Totalizer Bytes<<<", Port2_Totalizer_Bytes)

    //Conversion HEX-to-Int16

    var MyTemp = (short) Integer.parseInt(Port2_Temp_Bytes, 16) as Number

    var MyFlow = (short) Integer.parseInt(Port2_Flow_Bytes, 16) as Number

    //Conversion HEX-to-Float32

    var i = Long.parseLong(Port2_Totalizer_Bytes, 16) as Number

    var MyTotalizer = Float.intBitsToFloat(i.intValue()) as Number

    //

    Port2_Temperature.postUpdate(MyTemp)

    Port2_Flow.postUpdate(MyFlow)

    Port2_Totalizer.postUpdate(MyTotalizer)

end

```

- Services configuration:

```auto
#IFM

iolinlkmasterPort2.url=http://192.168.0.200/iolinkmaster/port%5B2%5D/iolinkdevice/pdin/getdata

iolinlkmasterPort2.updateInterval=1000

```

Evidently `var MyTemp = (short) Integer.parseInt(Port2_Temp_Bytes, 16) as Number` is not working as Visual Studio shows message “Type mismatch: cannot convert from Class to String”. What should I change to get a correct result? I tested the original code:

> ```
> short s = (short) Integer.parseInt(myString,16);
> System.out.println(s);
> 
> ```

in “[Online Java Compiler & IDE - Write, Run & Debug Java Code](https://www.tutorialspoint.com/compile_java_online.php)” and it worked fine.

---

<div class="post-metadata">

**Author:** ![rlkoshak](https://community.openhab.org/user_avatar/community.openhab.org/rlkoshak/32/75251_2.png) [@rlkoshak](https://community.openhab.org/u/rlkoshak)\
**Post date:** [March 4, 2021, 3:13pm UTC](https://community.openhab.org/t/conversion-form-hex-string-to-float32-and-signed-int16/118327/2 "2021-03-04T15:13:14Z")

</div>

Why parse to an `int` only to force it to a `short`? Use `Short.parseShort` in the first place and no conversion is necessary.

I’m pretty sure the `as Number` is going to cause some problems. `parseInt` returns a primitive `int`. `Number` is a type for an Object. You can’t just say “I know you are a primitive but now I want to use you like an Object.” If you really want the result to be a Number Object use `getShort` instead of `parseShort`. That will return a `Short` Object which implements `Number` so you can cast it to `as Number` if you want to.

---

<div class="post-metadata">

**Author:** ![vselitsky](https://community.openhab.org/user_avatar/community.openhab.org/vselitsky/32/69631_2.png) [@vselitsky](https://community.openhab.org/u/vselitsky)\
**Post date:** [March 4, 2021, 3:29pm UTC](https://community.openhab.org/t/conversion-form-hex-string-to-float32-and-signed-int16/118327/3 "2021-03-04T15:29:47Z")

</div>

Look Rich @rlkoshak , Short.parseShort does not accept values higher than 0x8000. In my case I get negative values as well because temperatures can be negative and flow can have opposite direction. In my example “42C3DC29FFDE060D” the flow value is negative and represented by “FFDE”. So Short.parseShort goes out of the permitted range. Is it the same range with getShort?

---

<div class="post-metadata">

**Author:** ![rlkoshak](https://community.openhab.org/user_avatar/community.openhab.org/rlkoshak/32/75251_2.png) [@rlkoshak](https://community.openhab.org/u/rlkoshak)\
**Post date:** [March 4, 2021, 3:36pm UTC](https://community.openhab.org/t/conversion-form-hex-string-to-float32-and-signed-int16/118327/4 "2021-03-04T15:36:43Z")

</div>

> [@vselitsky](#):
>
> Is it the same range with getShort?

Most likely. `short` is a 16 bit signed twos compliment integer. Java doesn’t have unsigned shorts.

---

<div class="post-metadata">

**Author:** ![vselitsky](https://community.openhab.org/user_avatar/community.openhab.org/vselitsky/32/69631_2.png) [@vselitsky](https://community.openhab.org/u/vselitsky)\
**Post date:** [March 4, 2021, 3:44pm UTC](https://community.openhab.org/t/conversion-form-hex-string-to-float32-and-signed-int16/118327/5 "2021-03-04T15:44:30Z")

</div>

> [@vselitsky](#):
>
> getShort

Thanks for the tip Rich @rlkoshak , the solution appeared to be the following:

`var MyFlow = Integer.parseInt(Port2_Flow_Bytes, 16).shortValue() as Number`

I reckon it might be useful to add this two conversions in your tutorial for stupid guys like me.

---

<div class="post-metadata">

**Author:** ![rlkoshak](https://community.openhab.org/user_avatar/community.openhab.org/rlkoshak/32/75251_2.png) [@rlkoshak](https://community.openhab.org/u/rlkoshak)\
**Post date:** [March 4, 2021, 3:48pm UTC](https://community.openhab.org/t/conversion-form-hex-string-to-float32-and-signed-int16/118327/6 "2021-03-04T15:48:09Z")

</div>

You still do not need the `as Number` and in some cases that will cause problems. `shortValue()` returns a primitive `short`, not an Object of type `Number`. You can’t just cast it to become one.

A lot of times though Rules DSL will convert numbers to BigDecimal behind the scenes which might be happening here and is why you don’t see a problem. But don’t count on that always working in all cases.

---

<div class="post-metadata">

**Author:** ![vselitsky](https://community.openhab.org/user_avatar/community.openhab.org/vselitsky/32/69631_2.png) [@vselitsky](https://community.openhab.org/u/vselitsky)\
**Post date:** [March 4, 2021, 3:52pm UTC](https://community.openhab.org/t/conversion-form-hex-string-to-float32-and-signed-int16/118327/7 "2021-03-04T15:52:27Z")

</div>

Sorry Rich @rlkoshak , when I took off as Number type it stopped working: with negative value always gives 0.
