-
Platform information:
- Hardware: CPUArchitecture/RAM/storage
- OS: Windows 7 64bit
- Java Runtime Environment: Zulu8
- openHAB version: 2.5
-
Issue of the topic: I am currently implementing into my openHAB configuration industrial flowmeter IFM SM8100 (SM8100 - Magnetic-inductive flow meter - ifm electronic). 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 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:
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:
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:
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:
#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 - Online Java Editor - Online Java IDE - Java Coding Online - Practice Java Online - Execute Java Online - Compile Java Online - Run Java Online” and it worked fine.