Standard Modbus commands / mixing Modbus slave types?

Hello

(I use Modbus Binding 1.10.0 Snapshot with OH2 2.1.0 Snapshot)

I’m working with BARIX R6 Modbus realy units. These devices support the following Modbus commands:

03 (0x03) read (holding) register
05 (0x05) write single coil
06 (0x06) write single register
16 (0x10) write multiple registers

In my modbus.cfg I define them as type=holding

serial.R6.connection=COM3:19200:8:even:1:rtu
serial.R6.id=1
serial.R6.start=0
serial.R6.length=1
serial.R6.type=holding
serial.R6.valuetype=bit

According to the openHAB2 Modbus documentation, the holding type reads with command 3 (read holding register) and writes with command 6 (Write single coil)

But I would like to use command 5 (write single coil) and this writing function is only used by Modbus slave type=coil.
If I change my my modbus.cfg to type=coil, the Modbus Addon tries to read with command 1 and this is not supported by my the BARIX devices! My log is flooded with errors…

Is there a way to mix types? type=holding to read from the device and type = coil to write? Or is there another way I can’t see at the moment?

TIA
Matthias

Yep. You can separately define read and write paths for an Item. You should separately define (virtual) slaves for each register type you want to use.

Hi again

That sounds promising! But as I’m a complete beginner, I have no clue how to implement this :confused:

Could you quickly give me a short example? I found some odler posts talking about virtual slaves, but this doesn’t make sense to me.

TIA Matthias

Define a bit which is read/write. (Because holding types are read/write by definition) You may or may not use both capabilities.

...
serial.R6.id=1
serial.R6.start=0
serial.R6.length=1
serial.R6.type=holding
serial.R6.valuetype=bit

Define a different, more usual, kind of bit, which is read/write (Because coil types are read/write by definition) You may or may not use both capabilities.

...
serial.R7.id=1
serial.R7.start=99
serial.R7.length=1
serial.R7.type=coil

(edit - removed valuetype, not needed for coil which is by definition bit)

Note that R6 and R7 both map onto the same physical device, at id 1.
Some folk call them virtual slaves, because they do not correspond to a unique hardware device, but share it instead.

If you have binding 1.10, you can set the read and write pathways separately for a given Item. Or leave either out, creating a read-only or write-only Modbus association.

Switch SomeItem "My thingy [%s]" <someicon> {modbus="<[R6:0] , >[R7:0]"}

Polls device holding register 0 bit 0 for status. If you send a command to the Item, it gets passed out to device coil 99. Whether that command gets reflected in the holding register (and so polled eventually) is up to the device designer.

Why people make such cranky devices is beyond me, when Modbus has a simple read-write bit-oriented access method purely in “coil”.

If you have synchronizing problems with this split effect, you might have to manage poll and write through separate Items, and link them with rules.

Thank you very much. I’m on the right track now :slight_smile: I’ll let you know when I have the test-system up an running.
Matthias

Hello rossko57

I’m about to give up …

I transfered my running OH2 installation from Windows to a new Raspberry 3 (openHABian V.1.3) and updated to the newest stable version of OH2. All the FS20 and Homematic components are working faultless.

For the Modbus devices, I tried your solution with the “virtual slaves” and i did not work. The log was flooded with errors. I tried different settings in the modbus.cfg file. But without success.

But now I have a fundamental problem: I assume that the modbus.cfg is parsed every time it is edited and saved? is this correct? (I’m using Eclispe SmartHomeDesigner)

For test purposes I deleted all modbus slaves in my modbus.cfg (an empty file!) saved it to the Services directory but the Error Log is still flooded with errors from deviced who don’t exist! I even restarted the system and after startup there are still the same errors. Is there a “hidden” place or a “shadow” copy of modbus.cfg? Cache?

I even uninstalled the modbus binding, deleted the modbus.cfg file and reinstalled modbus … still polling some old devices …:rage:

Actually I saved a total nonsense config (copy & paste some text from a text document) and my OH2 still tries to poll the same old devices … I’m absolutely lost. OH2 is such a brilliant system but very, very, very nerve-racking for a beginner like me :cry:

Any ideas?

TIA Matthias

