MODBUS binding problem with serial connection

Hi all,
I am on OH 3.0.1.
Today I have spent the whole day trying to make the modbus binding work without getting it to work properly.

First of all, the good news: this configuration works (and is the only one that works):

Bridge modbus:serial:evolink [ port="/dev/ttyUSB0", id=10, baud=19200, stopBits="1", parity="even", dataBits=8, connectMaxTries=1, receiveTimeoutMillis=1000 ] {
    Bridge poller holding1 [ start=0, length=6, refresh=600000, type="holding", maxTries=1 ] {
        Thing data h0 [ readStart="0", readValueType="uint16", writeStart="0", writeValueType="uint16", writeType="holding" ] 
        Thing data h1 [ readStart="1", readValueType="uint16", writeStart="1", writeValueType="uint16", writeType="holding" ] 
        Thing data h2 [ readStart="2", readValueType="uint16", writeStart="2", writeValueType="uint16", writeType="holding" ] 
        Thing data h3 [ readStart="3", readValueType="uint16", writeStart="3", writeValueType="uint16", writeType="holding" ] 
        Thing data h4 [ readStart="4", readValueType="uint16", writeStart="4", writeValueType="uint16", writeType="holding" ] 
        Thing data h5 [ readStart="5", readValueType="uint16", writeStart="5", writeValueType="uint16", writeType="holding" ] 
    }
}

So far so good.

But I need to add more pollers, and as soon as I add more pollers to the Bridge (after a reboot):

Bridge modbus:serial:evolink [ port="/dev/ttyUSB0", id=10, baud=19200, stopBits="1", parity="even", dataBits=8, connectMaxTries=1, receiveTimeoutMillis=1000 ] {
    Bridge poller holding1 [ start=0, length=6, refresh=600000, type="holding", maxTries=1 ] {
        Thing data h0 [ readStart="0", readValueType="uint16", writeStart="0", writeValueType="uint16", writeType="holding" ] 
        Thing data h1 [ readStart="1", readValueType="uint16", writeStart="1", writeValueType="uint16", writeType="holding" ] 
        Thing data h2 [ readStart="2", readValueType="uint16", writeStart="2", writeValueType="uint16", writeType="holding" ] 
        Thing data h3 [ readStart="3", readValueType="uint16", writeStart="3", writeValueType="uint16", writeType="holding" ] 
        Thing data h4 [ readStart="4", readValueType="uint16", writeStart="4", writeValueType="uint16", writeType="holding" ] 
        Thing data h5 [ readStart="5", readValueType="uint16", writeStart="5", writeValueType="uint16", writeType="holding" ] 
    }

    Bridge poller holding2  [ start=10, length=5, refresh=15000, type="holding", maxTries=1 ] {
        Thing data h10 [ readStart="10", readValueType="uint16", writeStart="10", writeValueType="uint16", writeType="holding" ]
        Thing data h11 [ readStart="11", readValueType="uint16", writeStart="11", writeValueType="uint16", writeType="holding" ]
        Thing data h12 [ readStart="12", readValueType="uint16", writeStart="12", writeValueType="uint16", writeType="holding" ]
        Thing data h13 [ readStart="13", readValueType="uint16", writeStart="13", writeValueType="uint16", writeType="holding" ]
        Thing data h14 [ readStart="14", readValueType="uint16", writeStart="14", writeValueType="uint16", writeType="holding" ]
    }
}

I get a lot of errors and all the Things remain OFFLINE:

2021-02-26 18:45:37.536 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - connect try 1/1 error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection@50fea4[portName=/dev/ttyUSB0,port=<null>]. Endpoint ModbusSerialSlaveEndpoint@8aeea1[portName=/dev/ttyUSB0]

2021-02-26 18:45:37.540 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - re-connect reached max tries 1, throwing last error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection@50fea4[portName=/dev/ttyUSB0,port=<null>]. Endpoint ModbusSerialSlaveEndpoint@8aeea1[portName=/dev/ttyUSB0]

2021-02-26 18:45:37.545 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - Error connecting connection SerialConnection@50fea4[portName=/dev/ttyUSB0,port=<null>] for endpoint ModbusSerialSlaveEndpoint@8aeea1[portName=/dev/ttyUSB0]: Could not get port identifier, maybe insufficient permissions. null

Tried to increase the log level but the info provided is always the same:

connect try 1/1 error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection@50fea4[portName=/dev/ttyUSB0,port=<null>]. Endpoint ModbusSerialSlaveEndpoint@8aeea1[portName=/dev/ttyUSB0]

I also tried to stop and restart the binding from Karaf, but after doing this also the first configuration that works after a reboot doesn’t work anymore.

Is it correct that after stopping and restarting the modbus binding the Bridge remains always OFFLINE?

Sorry for the long post, but the configuration files are huge.

There has been work on the serial handling since release.
Try the snapshot version.

I’m sorry but I’m unsure why you quoted this. That fix was for a memory leak in the rules engine.

I muffed that link,for shame.
The advice applies -there have been serial improvements for re-connect failures since 3.0

For me it worked.
thanks rossko57
EDIT: didn’t work

1 Like

I replied too early…
After some time it stops working with the same error.

Have you configured serial port according to this Serial Port Configuration | openHAB port-configuration? That could explain the permissions issue

Please be aware of known issues with serial devices with openhab3 (regression in serial library used by openhab) Serial ports getting blocked after some re-connecting · Issue #1842 · openhab/openhab-core · GitHub. See also discussion in Modbus Binding not working on OH3. I am not aware that this would be any better in 3.0.1 unfortunately

I read all those threads.
I gave up with this binding. It’s not usable.

