# Something is rounding my float values in sitemap

I’ve got OH1 succesfully reading a few things from my PLC, one of them being a float32 number which is temperature. I have a couple hardware modbus panels and also the AdvancedHMI software and they all read this number just fine and display it along with the decimal point, like 68.1F. However when I use OH1, and display this number in the sitemap, it rounds it to the nearest half digit. so it’ll show 68, 68.5, 69. it won’t show 68.1, or 68.2, etc. I’m reading the PLC with a hardware panel at the same time to check and it has no problem picking up a value of 66.3, but OH1 sitemap rounds it to 66. if the value goes up to 66.6, OH1 rounds it to 66.5

Long story short, the only decimal place it will show is .5. It’s like there’s something in java somewhere forcefully rounding the float32 number to the nearest half digit.

This is what’s in my item:.

Number TempAvg “Temp [%.1f]” (All) {modbus=“slave2:0”}

Indeed there is, the `[%.1f]` means print the state as a floating point number with only one decimal place. If you want 5 decimal places change it to `[%.5f]`. If you want to see the full floating point number in all its inaccurate glory use `[%f]` or `[%s]`. Note, after about the thousandths place the digits will be next to useless.

the full documentation for the % formatting notation is here:

https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html

I think you might have misread my post, sorry for not wording it very well.

I only need 1 decimal place, but have it actually show something other than .5. The issue is the only decimal value it is showing is .5 - not .1, .2, .3, etc. It jumps from a whole number like 65, all the way to 65.5, even if the real float number from the plc is 65.3. It’s rounding the decimal value to either .5 or a whole number.

The only states I am getting after the decimal point is 0 or 5, that;s it. Something is rounding the value to the nearest half digit.

For instance, right now the PLC value is a very stable 68.4. But this is all OH shows - http://i.imgur.com/1R84gaV.png
All my other software and devices are showing the correct 68.4 except for OH which is rounding it

if the value on the PLC rises to 68.5 or above, OH will round it to 68.5, then to 69, It will not show any decimal number other than 5

What binding version is in use? (there is a 1.9 with many improvements) May we see your binding config, where you set the float32 type?

Is there a way to check binding version other than just checking the package with dpkg? to install it I did a “apt-get install openhab-addon-binding-modbus” while following this guide: https://github.com/openhab/openhab/wiki/Linux-and-OS-X (I’m on debian 8)

Status: install ok installed
Priority: optional
Section: misc
Installed-Size: 179
Architecture: all
Version: 1.8.3

binding config:

modbus:tcp.slave2.connection=192.168.1.18
modbus:tcp.slave2.start=28759
modbus:tcp.slave2.length=2
modbus:tcp.slave2.type=holding
modbus:tcp.slave2.valuetype=float32

You have the 1.8.3 binding then, as it shows for the “Version” line.

This is almost certainly something occurring in the binding.

What’s the recommended way of replacing the binding with the newer version, if I installed it via apt? should I do an apt remove to get rid of the 1.8.3 modbus binding?

Then manually copy over the modbus binding from that link? If I remember right the modbus binding had a dependency as well (serial), should I grab the updated version of that from the link as well? Any way to just grab an updated version/repo from apt? I wonder why installing following the install guide fetches such old packages, is there a beta/snapshot repo I can switch to? Thanks for the help!

Move the 1.8.3 one out of the addons directory and copy the 1.9 jar file into it. The dependencies should be the same. That link will only have the addon jar files so any dependencies will not be at that link anyway.

The nightlies are not available via apt-get. 1.8.3 is the current released/stable version of 1.8.3. It is only a couple of months old. Verison 1.9 is the bleeding edge undergoing current development versions. There will never be a 1.9 release. As things stabilize the current 1.9 version may be released as 1.8.4.

In other words, the version you have is not old, it is just that the developer has recently (last couple of months) made several changes to the binding.

ah ok, that makes sense. I’ll do that and report back. Thanks again for all the help, this is my first day with OH

so I switched to the 1.9 binding and restarted everything just to be safe and I’m sad to report the exact same behavior

Let me take a wild guess, your Item is called “TempAvg”, that sounds like you are trying to display an average value. How do you calculate that average?

It’s an average of several temp sensors that the PLC itself is calculating. OH is doing zero math. Like I stated 3 times now, I am reading the exact same modbus register with three other devices and they all have no problem displaying the value properly

Discovered something extremely strange which I think definitely confirms it’s a bug in the modbus binding.

This behavior of rounding and not grabbing the full float string only happens when polling modbus registers above about 28707.

To deduce this, in my PLC I copied the same long float number to a huge block of floating point registers from about 28685 to 28755 - so to be clear, all these registers hold the exact same floating point value.

