Modbus openHAB2 binding available for alpha testing

Hi @ssalonen,

I’m having an issue with the binding while using it for a serial connection
It looks like the binding isn’t able to open the serial port because I see this message in the log files:

Error getting a new connection for endpoint null. Error was: null

I’ve enable trace logging for the binding (and transport).
You can find the log here:
https://pastebin.com/wJ9h3wNB

Let me know if you need more information!

Thanks

Greetings,
Frederic

Thanks @FredericMa !
Let’s try to debug this a bit further

  • Can you double check you have the latest version of the modbus binding and transport (should be from Aug 2)
  • If you have things text file configuration, can you paste it here
  • are all the things online? If not, can check the status messages (in paper ui)

Best

Hi @ssalonen,

  • Indeed, I’m using the latest version. Version number is 2.2.0.201708021259.
  • I don’t have a text configuration. I’ve added the things via paperUI. I do have the file where all things are stored by openHAB and the file that contains the linked channels to the items. You can find the things here: Modbus things file - Pastebin.com
    The content of the linked channels is this (i only linked one item for test):
{
  "DeviceVersion -\u003e modbus:read:705216e4:number": {
    "class": "org.eclipse.smarthome.core.thing.link.ItemChannelLink",
    "value": {
      "channelUID": {
        "segments": [
          "modbus",
          "read",
          "705216e4",
          "number"
        ]
      },
      "itemName": "DeviceVersion"
    }
  }
}
  • All things are online except the read-write and read definition.
    The error message for the read-write definition is:

OFFLINE - COMMUNICATION_ERROR Read write thing handler got read error: net.wimpi.modbus.ModbusIOException I/O exception - failed to read. See logs above for more information

The error message for the read definition is:

OFFLINE - COMMUNICATION_ERROR Error with read: net.wimpi.modbus.ModbusIOException: I/O exception - failed to read

If you want I can also make a short text based config.

Thanks!

Greetings,
Frederic

Hi

What an clear response! This helped a little bit.

Looking at the code I think I found the reason for the “null endpoint” indicated on the first log. However I think it might be just a temporary issue when the system is initializing… Do not have proper code access currently but will fix it end of this month or beginning of Sep.

If possible can you let it run for a while and then capture the most recent logs (perhaps you did this already?)

The status message indicates that there are read errors. Do you find anything in the logs with ModbusIOException? E.G. BG using “log:tail |grep ModbusIOException”

Best

Hi @ssalonen,

I’ve uploaded a new log file here: https://pastebin.com/FcExdNer
Remark: do not that I’m using a different port now. Preciously I was using the UART but now I’m using a USB to RS485 converter and the issue remains so it doesn’t look like it is a hardware issue.
As you can see, sometimes the connection does succeed but after a while it gets disconnected again.
If i filter out the ModbusIOException from one log file is get this result:

Line 20780: 2017-08-23 10:08:56.989 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Error when executing read request (ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@b0f51c[slaveId=11,functionCode=READ_MULTIPLE_REGISTERS,start=4060,length=1]): net.wimpi.modbus.ModbusIOException I/O failed to write
Line 20819: 2017-08-23 10:08:57.404 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Error when executing read request (ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@1828679[slaveId=11,functionCode=READ_MULTIPLE_REGISTERS,start=4036,length=9]): net.wimpi.modbus.ModbusIOException I/O exception - failed to read
Line 20859: 2017-08-23 10:08:58.363 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Error when executing read request (ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@17eb6e2[slaveId=11,functionCode=READ_MULTIPLE_REGISTERS,start=4015,length=5]): net.wimpi.modbus.ModbusIOException I/O exception - failed to read
Line 21537: 2017-08-23 10:08:59.380 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Error when executing read request (ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@bb0bd1[slaveId=11,functionCode=READ_MULTIPLE_REGISTERS,start=4046,length=5]): net.wimpi.modbus.ModbusIOException I/O exception - failed to read
Line 22004: 2017-08-23 10:09:04.989 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Error when executing read request (ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@1788667[slaveId=11,functionCode=READ_MULTIPLE_REGISTERS,start=4060,length=1]): net.wimpi.modbus.ModbusIOException I/O failed to write
Line 22081: 2017-08-23 10:09:05.349 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Error when executing read request (ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@14b8df8[slaveId=11,functionCode=READ_MULTIPLE_REGISTERS,start=4021,length=5]): net.wimpi.modbus.ModbusIOException I/O exception - failed to read
Line 22199: 2017-08-23 10:09:06.422 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Error when executing read request (ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@1008248[slaveId=11,functionCode=READ_MULTIPLE_REGISTERS,start=4027,length=8]): net.wimpi.modbus.ModbusIOException I/O exception - failed to read