I have written my own rules to query the modbus unit using the modpoll command line utility.
Works perfectly and absolutely reliable 100%.

As the binding maintainer I am sorry to hear it.

However the fix for serial slaves is out of my reach as the issue is with external library used by openHAB and the issue itself is way too low level to be tractable.

Would you care the share the rules? Others might benefit from this as well.

Hi @ssalonen
I didn’t mean to minimize your work. We all appreciate all the efforts that all of you put in this project.
And I know what it means to be in charge of an open source project as I am a contributor too to another domotic open source project (EspEasy).

I found your binding excellent and the documentation is phenomenal. Very clear and complete, probably the best documented binding in openHAB.

Regarding the serial port, unfortunately it’s not working.
Maybe you can push the core developers to fix the issues…
Or maybe you could develop a solution that calls “modpoll” utility:
Bridge modbus:modpoll:evolink [ port="/dev/ttyUSB0", id=10, baud=19200, stopBits="1", parity="even", dataBits=8, connectMaxTries=1, receiveTimeoutMillis=1000 ] that calls the modpoll utility instead of calling the serial port directly.
https://www.modbusdriver.com/modpoll.html

Here is how I have reproduced in the rules the behaviour of your binding…

file.things
Thing exec:command:ModbusHolding2 [command="/srv/openhab-conf/scripts/modpoll -a 10 -0 -1 -o 3 -t 4 -r 16 -c 6 /dev/ttyUSB0", interval=0, timeout=6, autorun=false, transform="REGEX(.*Polling slave...\\n(.*?))"]

file.items

String modpoll_result_mbH2  {channel="exec:command:ModbusHolding2:output"}
Switch run_mbH2 (gRunMBEvoLink) {channel="exec:command:ModbusHolding2:run", autoupdate="false"}
// Items
Number neMB_ControlMode "Mode (1=AUTO) [%d]" (gEvolink) 
Number neMB_ClSetPoint "Cl Production setpoint [%d%%]" (gEvolink) 
Number neMB_pHsetPoint "pH setpoint [%.1f]" (gEvolink)
Number neMB_ORPsetPoint "ORP setpoint [%d mV]" (gEvolink)

file.rules

rule "read modbus eypools thing holding2"
when
	Item modpoll_result_mbH2 received update
then		
	if (modpoll_result_mbH2 !== null && modpoll_result_mbH2.state != NULL && modpoll_result_mbH2.state != UNDEF){
		val String result = modpoll_result_mbH2.state.toString
		if (result.substring(0,1) == "[") {
			retryHolding2 = 0
			neMB_ControlMode.postUpdate(transform("REGEX", ".*16]: (.*?)\\n.*", result))
			neMB_ClSetPoint.postUpdate(transform("REGEX", ".*18]: (.*?)\\n.*", result))
			neMB_pHsetPoint.postUpdate(transform("JS", "divide100.js",transform("REGEX", ".*19]: (.*?)\\n.*", result)))
			neMB_ORPsetPoint.postUpdate(transform("REGEX", ".*20]: (.*?)\\n.*", result))
		} else {
			if (retryHolding2 < 3) {
				retryHolding2 += 1
				createTimer(now.plusSeconds(5)) [ | run_mbH2.sendCommand(ON) ]
			} else {
				// host is down. communication error for more than 3 times
			}
			sendNotification("xxx@gmail.com", "HOLDING2: " + result.substring(0,15) + ". Retry num.="+retryHolding2)
		}
	} 
end

file2.rules

rule "read modbus Holding2"
when
	Time cron "0 0/10 * 1/1 * ? *" // every 10 minutes
then
        run_mbH2.sendCommand(ON)
end

Note that for everybody else,it does work. But some serial users run into troubles after a while, where it appears a routine error recovery falls in hole.
Not working at all from the start still suggests that you have permissions problems.

Hi @rossko57
in my previous posts I explained that the serial binding works for a while and then it stops working.
When I say that the binding doesn’t work, I mean that it’s not usable as it stops receiving messages after a while, so it’s not reliable for my needs.

To be more precise, to setup the modbus binding, I have removed all other bindings (and relevant things and rules) and set up things, items and rules for the modbus. When everything was working I reenabled all the other bindings, things and rules and then after a while the modbus stopped working.

So the serial port configuration is perfectly fine in my system. Something else is creating the issue.

You’re right, I got muddled with another thread that never gets polling started.

Reading properly now …
Taking an overview of your mbpoll substitute method, a common factor between that and your original “one-poller Thing that works” is a single poll,always with long rests between.
I’d speculate your two-poller setup gets into trouble eventually with two polls closer together than the slave likes. That wouldn’t be unusual, and would be avoidable with use of timeBetweenTransactionsMillis= parameter.

That doesn’t help you, because that should be a recoverable error anyway.
But it fits with the theory that it’s the error recovery disconnect/reconnect that is really messing up between the binding and the serial library.

That’s exactly the point. I noticed that whenever there is any type of error, then the binding stops reading (and the error is “Could not get port identifier, maybe insufficient permissions. null.” )
And it doesn’t recover even if I stop and restart the binding. Only restarting OH solves the issue, but for me it takes 30-40 minutes for complete restart, so it’s not an option.

Hello everyone. is there any progress on this topic? I have the same problem with modbus 3.0.1, stops working after about 20 minutes.

No progress unfortunately as far as I can tell. Please see my previous post for the github link to openhab-core…

EDIT: FYI here, I’ve introduced a possible workaround for the serial library issues in modbus binding: [modbus] Workaround for nrjavaserial issues: do not disconnect serial by ssalonen · Pull Request #2272 · openhab/openhab-core · GitHub It’s not perfect but should in many cases.

EDIT2: You can find the precompiled jar in github