Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OH3] Add new serial reconnect logic #1338

Merged
merged 2 commits into from Sep 14, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -17,7 +17,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Optional;
import java.util.TooManyListenersException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -92,44 +91,15 @@ public void initialize() {
portId = (String) getConfig().get(CONFIGURATION_PORT);

super.initialize();
watchdog = scheduler.scheduleWithFixedDelay(this::watchSerialPort, WATCHDOG_INIT_SECONDS,
WATCHDOG_CHECK_SECONDS, TimeUnit.SECONDS);

}

/**
* Gets a serial port identifier for a given name.
* Workaround for getIdentifier in SerialPortManager class, because it doesn't detected correctly that the device is
* unplugged.
*
* @param the name
* @return a serial port identifier or null
*/
private @Nullable SerialPortIdentifier getSerialPortIdentifier(final String name) {
if (name.startsWith("rfc2217://")) {
return serialPortManager.getIdentifier(name);
}

Optional<SerialPortIdentifier> opt = serialPortManager.getIdentifiers().filter(id -> id.getName().equals(name))
.findFirst();
if (opt.isPresent()) {
return opt.get();
} else {
return null;
}
watchdog = scheduler.schedule(this::watchSerialPort, WATCHDOG_INIT_SECONDS, TimeUnit.SECONDS);
}

private void watchSerialPort() {
try {
SerialPortIdentifier portIdentifier = getSerialPortIdentifier(portId);
SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(portId);
if (portIdentifier == null) {
if (serialPort != null) {
onSerialPortError(ZWaveBindingConstants.OFFLINE_SERIAL_NOTFOUND);
}
return;
}

if (serialPort != null) {
watchdog = scheduler.schedule(this::watchSerialPort, WATCHDOG_CHECK_SECONDS, TimeUnit.SECONDS);
return;
}

Expand All @@ -138,11 +108,10 @@ private void watchSerialPort() {
try {
commPort = portIdentifier.open("org.openhab.binding.zwave", 2000);
} catch (IllegalStateException e) {
if (serialPort != null) {
onSerialPortError(ZWaveBindingConstants.OFFLINE_SERIAL_NOTFOUND);
}
watchdog = scheduler.schedule(this::watchSerialPort, WATCHDOG_CHECK_SECONDS, TimeUnit.SECONDS);
return;
}

serialPort = commPort;
commPort.setSerialPortParams(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
try {
Expand All @@ -156,6 +125,7 @@ private void watchSerialPort() {
} catch (UnsupportedCommOperationException e) {
logger.debug("Enabling receive timeout is unsupported");
}

inputStream = commPort.getInputStream();
outputStream = commPort.getOutputStream();
logger.debug("Starting receive thread");
Expand All @@ -164,8 +134,7 @@ private void watchSerialPort() {
receiveThread = zWaveReceiveThread;
zWaveReceiveThread.start();

// RXTX serial port library causes high CPU load
// Start event listener, which will just sleep and slow down event loop
// Start event listener, which will notify when the USB device is disconnected
commPort.addEventListener(zWaveReceiveThread);
commPort.notifyOnDataAvailable(false);

Expand Down Expand Up @@ -214,6 +183,9 @@ private void onSerialPortError(String errorMessage) {
stopNetwork();
disposeReceiveThread();
disposeSerialConnection();
receiveTimeoutEnabled = false;

watchdog = scheduler.schedule(this::watchSerialPort, WATCHDOG_INIT_SECONDS, TimeUnit.SECONDS);
}

/**
Expand Down Expand Up @@ -275,6 +247,8 @@ private class ZWaveReceiveThread extends Thread implements SerialPortEventListen
private static final int SEARCH_LEN = 1;
private static final int SEARCH_DAT = 2;

private static final int HARDWARE_ERROR = 11;

private int rxState = SEARCH_SOF;
private int messageLength;
private int rxLength;
Expand All @@ -286,10 +260,8 @@ private class ZWaveReceiveThread extends Thread implements SerialPortEventListen

@Override
public void serialEvent(SerialPortEvent arg0) {
try {
logger.trace("RXTX library CPU load workaround, sleep forever");
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
if (arg0.getEventType() == HARDWARE_ERROR) {
onSerialPortError(ZWaveBindingConstants.OFFLINE_SERIAL_NOTFOUND);
}
}

Expand Down Expand Up @@ -339,6 +311,7 @@ public void run() {
if (serialPort == null) {
break;
}

nextByte = inputStream.read();
// logger.debug("SERIAL:: STATE {}, nextByte {}, count {} ", rxState, nextByte, rxLength);

Expand Down