[ERROR] [.binding.modbus.internal.ModbusSlave] - ModbusSlave (R7): Error getting modbus data for request net.wimpi.modbus.msg.ReadMultipleRegistersRequest@13e6195. Error: I/O exception - failed to read. Endpoint ModbusSerialSlaveEndpoint@e00bc8[portName=/dev/ttyACM0]. Connection: SerialConnection@14f69c4[portName=/dev/ttyACM0,port=/dev/ttyACM0]
[ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 03 00 63 00 01 74 14
[ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: CRC Error in received frame: 0 bytes: 
[ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadMultipleRegistersRequest@1be68d5 (unit id 1 & transaction 443). Serial parameters: SerialParameters@1ba3fbb[portName=/dev/ttyACM0,baudRate=19200,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=even,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
[ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 03 00 63 00 01 74 14
[ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: CRC Error in received frame: 0 bytes: 
[ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 2/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadMultipleRegistersRequest@1be68d5 (unit id 1 & transaction 444). Serial parameters: SerialParameters@1ba3fbb[portName=/dev/ttyACM0,baudRate=19200,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=even,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
[ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 01 03 00 63 00 01 74 14
[ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: CRC Error in received frame: 0 bytes: 
[ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 3/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadMultipleRegistersRequest@1be68d5 (unit id 1 & transaction 445). Serial parameters: SerialParameters@1ba3fbb[portName=/dev/ttyACM0,baudRate=19200,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=even,encoding=rtu,echo=false,receiveTimeoutMillis=1500]
[ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute reached max tries 3, throwing last error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadMultipleRegistersRequest@1be68d5 (unit id 1 & transaction 445). Serial parameters: SerialParameters@1ba3fbb[portName=/dev/ttyACM0,baudRate=19200,flowControlIn=none,flowControlOut=none,databits=8,stopbits=1,parity=even,encoding=rtu,echo=false,receiveTimeoutMillis=1500]

I do not believe that is true for OH2. (It never was for OH1, you had to restart OH1)

OH2 does keep a “secret cache” which trips lots of people up, so as you might expect it has cropped up here too before

Maybe this kind of thing doesn’t happen with native OH2 bindings.

Indeed this is the case. Original openhab2 bug reported here https://github.com/openhab/openhab-distro/issues/396

No much progress on the issue it seems.

Openhab2 version of modbus binding (being developed slowly by me) should not suffer from this issue as far as I know.

Sami

Good evening. Thanks for your answers.

I read through all the posts and linked sites. But my only questions still remains: is there a solution for this problem? A workaround? I’m thinking about a fresh openHABian installation.
My modbus.config makes my OH2 system completely unusable. Very, very frustrating for a beginner like me. I was so excited! And now disenchantment

Matthias

The workaround was given here

Thanks again! This time it seems to work. But I already have more questions. I’ll post them in a new topic.
Matthias

Hi Rossko57

I have to resume this topic, because my question is still related to my original problem.

As mentioned above, I have to read data from my BARIX R6 relay devices with command 3 (Read holding register) and write to the coresponding register with command 5 (Write Single Coil). I use the type holding and coil for the same device (virtual device). This constellation works as you proposed- BUT: Is there a way to prevent OH2 from polling my device with function 1 (Read coil status)? As the R6 doesn’t understand this command, the log file is flooded with error messages. Sure, I could just ignore them but that’s not a pretty solution.

TIA Matthias

I don’t believe there is a way, at present.
You can define an Item with a write-only binding.
But to do that, you have to define a slave in the binding .cfg file for the coil(s) in question.
Everything defined in the .cfg file gets polled (read) whether or not it is bound to an Item.
There’s only one common polling service between all theslaves, that is a feature of 1.x version binding that won’t be changing now.

There has been talk of radical change in this area for a native OH2 binding, but don’t hold your breath for that.

Meantime, you should also be aware that the failed read polls will also impact performance. The binding will be entering error recovery if there is a non-response from the Barix thingy, which will invoke a timeout and N retries, each with their own timeout. While that is happening, nothing else will on your Modbus.
So in your case you really want to configure a short timeout and minimise retries.

It might be worth encouraging the makers of the Barix to fully support Modbus coil functions, instead of just half?

Meantime I have added a note to the Modbus-2 work in progress record

Thanks again for your detailed answer. I was afraid I would get this answer. I have 28 Barix R6 devices connected and running and I can’t afford to replace all of them. I have a complex BARIX home-automation system running for over 8 years (non stop!) and would like to replace only the “logic” with OH2. But I guess I have to give up this idea …

So in your case you really want to configure a short timeout and minimise retries.

Is there a way to do this with a serial Modbus connection?

The manual says:

port[:baud[:dataBits[:parity[:stopBits[:encoding[:interTransactionDelayMillis[:receiveTimeoutMillis[:flowControlIn[:flowControlOut]]]]]]]]

These parameters are only available for TCP devices :roll_eyes:

Erm, those are the params for serial (there is no retry control, only the timeout for serial). If the Barix rejects (with a Modbus fail code) rather than simply ignoring coil reads, you need not worry about this - the error gets handled promptly.

Go beat Barix up about Modbus conformance :slight_smile:

EDIT from a quick look at Barix spec, you can alternatively write to coils via bits in a holding register. Now, the OH binding does not support bitwise writing to a holding register - because Modbus itself does not allow that at all. You have to write the whole register across Modbus.

But you could in theory construct an OH Item that holds an image of the whole register, and use rules to update that whole-register Item with bits corresponding to your induvidual Switch Items. When that Item gets changed, you can issue a command to get the binding to write it out to the Barix.
Doing that complication would avoid having to configure coils at all, so removing the source of read errors.

All I see in the log is the exception response code 81 (always 3 attempts).

Sent: 01 01 00 00 00 05 fc 09 
Response: 01 81 

The BARIX R6 device supports the following commands:

03 (0x03)read (holding) register
05 (0x05)write single coil
06 (0x06)write single register
16 (0x10)write multiple registers

I already tried bitwise writing to a holding register :slight_smile: and understandably failed miserable …

So you would suggest using command 03 and 06? In theory this seems the only solution/workaroud. But as a complete newbie I’m more than far away from getting the neccessary code (rules) together. I’m still used to the BARIX control language (BCL).
Do we talk about working with bitmasks? Where could I find some code snippets - to bring me on the right track?

It would be a fiddly faff to implement all the dummy items and rules, particularly as you have many devices. Very educational to get it working, but probably frustrating for a starter.

As Modbus-2 will natively do what you need, I would wait for that to be released.

The only real sideffect with the way you do it now is the error logging - once you are happy things are working as you want, you could I believe divert modbus binding logs to their own file where you don’t have to look at them. I don’t know exactly how, but there are examples in this forum. (keyword logger)