Skip to content
This repository has been archived by the owner on May 17, 2021. It is now read-only.

Commit

Permalink
Merge pull request #3561 from idserda/denon-connect-fix
Browse files Browse the repository at this point in the history
Denon binding telnet connection fix
  • Loading branch information
teichsta committed Dec 18, 2015
2 parents e4e84f7 + 759d5cd commit 2f2a9ab
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 54 deletions.
Expand Up @@ -136,11 +136,21 @@ public DenonConnector(DenonConnectionProperties connection, DenonPropertyUpdated
*/
public void connect() {
if (connection.isTelnet()) {
listener = new DenonListener(connection, new DenonUpdateReceivedCallback() {
listener = new DenonListener(connection, new DenonUpdateReceivedCallback() {
@Override
public void updateReceived(String command) {
processUpdate(command);
}

@Override
public void listenerConnected() {
getInitialState();
}

@Override
public void listenerDisconnected() {
sendUpdate(DenonProperty.POWER.getCode(), OnOffType.OFF);
}
});
listener.start();
}
Expand Down Expand Up @@ -552,9 +562,9 @@ private <T> T getDocument(String uri, Class<T> response) {
return obj;
}
} catch (JAXBException e) {
logger.warn("Encoding error in get", e);
logger.debug("Encoding error in get", e);
} catch (XMLStreamException e) {
logger.warn("Communication error in get", e);
logger.debug("Communication error in get", e);
}

return null;
Expand All @@ -579,7 +589,7 @@ private <T,S> T postDocument(String uri, Class<T> response, S request) {
return obj;
}
} catch (JAXBException e) {
logger.warn("Encoding error in post", e);
logger.debug("Encoding error in post", e);
}

return null;
Expand Down
Expand Up @@ -8,97 +8,128 @@
*/
package org.openhab.binding.denon.internal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.SocketTimeoutException;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.telnet.TelnetClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Manage telnet connection to the Denon Receiver
* Manage telnet connection to the Denon Receiver
*
* @author Jeroen Idserda
* @since 1.7.0
*/
public class DenonListener extends Thread {

private static final Logger logger = LoggerFactory.getLogger(DenonListener.class);

private static final Integer RECONNECT_DELAY = 10000; // 10 seconds


private static final Integer RECONNECT_DELAY = 60000; // 1 minute

private static final Integer TIMEOUT = 60000; // 1 minute

private DenonConnectionProperties connection;

private DenonUpdateReceivedCallback callback;

private TelnetClient tc;

boolean running = true;


private TelnetClient tc;

private boolean running = true;

private boolean connected = false;

public DenonListener(DenonConnectionProperties connection, DenonUpdateReceivedCallback callback) {
logger.debug("Denon listener created");
this.tc = new TelnetClient();
this.connection = connection;
this.callback = callback;

this.tc = createTelnetClient();
}

@Override
public void run() {
while (running) {
if (!tc.isConnected()) {
connectTelnetClient();
}

boolean end_loop = false;
BufferedReader reader = new BufferedReader(new InputStreamReader(tc.getInputStream()));

do {
try {
String line = reader.readLine();

if (!StringUtils.isBlank(line)) {
logger.trace("Received from {}: {}", connection.getHost(), line);
callback.updateReceived(line);
}
} catch (IOException e) {
logger.warn("Error in telnet connection", e);
end_loop = true;
if (!connected) {
connectTelnetClient();
}

InputStream is = tc.getInputStream();
PrintWriter out = new PrintWriter(tc.getOutputStream(), true);

int readCount = 0;
byte[] buffer = new byte[4096];

do {
try {
readCount = is.read(buffer);
if (readCount > -1) {
String line = StringUtils.trim(new String(buffer, 0, readCount));
if (!StringUtils.isBlank(line)) {
logger.trace("Received from {}: {}", connection.getHost(), line);
callback.updateReceived(line);
}
} else {
throw new IOException("Telnet connection disconnected");
}
} catch (SocketTimeoutException e) {
logger.trace("Socket timeout");
// Disconnects are not always detected unless you write to the socket.
out.print(" ");
out.flush();
} catch (IOException e) {
callback.listenerDisconnected();
logger.debug("Error in telnet connection", e);
connected = false;
}
}
while(running && end_loop == false);
} while (running && connected);
}
}


public void shutdown() {
this.running = false;
disconnect();
}

private void connectTelnetClient() {
disconnect();
int delay = 0;

while (!tc.isConnected()) {
try {
Thread.sleep(delay);
logger.debug("Connecting to {}", connection.getHost());
tc.connect(connection.getHost(), connection.getTelnetPort());
} catch (SocketException e) {
logger.error("Error connecting to {}", connection.getHost(), e);
callback.listenerConnected();
connected = true;
} catch (IOException e) {
logger.error("Error connecting to {}", connection.getHost(), e);
logger.debug("Cannot connect to {}", connection.getHost(), e);
} catch (InterruptedException e) {
logger.error("Error connecting to {}", connection.getHost(), e);
logger.debug("Interrupted while connecting to {}", connection.getHost(), e);
}
delay = RECONNECT_DELAY;
}

logger.debug("Denon telnet client connected to {}", connection.getHost());
}

public void shutdown(){
this.running = false;

try {
this.tc.disconnect();
} catch (IOException e) {
logger.debug("Error while disconnecting telnet client", e);
private void disconnect() {
if (tc != null) {
try {
this.tc.disconnect();
} catch (IOException e) {
logger.debug("Error while disconnecting telnet client", e);
}
}
}

private TelnetClient createTelnetClient() {
TelnetClient tc = new TelnetClient();
tc.setDefaultTimeout(TIMEOUT);
return tc;
}

}
Expand Up @@ -17,10 +17,20 @@
public interface DenonUpdateReceivedCallback {

/**
* Update was received.
* Update was received.
*
* @param command The line of text that was received from the telnet connection
* @param command
* The line of text that was received from the telnet connection
*/
public void updateReceived(String command);

/**
* The listener has successfully connected to the receiver.
*/
public void listenerConnected();

/**
* The listener has lost connection to the receiver.
*/
public void listenerDisconnected();
}

0 comments on commit 2f2a9ab

Please sign in to comment.