So indeed, I do see these errors in the log files.

Let me know if i can help you with anything else on this.

Greetings,
Frederic

I’m probably missing something simple, but I cannot build the configuration to test this building.

Here is the configuration I used with v1 binding:

tcp.slave100.connection=192.168.5.239:502
tcp.slave100.id=2
tcp.slave100.start=0
tcp.slave100.length=4
tcp.slave100.type=coil

and

Switch ModbusTest1 "ADAM DO port 1" {modbus="slave100:0"}
Switch ModbusTest2 "ADAM DO port 2" {modbus="slave100:1"}

Can someone share the sample configuration, similar to serial example provided earlier?
I was able to create some components from the Paper UI but I found no option to put the “offset” like :0 and :1 in the item configuration and the thing state was Uninitialized.

Hi @AndrewZ! Thanks for taking time to test this new version…

Here’s a configuration that should get you started. Should work, tested locally using diagslave

modbus.things

Bridge modbus:tcp:endpointTCP [ host="192.168.5.239", port=502, id=2 ] {
    Bridge poller coils [ start=0, length=4, refresh=500, type="coil" ] {
        Bridge readwrite DO1 { 
            Thing read readTCP [ start=0, valueType="bit" ]
            Thing write writeTCP [ start=0, valueType="bit", type="coil" ]
        }

        Bridge readwrite DO2 { 
            Thing read readTCP [ start=1, valueType="bit" ]
            Thing write writeTCP [ start=1, valueType="bit", type="coil" ]
        }
    }
}

modbus.items:

Switch ModbusTest1            "ADAM DO port 1 [%d]"    { channel="modbus:readwrite:endpointTCP:coils:DO1:number" }
Switch ModbusTest2            "ADAM DO port 2 [%d]"    { channel="modbus:readwrite:endpointTCP:coils:DO2:number" }

modbus.sitemap:

sitemap modbus label="Modbus"
{
    Frame {
        Switch item=ModbusTest1
        Switch item=ModbusTest2
    }
}
1 Like

Hi @ssalonen, thanks a lot for the detailed example.
It works, but I have 0 or 1 in the UI next to the switch - how I can get rid of this?

And I have to admit that this new configuration looks way more complicated in comparison to the old one. Anyway, will try to add more devices. Thanks a lot for all your efforts!

The item label includes [%d]. It seems that you need to have empty brackets to suppress the number

Switch ModbusTest1            "ADAM DO port 1 []"    { channel="modbus:readwrite:endpointTCP:coils:DO1:number" }
Switch ModbusTest2            "ADAM DO port 2 []"    { channel="modbus:readwrite:endpointTCP:coils:DO2:number" }

Regarding the config complexity, posting a follow up on that one here…

EDIT: updated the brackets

That was my obvious choice, but gave me Err instead of 0 or 1
And here is the log:

Exception while formatting value 'OFF' of item ModbusTest2 with format '%.0f'

Seems like openHAB2 handles labels differently than openHAB1, you can use [] to make it work (updated the above example).

That works, thank you.
One more question - I see some errors in the log and believe that could be cured by adjusting timers. Any recommendations? With syntax example please :wink:

[ERROR] [wimpi.modbus.io.ModbusTCPTransaction] - execute try 1/3 error: I/O exception - failed to read.. Request: net.wimpi.modbus.msg.ReadCoilsRequest@3b66a3b9 (unit id 2 & transaction 5830). Address: /192.168.5.239:502

Not sure, the underlying socket returns EOF – perhaps the physical slave is not able to respond as fast or something similar. You can try to lower the poll rate.

All right @FredericMa, investigated the logs a bit.

