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

Denon binding telnet connection fix #3561

Merged
merged 1 commit into from Dec 18, 2015
Merged
Show file tree
Hide file tree
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 @@ -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 @@ -550,9 +560,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 @@ -574,7 +584,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();
}