Make retries more robust

Makes retries more robust. Three times for connection and one retry on the command.
Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
This commit is contained in:
Bob Eckhoff 2024-11-23 11:09:48 -05:00
parent 23ec6aeb7e
commit 18d67a08c5

View File

@ -70,7 +70,7 @@ public class ConnectionManager {
private int droppedCommands = 0; private int droppedCommands = 0;
/** /**
* True allows one short retry after connection problem * True allows command retry if null response
*/ */
private boolean retry = true; private boolean retry = true;
@ -124,36 +124,35 @@ public class ConnectionManager {
public synchronized void connect() throws MideaConnectionException, MideaAuthenticationException { public synchronized void connect() throws MideaConnectionException, MideaAuthenticationException {
logger.trace("Connecting to {}:{}", ipAddress, ipPort); logger.trace("Connecting to {}:{}", ipAddress, ipPort);
int maxTries = 3;
int retryCount = 0;
// Open socket // Open socket
try { // Retry addresses most common wifi connection problems- wait 5 seconds and try again
socket = new Socket(); while (retryCount < maxTries) {
socket.setSoTimeout(timeout * 1000); try {
socket.connect(new InetSocketAddress(ipAddress, ipPort), timeout * 1000); socket = new Socket();
} catch (IOException e) { socket.setSoTimeout(timeout * 1000);
// Retry addresses most common wifi connection problems- wait 5 seconds and try again socket.connect(new InetSocketAddress(ipAddress, ipPort), timeout * 1000);
if (retry) { break;
logger.debug("Retrying Socket, IOException connecting to {}: {}", ipAddress, e.getMessage()); } catch (IOException e) {
try { retryCount++;
Thread.sleep(5000); if (retryCount < maxTries) {
} catch (InterruptedException ex) { try {
logger.debug("An interupted error (socket retry) has occured {}", ex.getMessage()); Thread.sleep(5000);
} catch (InterruptedException ex) {
logger.debug("An interupted error (socket retry) has occured {}", ex.getMessage());
}
logger.debug("Socket retry count {}, IOException connecting to {}: {}", retryCount, ipAddress,
e.getMessage());
} }
retry = false;
try {
socket.close();
socket = new Socket();
socket.setSoTimeout(timeout * 1000);
socket.connect(new InetSocketAddress(ipAddress, ipPort), timeout * 1000);
} catch (IOException e2) {
deviceIsConnected = false;
logger.debug("Second try IOException connecting to {}: {}", ipAddress, e2.getMessage());
throw new MideaConnectionException(e2);
}
} else {
deviceIsConnected = false;
throw new MideaConnectionException(e);
} }
} }
if (retryCount == maxTries) {
deviceIsConnected = false;
logger.info("Failed to connect after {} tries. Try again with next scheduled poll", maxTries);
throw new MideaConnectionException("Failed to connect after maximum tries");
}
// Create streams // Create streams
try { try {
@ -180,7 +179,6 @@ public class ConnectionManager {
} }
logger.debug("Connected to IP {}", ipAddress); logger.debug("Connected to IP {}", ipAddress);
deviceIsConnected = true; deviceIsConnected = true;
retry = true;
} }
/** /**
@ -321,6 +319,7 @@ public class ConnectionManager {
byte[] responseBytes = read(); byte[] responseBytes = read();
if (responseBytes != null) { if (responseBytes != null) {
retry = true;
if (version == 3) { if (version == 3) {
Decryption8370Result result = security.decode8370(responseBytes); Decryption8370Result result = security.decode8370(responseBytes);
for (byte[] response : result.getResponses()) { for (byte[] response : result.getResponses()) {
@ -412,14 +411,30 @@ public class ConnectionManager {
Utils.bytesToHex(data)); Utils.bytesToHex(data));
if (data.length > 0) { if (data.length > 0) {
data = Arrays.copyOfRange(data, 10, data.length); data = Arrays.copyOfRange(data, 10, data.length);
byte bodyType = data[0x0];
logger.trace("V2 Bytes decoded and stripped without header: length: {}, data: {}", data.length, logger.trace("V2 Bytes decoded and stripped without header: length: {}, data: {}", data.length,
Utils.bytesToHex(data)); Utils.bytesToHex(data));
if (data.length < 21) {
lastResponse = new Response(data, version, "", (byte) 0x00); logger.warn("Response data is {} long, minimum is 21!", data.length);
logger.debug("Data length is {}, version is {}, Ip Address is {}", data.length, version, return;
ipAddress); }
if (callback != null) { if (bodyType != -64) {
callback.updateChannels(lastResponse); if (bodyType == 30) {
logger.warn("Error response 0x1E received {} from IP Address:{}", bodyType, ipAddress);
return;
}
logger.warn("Unexpected response bodyType {}", bodyType);
return;
}
lastResponse = new Response(data, version, "", bodyType);
try {
logger.trace("Data length is {}, version is {}, Ip Address is {}", data.length, version,
ipAddress);
if (callback != null) {
callback.updateChannels(lastResponse);
}
} catch (Exception ex) {
logger.warn("Processing response exception: {}", ex.getMessage());
} }
} else { } else {
droppedCommands = droppedCommands + 1; droppedCommands = droppedCommands + 1;
@ -429,10 +444,17 @@ public class ConnectionManager {
} }
return; return;
} else { } else {
droppedCommands = droppedCommands + 1; if (retry) {
logger.debug("Problem with reading response, skipping {} skipped count since startup {}", command, logger.debug("Resending Command {}", command);
droppedCommands); retry = false;
return; sendCommand(command, callback);
} else {
droppedCommands = droppedCommands + 1;
logger.info("Problem with reading response, skipping {} skipped count since startup {}", command,
droppedCommands);
retry = true;
return;
}
} }
} catch (SocketException e) { } catch (SocketException e) {
droppedCommands = droppedCommands + 1; droppedCommands = droppedCommands + 1;