Then in OpenHab config, the only thing I changed was the “modbus:tcp.slave2.start=28685” line - changing the number lower and lower until the bug disappeared. once the register it was trying to read got down to about 28707, the bug disappeared, it stopped only displaying “67.0”, and started showing the proper value of “67.10687255859375”

That was fun to diagnose! I changed numbers pretty quick so I’m not sure exactly what register number the bug starts appearing, but it’s somewhere around 28707, I’ll try to figure out the exact number later. To be clear, with other software such as AdvancedHmi, it read every single one of these registers correctly and always returned the full float string, so definitely something Openhab specific.

Should I report this on github so the modbus contributors see it easier?

Just confirmed the point this begins happening is register 28709 - I can poll 28707 or lower and it properly retrieves "“67.10687255859375"”

However when I poll 28709 (two registers higher as they are floating point registers which occupy two), the bug begins and it only returns “67.0” and switching back and forth and having this happen is 100% reproducible

I think those addresses fall outside standard Modbus range for input or holding registers.
@ssalonen is likely the fellow with best insight here. As you can reproduce now, a bug report on github would look like a good idea

Thanks for the quick reply! according to wikipedia the range for holding registers was extended to 400001-465535 and that falls in line with all the modbus enabled gear I’ve dealt with in the past 10 years, I think it’s been quite some time since I’ve seen equipment with holding registers that only fell within the original 70’s spec “40001 to 49999” limit

Another issue I’ve ran into is that float32 values are inaccurate by quite a lot which is extremely odd, and unlike the above bug it doesn’t matter which registers they are. There’s definitely some math bug going on.

Here’s an example, every other modbus program I can find at 6am reading it with no problem except for OpenHAB - http://i.imgur.com/eJOaaDq.png

I’ll definitely write a github issue sometime tomorrow with all this, thanks!

To complete the picture, trying reading the same register pairs as uint32 datatype to see if it is the reading process and/or the floating point parsing process that is inconsistent.

"according to wikipedia the range for holding registers was extended to 400001-465535"
umm, well de-facto extensions are not the same as formal standards. This whole area confuses me, dunno about anyone else. Everybody’s Modbus is different.

I believe what should happen though is that we should specify the offset in OH config, i.e. the address without the 40,000 (old standard) or 400,000 (current practice) “prefix”. Strictly speaking it’s the offset-1 since we want to start from zero not 1.
The binding should put this offset out unmolested in the actual protocol. And I think you are correct, it should pass values in the 0-65,535 range, not try to enforce adherence to any standard that few devices fully follow in practice.
It’s up to the user to configure sensible values for each unique device.

It seems deeply suspicious that your observed change in behaviour is around (word) register offset 28,000 ; which is byte addressing 66,000 ; i.e. an overflow if the binding or libraries it incorporates is using 16-bit integer or buffer internally somewhere. This wouldn’t show up with old-style 1-9999 addressing as found in most simple slaves.

@fohdeesha Could you please try to read with uint 16bit data type to keep the test really simple?

The binding addressing is covered in the modbus binding wiki page. Essentially, the user configures the address that goes on the wire (zero-based index).

Quick glance through the code seems to indicate that the address are written as 16bit java `short`, the address is stored 32bit `int` int format. I could not find any other reference to writing this. 16 bit short should be OK I guess?

Regarding the floating point issues you experienced, that’s really weird and have not noted same behaviour. There’s really no “random” behaviour that I know in the implementation.

Generally speaking, perhaps you could use some other modbus server for testing purposes? Would diagslave (as documented in the wiki) work for you?

[quote=“ssalonen, post:18, topic:13704”]Quick glance through the code seems to indicate that the address are written as 16bit java short
[/quote]
mm, that is signed isn’t it? If the code (binding or serial libraries etc.) treats addresses greater than 32,767 as negative numbers, will that affect increments or comparisons? Although I can’t see any reason why they should process it at all; so far as the binding is concerned this is just two bytes to be placed on the wire.

And of course what I said before about the suspect area 28,709 being near this boundary is rubbish, doh.

Reading the same block of registers as uint16, uint32, float32 should be very enlightening.

Do you mean to read the same floating point register (both registers that comprise it) as uint 16, or to read a different 16 bit register on the PLC? Just want to make sure I understand correctly and I will test when I get home. I tried reading another modbus device I had here with registers roughly as high and I had the same behavior.

The randomness in the errors confuses me too, if it were a simple math or reading error somewhere I would think that the error would be the same every read. But it indeed changes every poll while all other modbus softwares I use read the same value every time.

I can also give diagslave a try, but the documentation is sparse. Can I set a value and register in it to read from? I’m not sure how to test this bug unless I know ahead of time exactly what the floating point value should be, and setting it to a high register