- Platform information:
- Hardware: 4690k, 32gb, spinning rust
- OS: Debian Buster Docker
- Java Runtime Environment: whatever comes with docker latest
- openHAB version: latest
- Issue of the topic: Trouble combining bytes into float
For some reason the manufacter likes to supply json which split each upper and lower byte into separate fields.
Here is an example of the atrocity I am dealing with:
{"nodenr": 23,
"ch_temp_lsb": 219,
"ch_temp_msb": 21,
"tap_temp_lsb": 181,
"tap_temp_msb": 18,
"ch_pressure_lsb": 126,
"ch_pressure_msb": 0,
"room_temp_1_lsb": 235,
"room_temp_1_msb": 8,
"room_temp_set_1_lsb": 164,
"room_temp_set_1_msb": 6,
"room_temp_2_lsb": 255,
"room_temp_2_msb": 127,
"room_temp_set_2_lsb": 255,
"room_temp_set_2_msb": 127,
"displ_code": 126,
"IO": 0,
"serial_year": 14,
"serial_month": 12,
"serial_line": 15,
"serial_sn1": 1,
"serial_sn2": 69,
"serial_sn3": 51 ,
"room_set_ovr_1_msb": 6,
"room_set_ovr_1_lsb": 64,
"room_set_ovr_2_msb": 0,
"room_set_ovr_2_lsb": 0,
"rf_message_rssi": 33,
"rfstatus_cntr": 0}
All of these values are floats and as of such I would like to recombine the separate fields into their corresponding value. Below is what I have so far the most important part being the rules section.
Currently my output by rules is the following:
2020-06-20 10:42:04.346 [INFO ] [el.script.>>> HeatingDescription <<<] - 95c
2020-06-20 10:42:04.347 [INFO ] [el.script.>>> HeatingDescription <<<] - 2396
2020-06-20 10:42:04.348 [INFO ] [el.script.>>> HeatingDescription <<<] - 0
2020-06-20 10:42:04.349 [INFO ] [el.script.>>> HeatingDescription <<<] - 0
The javascript on the webplatform responsible for converting this mess achieves it
through the following: (jsondata.room_temp_1_lsb + jsondata.room_temp_1_msb*256) / 100
Items:
Number temperature_lsb { http="<[http://192.168.3.254/data.json:30000:REGEX(.*?\"room_temp_1_lsb\": (.*?),.*)]" }
Number temperature_msb { http="<[http://192.168.3.254/data.json:30000:REGEX(.*?\"room_temp_1_msb\": (.*?),.*)]" }
String temperature
Sitemap
sitemap default label="My home automation" {
Frame label="Demo" {
Text item=temperature_lsb label="Living Room [%.1f °C]" icon="temperature"
Text item=temperature_msb label="Living Room [%.1f °C]" icon="temperature"
Text item=temperature label="Living Room [%s]" icon="temperature"
}
Frame label="Chart" {
Chart item=temperature_lsb label="Temperature chart" refresh=10000 period=h
Chart item=temperature_msb label="Temperature chart" refresh=10000 period=h
}
}
Rules
import java.math.BigDecimal
import org.openhab.core.library.types.*
rule "LivingRoomCombine"
when
Item temperature_lsb received update or
Item temperature_msb received update or
System started
then
val int default_int = 0
val String hex_lsb = if (temperature_lsb.state instanceof DecimalType) Integer.toHexString((temperature_lsb.state as DecimalType).intValue) else Integer.toHexString(default_int)
val String hex_msb = if (temperature_msb.state instanceof DecimalType) Integer.toHexString((temperature_msb.state as DecimalType).intValue) else Integer.toHexString(default_int)
val String hex = String::format("%s%s", hex_msb, hex_lsb)
logInfo(">>> HeatingDescription <<<", hex)
val DecimalType hex_int = new DecimalType(Integer.parseInt(hex, 16))
logInfo(">>> HeatingDescription <<<", String::format("%1$.0f", hex_int.toBigDecimal))
val Float hex_float = Float.intBitsToFloat(hex_int.intValue)
val DecimalType hex_deci = new DecimalType(hex_float)
logInfo(">>> HeatingDescription <<<", String::format("%1$.0f", hex_float))
logInfo(">>> HeatingDescription <<<", String::format("%1$.0f", hex_deci.toBigDecimal))
val BigDecimal temperature_lsb_t = if (temperature_lsb.state instanceof DecimalType) (temperature_lsb.state as DecimalType).toBigDecimal else new BigDecimal(0)
val BigDecimal temperature_msb_t = if (temperature_msb.state instanceof DecimalType) (temperature_msb.state as DecimalType).toBigDecimal else new BigDecimal(0)
var String formattedString = String::format("%1$.0f°C / %2$.0f°C", temperature_lsb_t, temperature_msb_t)
temperature.postUpdate(new StringType(formattedString))
end
Services
# timeout in milliseconds for the http requests (optional, defaults to 5000)
#timeout=
# the interval in milliseconds when to find new refresh candidates
# (optional, defaults to 1000)
#granularity=
# whether to substitute the current time or state value into the URL
# (optional, defaults to true)
#format=
# configuration of the first cache item
thermostat.url=http://192.168.3.254/roomthermostat.htm?heater=0
thermostat.updateInterval=5000