The “null endpoint” seems to be the most critical – I now applied a fix for that. Fix should be now out from the usual location.

Could you please try with that version and see if that fixes the issues for you.


There were also some read errors, some comments below

Transmit Echo not received

[ERROR] [impi.modbus.io.ModbusSerialTransport] - Transmit Echo not received

I think this means that the modbus library tries to read the “echo” message, since you have specified echo parameter in serial connection as true. From the logs you can see that echo is not there at all – perhaps you want to disable the echo?

exact log messages:

017-08-23 10:08:52.145 [TRACE] [rt.modbus.internal.ModbusManagerImpl] - borrowing connection (got Optional[SerialConnection@1ad9f9e[portName=/dev/ttyUSB0,port=/dev/ttyUSB0]]) for endpoint ModbusSerialSlaveEndpoint@112b8a1[portName=/dev/ttyUSB0] took 701 ms
2017-08-23 10:08:52.147 [TRACE] [rt.modbus.internal.ModbusManagerImpl] - Executing task PollTaskImpl@1d12d97[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@b0f51c[slaveId=11,functionCode=READ_MULTIPLE_REGISTERS,start=4060,length=1],endpoint=ModbusSerialSlaveEndpoint@112b8a1[portName=/dev/ttyUSB0],callback=org.openhab.binding.modbus.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@96fdca40] (oneOff=false)! Connection received in 704 ms
2017-08-23 10:08:52.263 [DEBUG] [t.wimpi.modbus.io.ModbusRTUTransport] - Sent: 0b 03 0f dc 00 01 46 4e 
2017-08-23 10:08:53.782 [DEBUG] [impi.modbus.io.ModbusSerialTransport] - Echo: 0b 83 04 60 f1 
2017-08-23 10:08:53.784 [ERROR] [impi.modbus.io.ModbusSerialTransport] - Transmit Echo not received
2017-08-23 10:08:53.789 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O failed to write. Request: net.wimpi.modbus.msg.ReadMultipleRegistersRequest@12ae47b (unit id 11 & transaction 1). Serial parameters: SerialParameters@190c70b[portName=/dev/ttyUSB0,baudRate=9600,flowControlIn=xon/xoff in,flowControlOut=xon/xoff out,databits=8,stopbits=1,parity=even,encoding=rtu,echo=true,receiveTimeoutMillis=1500]
2017-08-23 10:08:53.842 [DEBUG] [t.wimpi.modbus.io.ModbusRTUTransport] - Sent: 0b 03 0f dc 00 01 46 4e 
2017-08-23 10:08:55.382 [DEBUG] [impi.modbus.io.ModbusSerialTransport] - Echo: 0b 83 04 60 f1 
2017-08-23 10:08:55.384 [ERROR] [impi.modbus.io.ModbusSerialTransport] - Transmit Echo not received
...
snipping other retries
...
2017-08-23 10:08:56.987 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute reached max tries 3, throwing last error: I/O failed to write. Request: net.wimpi.modbus.msg.ReadMultipleRegistersRequest@12ae47b (unit id 11 & transaction 3). Serial parameters: SerialParameters@190c70b[portName=/dev/ttyUSB0,baudRate=9600,flowControlIn=xon/xoff in,flowControlOut=xon/xoff out,databits=8,stopbits=1,parity=even,encoding=rtu,echo=true,receiveTimeoutMillis=1500]

CRC Error in received frame

CRC error thust discarding the messages, might be related to “echo” issue above as well.


