openhab / jamod

A fork of Java Modbus Library (jamod) - http://jamod.sourceforge.net/
Apache License 2.0
17 stars 26 forks source link

Added request for full list of CommPortIdentifiers if we're unable to get identifer by name. #12

Open denis-ftc-denisov opened 3 years ago

denis-ftc-denisov commented 3 years ago

Hello!

I was receiving a problem of OpenHAB being to unable to open COM port under OpenSUSE Linux (detailed explanation and what i've tried is here https://community.openhab.org/t/modbus-binding-does-not-see-serial-port/118527).

More exactly, there was these errors in logfiles:

2021-03-16 22:58:03.774 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - Error connecting connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyACM0] for endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0]: Could not get port identifier, maybe insufficient permissions. null
2021-03-16 22:58:03.774 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Could not connect to endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0] -- aborting request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=10, maxTries=3] [operation ID f676e96f-e379-43e1-8757-325f65c2caac]
2021-03-16 22:58:04.279 [WARN ] [ing.ModbusSlaveConnectionFactoryImpl] - connect try 1/1 error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyACM0]. Endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0]
2021-03-16 22:58:04.279 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - re-connect reached max tries 1, throwing last error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyACM0]. Endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0]
2021-03-16 22:58:04.279 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - Error connecting connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyACM0] for endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0]: Could not get port identifier, maybe insufficient permissions. null
2021-03-16 22:58:04.279 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Could not connect to endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0] -- aborting request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=10, maxTries=3] [operation ID 3f58640a-4d38-44e0-a37d-510b61d0ba7f]
2021-03-16 22:58:04.784 [WARN ] [ing.ModbusSlaveConnectionFactoryImpl] - connect try 1/1 error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyACM0]. Endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0]
2021-03-16 22:58:04.784 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - re-connect reached max tries 1, throwing last error: Could not get port identifier, maybe insufficient permissions. null. Connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyACM0]. Endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0]
2021-03-16 22:58:04.784 [ERROR] [ing.ModbusSlaveConnectionFactoryImpl] - Error connecting connection SerialConnection [m_SerialPort=null, m_Parameters.getPortName()=/dev/ttyACM0] for endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0]: Could not get port identifier, maybe insufficient permissions. null
2021-03-16 22:58:04.784 [WARN ] [rt.modbus.internal.ModbusManagerImpl] - Could not connect to endpoint ModbusSerialSlaveEndpoint [getPortName()=/dev/ttyACM0] -- aborting request ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=0, length=10, maxTries=3] [operation ID dd687ef2-12d0-470d-b3ef-0f59b2ffdb64]

After poking the code for some time it seems to me, that CommPortIdentifier class could return null for existing port if there was no call to getCommPortIdentifiers() before calling getCommPortIdentifier(String) (that is because is has internal list of ports with head in CommPortIndex variable and this list is filled only when getCommPortIdentifiers() is called).

So, i'm suggesting a bit ugly but tiny workaround for that problem. I've tested it in my environment and it works after fix.

ssalonen commented 3 years ago

Hmm must be something with OpenSUSE since I think we have reports of having some sort of success with serial devices in OH3. Any theories why this is so?

If this change (workaround?) is indeed required for openSUSE, should this change live somewhere in openHAB core / nrjavaserial that all bindings benefit from this?

denis-ftc-denisov commented 3 years ago

Hello! It seems better to fix that inside nrjavaserial, but i don't know which version now openhab uses (so, where to send PR). This https://github.com/openhab/nrjavaserial looks like frozen repository. I don't have working theory right now, because in nrjavaserial code (as eclipse shows it) there already is similar logic (in CommPortIdentifier.getPortIdentifier(String)). Maybe my OpenHab version uses older version of nrjavaserial. I'll try to decompile that and take a look.

denis-ftc-denisov commented 3 years ago

Hello! I've investigated further, it seems that nrjavaserial-5.2.1 is used (despite having 3.12.0 in pom.xml). So it should really call getPortIdentifiers() when port is not found. My best guess is that some exception occurs inside getPortIdentifiers() (in this case CommPortIndex will stay null).