Modbus RTU Drexel & Weiss <> openHAB

You mean converting the x1000 integer to decimal degrees?
I think you could do that now with a transform in the Modbus binding.

I’ve no experience of that, an alternative approach is to create a proxy item (unbound to any device) and have a rule triggered on a change to the Modbus Item that calculates as needed and updates the proxy Item.

1 Like

By the way, you can now use standard development version of the modbus binding, it includes the transformation support.

The thread linked by @rossko57 contains example of scaling.

Best,
Sami

i can’t get 1.10 to work, so i’ll probably stick with proxy items!
cheers

@narf27, could you please elaborate what kind of issues you were facing with 1.10.0 version?

Best,
Sami

@ssalonen putting the .jar file in the addons folder didn’t do the trick i already gave up.
so it’s problably not a problem of the binding but my fault!

@rossko57 today i tried to implement a r/w register, but it won’t work:

modbus.cfg:

writemultipleregisters=true

serial.slave2.connection=/dev/ttyAMA0:9600:8:none:1:rtu
serial.slave2.id=1
serial.slave2.type=holding
serial.slave2.start=200
serial.slave2.length=2
serial.slave2.valuetype=int32

item:

Number Raum_MB "Innentemperatur IST" (Modbus) {modbus="slave2:0"}

it’s on page 102 of the parameter pdf posted above…

here’s what the openhab log says:

2017-04-17 20:05:11.483 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 ca 00 02 51 f5
2017-04-17 20:05:11.484 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-04-17 20:05:11.486 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@a43d6c (unit id 1 & transaction 849). Serial parameters: SerialParameters@4e760e[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]

Btw, you probably had similar issues than @nickma82 on this thread : Modbus support for transformations, roller shutter items, read-only items, write-only items, and others
. The solution is given there.

Regarding the error you receive, did it work out eventually after retries? The log you output is the first try out of three.

Best
Sami

My German is not good enough with the product manuals to tell if you should now be using modbus id=1 when it worked with id=2 before.

On page 5 of the register guide, 202 is shown as read-only.

No matter, the failing Modbus function code is 04, read input register, for address CA (202). The error is not a write error.
The config for “slave2” you show us should use FC 03 for read holding.
This error command must come from somewhere else. Perhaps a cached config from before your last edit.

Maybe this slave doesn’t like being hit with two successive polls too quickly. There is an inter-transaction gap parameter to play with for that.


However: my German is not good enough to understand the documentation - you will need to understand it yourself if you want success - But from what I can see on pages 10 & 11
http://gasserenergy.ch/wp-content/uploads/2015/09/900.6660_01_TI_Modbus_RTU_DE.pdf
this devices supports only FC04 (read input) and FC10 (write multiple holding).
Oddly it does not seem to support reading of holding types, but lets see if FC03 errors arise yet. Perhaps it will read in reality.

The document says, that it makes all Modbus devices accessible from within a single (main if you want) Modbus-Connection (in that case the RS232, page 8).
That means, if id==2 worked, use that.

IMHO that’s correct.

I would suggest: try to bring the connection up with a small modbus software (e.g. pythons minimalmodbus), but a fully fledged home automation integration. This makes debugging much easier and gives you the ability to expulse some fault cases (e.g. the timing constraint you mentioned).
For an example see: nilan_communication_bringup/src/nilan.py at master · nickma82/nilan_communication_bringup · GitHub

Best

argh, i just checked the log with my initial (working) setup for 202 register…
first of all: it didn’t work with id2, but with id1, so that should not be the problem!

events.log

2017-04-18 07:40:46.624 [ItemStateChangedEvent     ] - Aussen_MB changed from 12503 to 12648
2017-04-18 07:40:46.663 [ItemStateChangedEvent     ] - Aussen_MB_kr changed from 12.50300000 to 12.64800000
2017-04-18 07:42:28.396 [ItemStateChangedEvent     ] - Aussen_MB changed from 12648 to 11645
2017-04-18 07:42:28.421 [ItemStateChangedEvent     ] - Aussen_MB_kr changed from 12.64800000 to 11.64500000
2017-04-18 07:44:10.142 [ItemStateChangedEvent     ] - Aussen_MB changed from 11645 to 10802
2017-04-18 07:44:10.167 [ItemStateChangedEvent     ] - Aussen_MB_kr changed from 11.64500000 to 10.80200000
2017-04-18 07:45:51.904 [ItemStateChangedEvent     ] - Aussen_MB changed from 10802 to 10251
2017-04-18 07:45:51.930 [ItemStateChangedEvent     ] - Aussen_MB_kr changed from 10.80200000 to 10.25100000
2017-04-18 07:47:33.662 [ItemStateChangedEvent     ] - Aussen_MB changed from 10251 to 10112
2017-04-18 07:47:33.688 [ItemStateChangedEvent     ] - Aussen_MB_kr changed from 10.25100000 to 10.11200000