2017-08-23 10:08:57.170 [TRACE] [rt.modbus.internal.ModbusManagerImpl] - Executing task PollTaskImpl@c46f14[request=ModbusPollerThingHandlerImpl.ModbusPollerReadRequest@1828679[slaveId=11,functionCode=READ_MULTIPLE_REGISTERS,start=4036,length=9],endpoint=ModbusSerialSlaveEndpoint@112b8a1[portName=/dev/ttyUSB0],callback=org.openhab.binding.modbus.handler.ModbusPollerThingHandlerImpl$ReadCallbackDelegator@b573dd14] (oneOff=false)! Connection received in 5451 ms
2017-08-23 10:08:57.192 [DEBUG] [t.wimpi.modbus.io.ModbusRTUTransport] - Sent: 0b 03 0f c4 00 09 c7 8f 
2017-08-23 10:08:57.213 [DEBUG] [impi.modbus.io.ModbusSerialTransport] - Echo: 0b 03 12 00 01 00 00 00
2017-08-23 10:08:57.217 [TRACE] [t.wimpi.modbus.io.ModbusRTUTransport] - Managed to read at least one byte
2017-08-23 10:08:57.235 [DEBUG] [t.wimpi.modbus.io.ModbusRTUTransport] - Response: 00 00 
2017-08-23 10:08:57.238 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 0b 03 0f c4 00 09 c7 8f
2017-08-23 10:08:57.239 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: CRC Error in received frame: 0 bytes: 
2017-08-23 10:08:57.242 [ERROR] [pi.modbus.io.ModbusSerialTransaction] - execute try 1/3 error: I/O exception - failed to read. Request: net.wimpi.modbus.msg.ReadMultipleRegistersRequest@1623f3f (unit id 11 & transaction 4). Serial parameters: SerialParameters@190c70b[portName=/dev/ttyUSB0,baudRate=9600,flowControlIn=xon/xoff in,flowControlOut=xon/xoff out,databits=8,stopbits=1,parity=even,encoding=rtu,echo=true,receiveTimeoutMillis=1500]
2017-08-23 10:08:57.280 [DEBUG] [t.wimpi.modbus.io.ModbusRTUTransport] - Clear input: 00 00 00 00 00 00 01 00 01 00 00 65 b8
2017-08-23 10:08:57.302 [DEBUG] [t.wimpi.modbus.io.ModbusRTUTransport] - Sent: 0b 03 0f c4 00 09 c7 8f 
2017-08-23 10:08:57.309 [DEBUG] [impi.modbus.io.ModbusSerialTransport] - Echo: 0b 03 12 00 01 00 00 00
2017-08-23 10:08:57.312 [TRACE] [t.wimpi.modbus.io.ModbusRTUTransport] - Managed to read at least one byte
2017-08-23 10:08:57.313 [DEBUG] [t.wimpi.modbus.io.ModbusRTUTransport] - Response: 00 00 
2017-08-23 10:08:57.315 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - Last request: 0b 03 0f c4 00 09 c7 8f
2017-08-23 10:08:57.317 [ERROR] [t.wimpi.modbus.io.ModbusRTUTransport] - failed to read: CRC Error in received frame: 0 bytes: 
...
snipping other retries
...
2017-08-23 10:08:57.402 [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@1623f3f (unit id 11 & transaction 6). Serial parameters: SerialParameters@190c70b[portName=/dev/ttyUSB0,baudRate=9600,flowControlIn=xon/xoff in,flowControlOut=xon/xoff out,databits=8,stopbits=1,parity=even,encoding=rtu,echo=true,receiveTimeoutMillis=1500]
2017-08-23 10:08:57.404 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Error when executing read request

Thanks @rossko57, @AndrewZ and @mbs38 on comments regarding the configuration complexity.

Indeed that is a valid concern. As we are discussing a low level protocol with no “thing” discovery, I tend to agree with @rossko57 that ultimately user should be able to decide what kind of modbus requests the software is executing. Otherwise the binding developer has made the decision for the user, and in the worst case ending up with non-working config.

For example, we have seen so many “exotic” modbus devices (as @rossko57 said) in these forums, that any automatic “combination” of requests is error prone I think.

One of the other design criterias was not to reduce functionality compared to older binding (I think we have managed with this pretty well – although some limitations are there, as discussed in this thread). For example, with the openhab1 binding, one can configure Rollershutter “device” without any rules, ultimately represented by a single thing. Yes, there are additional “helper” things to make it happen but I think that’s a necessary compromise (see more discussion below).

If we would decide to leave the modbus binding with simple IO functionality (just supporting number items for example with no transformations), much of the binding complexity could be reduced. Naturally, the complexity would be introduced in the form of “proxy items” and rules.

For example of more complex example, rollershutter example from openhab1

modbus.things

Bridge modbus:tcp:endpointTCP [ host="127.0.0.1", port=502, id=2 ] {

    Bridge poller holding [ start=0, length=4, refresh=500, type="holding" ] {
        Bridge readwrite LivingRoomRollershutter { 
            // Roller shutter position is read from register 0
            Thing read readPosition [ start=0, valueType="int16" ]
            
            // UP(=1)/DOWN(=-1) commands are written to register 1
            Thing write writeUp [ start=1, trigger="UP", transform="1", valueType="int16", type="holding" ]
            Thing write writeDown [ start=1, trigger="DOWN", transform="-1", valueType="int16", type="holding" ]
            
            // MOVE(=1)/STOP(=0) commands are written to register 2
            Thing write writeMove [ start=2, trigger="MOVE", transform="1", valueType="int16", type="holding" ]
            Thing write writeStop [ start=2, trigger="STOP", transform="0", valueType="int16", type="holding" ]
        }

}

Here the item would be

Rollershutter RollershutterLivingRoomPosition "Roller shutter position [%.1f]" <temperature> {channel="modbus:readwrite:endpointTCP:holding:LivingRoomRollershutter:rollershutter"}

and sitemap same as in old version (see the link).

You can compare this to the openhab1 version (rows added for clarity) and see the analogy.

Rollershutter RollershutterItem "Roller shutter position [%.1f]" 
  <temperature> {modbus="<[slave1:0],
            >[slave1:1:trigger=UP,transformation=1],
            >[slave1:1:trigger=DOWN,transformation=-1],
            >[slave1:2:trigger=MOVE,transformation=1],
            >[slave1:2:trigger=STOP,transformation=0]"}

A bit unfortunately, we have had quite many cases requiring this kind of functionality (see the thread and linked threads).

We could support the “cryptical” item configuration pattern above and thus there would be no need for read and write things, just the readwrite. However, we then would lose the UI configuration possibilities and it’s easy to make typoes.

We could combine some things though: Say we would combine poller and endpoint things. Since we have different parameters for serial and tcp endpoints, we would have to introduce “tcp-poller” and “serial-poller”. In case of many “pollers” (e.g. user wants to poll coils and holding registers), one would have to carefully copy-paste the endpoint information (e.g. ip address and other relevant settings). The current design tries to be “orthogonal” and as such no information is repeated.

One thing that I would like to mention is that I do have a concern that we are inventing something here that is quite different from the other bindings. As said in this thread, I found no other as low level protocols supports as openHAB2 addons yet to take example from. For example, there has been quite long discussions with KNX and MQTT bindings – there are no easy/natural thing hierachy there.

Nevertheless, if the outcome feels like super-complex and hard to understand we have work to do. I hope that with clear examples and proper documentation this can be remedied…

What do you think? Does this make sense at all?

EDIT: managed to get rid of the mapping in the example by using rolleshutter channel instead of number channel.

@ssalonen where I can download the current .jar directly? I believe that the market version is not always up to date, right?

I’m stuck with the errors like the one quoted below :cry:

Exception occurred while calling thing updated at ThingHandler 'org.openhab.binding.modbus.handler.ModbusTcpThingHandler@263c4781': java.lang.NullPointerException

Hi,
marketplace should be up-to-date – perhaps I introduced some new issue?

When in doubt with the marketplace, you can check the timestamp from the download link in market place:

For your convenience, here are the links to folders with jars

The error message does not help much without more comprehensive log with stack trace.

EDIT: tried reproducing the issue you are experienced and managed to get it. It was an regression in the latest change today. Try with the latest version (27-Aug-2017 16:13 UTC or newer) please

One issue less, thanks @ssalonen
one issue more:

[WARN ] [dbus.handler.ModbusWriteThingHandler] - Cannot process command REFRESH with channel modbus:write:endpointTCP:coils:DO2:writeTCP:number since command is not OnOffType, OpenClosedType or Decimal trying to write to coil. Do not know how to convert to 0/1

Edit: that disappeared after restart

Previously that crashed, now it is logged. You can safely ignore that, REFRESH command is not yet supported.

Openhab itself sends these commands on startup, in order to ensure that data is refreshed from the physical device.

not sure what is the cause, but now I see this on startup: https://pastebin.com/2j3FZ0YE

Edit: after restart see the earlier REFRESH error. Weird.