BUT!!! openhab.log:

2017-04-18 07:40:46.503 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 ca 00 02 51 f5
2017-04-18 07:40:46.504 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-04-18 07:40:46.506 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@15fac32 (unit id 1 & transaction 654). Serial parameters: SerialParameters@d1b2c[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
2017-04-18 07:42:28.253 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 ca 00 02 51 f5
2017-04-18 07:42:28.254 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-04-18 07:42:28.256 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@e7c6a3 (unit id 1 & transaction 656). Serial parameters: SerialParameters@d1b2c[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
2017-04-18 07:44:10.013 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 ca 00 02 51 f5
2017-04-18 07:44:10.014 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-04-18 07:44:10.016 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@1fb12df (unit id 1 & transaction 658). Serial parameters: SerialParameters@d1b2c[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
2017-04-18 07:45:51.773 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 ca 00 02 51 f5
2017-04-18 07:45:51.774 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-04-18 07:45:51.776 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@1c5c295 (unit id 1 & transaction 660). Serial parameters: SerialParameters@d1b2c[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
2017-04-18 07:47:33.523 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 ca 00 02 51 f5
2017-04-18 07:47:33.525 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-04-18 07:47:33.527 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@1dbd3a3 (unit id 1 & transaction 662). Serial parameters: SerialParameters@d1b2c[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]

so i get the values but openhab still has errors in the log.

modbus.cfg:

serial.slave1.connection=/dev/ttyAMA0:9600:8:none:1:rtu
serial.slave1.id=1
serial.slave1.type=input
serial.slave1.start=202
serial.slave1.length=2
serial.slave1.valuetype=int32

item(s) where 2nd item is my proxy item:

Group Modbus
Number Aussen_MB "Außentemperatur" (Modbus) {modbus="slave1:0"}
Number Aussen_MB_kr "Außentermperatur korrigiert" (Modbus)

as you spoke of cache problems i tried a reboot but that didn’t help!

Okay

So this I don’t understand ?

[quote=“narf27, post:49, topic:22379”] …
[ERROR] … Last request: 01 04 00 ca 00 02 51 f5
[/quote]

This is a read (FC04) error for ID=1.

I think there is more to it than that

I am not yet an OH2 user, but what a sorry business this seems to be.

oh boy, i shouldn’t post on the internet before coffee…
id2 didn’t work, id1 did! (post updated!)
why do i get a read error for id1?
i get regular update on my item but in the same time the error pops up :confused:
i’ll take a look at the “chached config files” thread.

If you look at the time stamps, they pop up only every few minutes. So it isn’t broken, just a bit marginal somehow. You see only try 1/3 in error (default allows 3 retries). So try 2 seems to work each time. The error is recovered.

Sometimes Modbus slaves will not respond, or not respond quickly enough, if they are queried too often or while they are doing something else.

First I would look at your Modbus binding poll rate - how often do you need to read the data, several times per second or once a minute? (Bearing in mind you will no doubt want other data items later)

Next I would look at the inter-transaction gap in the binding config - should you enforce more time between queries.

The timeout (wait-for-response) is pretty generous by default, I wouldn’t mess with that. If it is too long it will actually slow everything down when errors occur.

It might be down to genuine errors on the data line - electrical noise. On RS485 serial lines best performance is obtained by using twisted pair cables and carefully terminating and biasing the line, a subject of itself and outside the scope of Openhab. But this often isn’t necessary with short cables. Line glitches are more likely when you dealing with mains powered motors and so on (aircon units!)
EDIT - but this is RS232 isn’t it? Still susceptible to glitches, but there is no termination to check.

There might simply be nothing you can do about it if the slave decides to drop the odd response. So long as it recovers this is not a disaster.

Huh! Modbus Poll is 1,67 minutes. (lowered from 5 mins for testing purpose)
The errors appear just a few milliseconds just before the item change is registern in events.log.
so you’re probably right and the first try fails but the second succeeds.
i’ll take a look at the inter transaction gap - not sure what it means =)

yesterday i tried the 200 register with a read slave.
modbus.cfg

serial.slave1.connection=/dev/ttyAMA0:9600:8:none:1:rtu
serial.slave1.id=1
serial.slave1.type=input
serial.slave1.start=200
serial.slave1.length=2
serial.slave1.valuetype=int32

item:

Number Aussen_MB "Außentemperatur raw" (Modbus) {modbus="slave1:0"}

apart from the error mentioned above i get the right value for room temperature.

BUT!!! when i add a second item:

Number Aussen2_MB "Außentemperatur raw 2" (Modbus) {modbus="slave1:2"}

i still get the value for 200, BUT! i don’t get the value for (200+2 =) 202 and an error like this:

2017-04-21 07:37:10.936 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 c8 00 02 f0 35
2017-04-21 07:37:10.938 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: Error reading response (EOF)
2017-04-21 07:37:10.940 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@17590e (unit id 1 & transaction 200). Serial parameters: SerialParameters@45ecae[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
2017-04-21 07:37:11.054 [ERROR] [.binding.modbus.internal.ModbusSlave] - ModbusSlave (slave1) error getting response from slave
java.lang.ArrayIndexOutOfBoundsException: 4
        at org.openhab.binding.modbus.internal.ModbusBinding.extractStateFromRegisters(ModbusBinding.java:319)[201:org.openhab.binding.modbus:1.9.0]
        at org.openhab.binding.modbus.internal.ModbusBinding.internalUpdateItem(ModbusBinding.java:213)[201:org.openhab.binding.modbus:1.9.0]
        at org.openhab.binding.modbus.internal.ModbusSlave.updateItem(ModbusSlave.java:463)[201:org.openhab.binding.modbus:1.9.0]
        at org.openhab.binding.modbus.internal.ModbusSlave.update(ModbusSlave.java:441)[201:org.openhab.binding.modbus:1.9.0]
        at org.openhab.binding.modbus.internal.ModbusBinding.execute(ModbusBinding.java:413)[201:org.openhab.binding.modbus:1.9.0]
        at org.openhab.core.binding.AbstractActiveBinding$BindingActiveService.execute(AbstractActiveBinding.java:157)[182:org.openhab.core.compat1x:2.0.0]
        at org.openhab.core.service.AbstractActiveService$RefreshThread.run(AbstractActiveService.java:173)[182:org.openhab.core.compat1x:2.0.0]

(first 3 lines are the usual ones, the rest is new)

have i misunderstood item configuration?

int32 datatypes use 2 standard modbus 16-bit registers. A single item is thus length 2.

A hint for that comes in the devices manual, the next “32-bit register” after 200 is 202. The binding config above fetches 200 and 201 and stitches them together as a single 32-bit data element.

To fetch two consecutive int32 types you would need length 4

The :2 in the Item definition refers to the third data element from the binding, as we count from zero here.

It gets a bit confusing because where in the binding config we count in standard size modbus registers, in the the Item definition we count in processed data elements passed from the binding.

This is the price of passing 32-bit data over a 16-bit standard, it works but needs care.

erm, well… ok (i guess?)

so to get 200 & 202 i’d have to adjuts length to “4” and second item should be

Number Aussen2_MB "Außentemperatur raw 2" (Modbus) {modbus="slave1:1"}

?

what if i want to read f.e. register 216 (Temperatur: Sole) as third item?
lenght = 2 + 2 + 2 = 6?
and item “:8”?

Yup.

The binding can only read consecutive blocks of registers, because that is all that Modbus standard allows.
The binding can only treat such blocks as the same datatype throughout (int32 in this case), because it would get really confusing if we mixed datatypes within a block

But there is nothing in OpenHAB to prevent you reading a block and not using all the registers in it.

So to poll 200, 202 and 216 you might have

serial.block1.start=200
serial.block1.length=18
serial.block1.valuetype=int32

This will read all Modbus 16-bit registers 200 to 217, and the binding will process them into 9 32-bit data elements
You would pick the three you want like

Number Aussen1_MB "data 200 raw" {modbus="block1:0"}
Number Aussen2_MB "data 202 raw" {modbus="block1:1"}
Number Aussen3_MB "data 216 raw" {modbus="block1:8"}

This would use the first, second, and ninth data pairs in OpenHAB and simply not use the others in-between - though they do get read over Modbus.


Unfortunately, there is a complication. Modbus slaves are NOT obliged to allow reads from registers that their designers have not defined. They might respond with null data, or they might reject the read altogether. Rejection might take the form of an error code response, or it might simply ignore it and produce a timeout.
So the technique above may or may not work with any given device, if the registers in-between are not defined by the designer.
It’s a case of try it and see.

If it doesn’t work, then you have to split the blocks. There is nothing to stop you defining more than one ‘virtual’ slave in the binding config for the same physical device.
Indeed, you have to do that where different datatypes are involved, such as input registers and holding registers, or 16 and 32 bit numbers.

So for your example we could define two slaves

serial.block1.connection=/dev/ttyAMA0:9600:8:none:1:rtu
serial.block1.id=1
serial.block1.type=input
serial.block1.start=200
serial.block1.length=4
serial.block1.valuetype=int32

serial.block2.connection=/dev/ttyAMA0:9600:8:none:1:rtu
serial.block2.id=1
serial.block2.type=input
serial.block2.start=216
serial.block2.length=2
serial.block2.valuetype=int32

This would read only the registers wanted, at the cost of polling the device twice instead of once.
Items would then be

Number Aussen1_MB "data 200 raw" {modbus="block1:0"}
Number Aussen2_MB "data 202 raw" {modbus="block1:1"}
Number Aussen3_MB "data 216 raw" {modbus="block2:0"}

for the first two pairs in block1 and the first pair in block2

1 Like

Hi again… since i was busy the last weeks i couldn’t make much progress.
i tried your suggestions:

modbus.cfg:

serial.slave1.connection=/dev/ttyAMA0:9600:8:none:1:rtu
serial.slave1.id=1
serial.slave1.type=input
serial.slave1.start=200
serial.slave1.length=4
serial.slave1.valuetype=int32

items:

Group Modbus
Number Raum_MB "Raumtemperatur raw" (Modbus) {modbus="slave1:0"}
Number Raum_MB_kr "Raumtermperatur" (Modbus)
Number Aussen_MB "Aussentemperatur raw" (Modbus) {modbus="slave1:1"}

i get no values but errors in openhab.log

2017-05-09 19:53:46.916 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 c8 00 04 70 37
2017-05-09 19:53:46.917 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: CRC Error in received frame: 0 bytes:
2017-05-09 19:53:46.919 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@10da78e (unit id 1 & transaction 1). Serial parameters: SerialParameters@d8e661[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
2017-05-09 19:53:47.067 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 c8 00 04 70 37
2017-05-09 19:53:47.072 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: CRC Error in received frame: 0 bytes:
2017-05-09 19:53:47.073 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 2/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@10da78e (unit id 1 & transaction 1). Serial parameters: SerialParameters@d8e661[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
2017-05-09 19:53:47.176 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 04 00 c8 00 04 70 37
2017-05-09 19:53:47.177 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: CRC Error in received frame: 0 bytes:
2017-05-09 19:53:47.178 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 3/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@10da78e (unit id 1 & transaction 1). Serial parameters: SerialParameters@d8e661[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
2017-05-09 19:53:47.178 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute reached max tries 3, throwing last error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadInputRegistersRequest@10da78e. Serial parameters: SerialParameters@d8e661[portName=/dev/ttyAMA0,baudRate=9600,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=none,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
2017-05-09 19:53:47.179 [ERROR] [.binding.modbus.internal.ModbusSlave] - ModbusSlave (slave1): Error getting modbus data for request net.wimpi.modbus.msg.ReadInputRegistersRequest@10da78e. Error: I/O exception - failed to read. Endpoint ModbusSerialSlaveEndpoint@1c6568[portName=/dev/ttyAMA0]. Connection: SerialConnection@319350[portName=/dev/ttyAMA0,port=/dev/ttyAMA0]

with 2 different slaves it works:

serial.slave1.connection=/dev/ttyAMA0:9600:8:none:1:rtu
serial.slave1.id=1
serial.slave1.type=input
serial.slave1.start=200
serial.slave1.length=2
serial.slave1.valuetype=int32

serial.slave2.connection=/dev/ttyAMA0:9600:8:none:1:rtu
serial.slave2.id=1
serial.slave2.type=input
serial.slave2.start=202
serial.slave2.length=2
serial.slave2.valuetype=int32

items:

Group Modbus
Number Raum_MB "Raumtemperatur raw" (Modbus) {modbus="slave1:0"}
Number Raum_MB_kr "Raumtermperatur" (Modbus)
Number Aussen_MB "Aussentemperatur raw" (Modbus) {modbus="slave2:0"}

This is for reading items.

I note that the “working” and “not working” slave1 are completely identical.

yeah… well… after changing back to “working” setup i forgot to adjust length to “2”. (correct now in post above!)
just took my 2 hours why i had no success in reading slave1. argh!!! :confounded:

i tried to setup a r/w item and could read 5016, but i wasn’t able to write. i’ll post conf & log tonight!
cheers