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

[Davis] Enable IP communication with davis weather station #5227

Merged
merged 4 commits into from Jul 5, 2019
Merged
Show file tree
Hide file tree
Changes from 2 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
14 changes: 9 additions & 5 deletions bundles/binding/org.openhab.binding.davis/README.md
@@ -1,6 +1,6 @@
# Davis Binding

The openHAB Davis binding supports reading data from Davis weather stations. Most Davis weather stations should be supported.
The openHAB Davis binding supports reading data from Davis weather stations. Most Davis weather stations should be supported. Connection type may be SERIAL (serial port given in property 'port') or IP (hostName property).
9037568 marked this conversation as resolved.
Show resolved Hide resolved

The binding is based on the [Serial Communication Reference Manual](http://www.google.at/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCQQFjAA&url=http%3A%2F%2Fwww.davisnet.com%2Fsupport%2Fweather%2Fdownload%2FVantageSerialProtocolDocs_v261.pdf&ei=yns1VLO9B9Pe7Ab9hYDgDQ&usg=AFQjCNEUP_O6jjV3tHaxc7_faaLKWAtw2g&sig2=0YuJy45Qmk76RlffOqayuA&bvm=bv.76943099,d.ZGU) from Davis.

Expand All @@ -9,10 +9,14 @@ The binding is based on the [Serial Communication Reference Manual](http://www.g

The binding can be configured in the file `services/davis.cfg`.

| Property | Default | Required | Description |
|----------|---------|:--------:|----------------------------------------|
| port | | Yes | The serial port of the Weather station |
| refresh | 10000 | No | The refresh interval (in milliseconds) |
| Property | Default | Required | Description |
|----------------------|----------|:--------:|------------------------------------------------------|
| refresh | 10000 | No | The refresh interval (in milliseconds) |
| port | | No | The serial port of the Weather station |
| hostName | | No | HostName of the Weather station |
9037568 marked this conversation as resolved.
Show resolved Hide resolved
| readResponseWaitTime | 200|1000 | No | Wait time for response (in milliseconds) |
| | | | 200 in case of serial - 1000 for IP |



## Item Configuration
Expand Down
Expand Up @@ -13,6 +13,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Enumeration;
Expand Down Expand Up @@ -42,7 +44,7 @@
* @author Trathnigg Thomas
* @since 1.6.0
*/
public class DavisBinding extends AbstractActiveBinding<DavisBindingProvider>implements ManagedService {
public class DavisBinding extends AbstractActiveBinding<DavisBindingProvider> implements ManagedService {

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

Expand All @@ -54,7 +56,33 @@ public class DavisBinding extends AbstractActiveBinding<DavisBindingProvider>imp

private static final int BUF_LENGTH = 256;

private boolean typeIsSerial = true;

/**
* serial port name of the davis weather station, in case of SERIAL communication
*/
private String port;

private Socket ipSocket;

/**
* hostName of the davis weather station, in case of IP communication
*/
private String hostName;

/**
* ipPortNumber of the davis weather station, in case of IP communication (davis settings, fixed)
*/
private int ipPortNumber = 22222;

/**
* waitTime before reading response, default value are is different according communication type
*/
private long readResponseWaitTime;

private long defaultSerialReadResponseWaitTime = 200;
private long defaultIpReadResponseWaitTime = 1000;

private SerialPort serialPort;
private InputStream inputStream;
private OutputStream outputStream;
Expand Down Expand Up @@ -139,50 +167,98 @@ public void updated(Dictionary<String, ?> config) throws ConfigurationException
if (StringUtils.isNotBlank(refreshIntervalString)) {
refreshInterval = Long.parseLong(refreshIntervalString);
}

String newPort = (String) config.get("port"); //$NON-NLS-1$
if (StringUtils.isNotBlank(newPort) && !newPort.equals(port)) {
port = newPort;
String newHostName = (String) config.get("hostName"); //$NON-NLS-1$

if (StringUtils.isNotBlank(newPort) && StringUtils.isNotBlank(newHostName)) {
logger.error(
9037568 marked this conversation as resolved.
Show resolved Hide resolved
"both properties port and hostname configured, only one can be set according communication type serial (port) or IP (hostname)");
setProperlyConfigured(false);
} else {
if (StringUtils.isNotBlank(newPort)) {
typeIsSerial = true;
port = newPort;
readResponseWaitTime = defaultSerialReadResponseWaitTime;
}
9037568 marked this conversation as resolved.
Show resolved Hide resolved
if (StringUtils.isNotBlank(newHostName)) {
typeIsSerial = false;
hostName = newHostName;
readResponseWaitTime = defaultIpReadResponseWaitTime;
}
9037568 marked this conversation as resolved.
Show resolved Hide resolved

String readResponseWaitTimeString = (String) config.get("readResponseWaitTime");
if (StringUtils.isNotBlank(readResponseWaitTimeString)) {
try {
readResponseWaitTime = Long.parseLong(readResponseWaitTimeString);
} catch (NumberFormatException e) {
logger.warn("ignoring property 'readResponseWaitTime', not numeric");
}
}

if (typeIsSerial) {
logger.info("ProperlyConfigured on port " + port + " with readResponseWaitTime on "
9037568 marked this conversation as resolved.
Show resolved Hide resolved
+ readResponseWaitTime);
} else {
logger.info("ProperlyConfigured with hostName " + hostName + " with readResponseWaitTime on "
9037568 marked this conversation as resolved.
Show resolved Hide resolved
+ readResponseWaitTime);
}

setProperlyConfigured(true);
}
}
}

public void openPort() throws InitializationException {
CommPortIdentifier portIdentifier;

try {
portIdentifier = CommPortIdentifier.getPortIdentifier(port);
if (typeIsSerial) {
CommPortIdentifier portIdentifier;

try {
serialPort = portIdentifier.open("openhab", 3000);
serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
serialPort.enableReceiveTimeout(100);
serialPort.enableReceiveThreshold(1);
inputStream = new DataInputStream(new BufferedInputStream(serialPort.getInputStream()));
outputStream = serialPort.getOutputStream();
logger.debug("port opened: " + port);
} catch (PortInUseException e) {
throw new InitializationException(e);
} catch (UnsupportedCommOperationException e) {
throw new InitializationException(e);
} catch (IOException e) {
throw new InitializationException(e);
}
portIdentifier = CommPortIdentifier.getPortIdentifier(port);

try {
serialPort = portIdentifier.open("openhab", 3000);
serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN |
9037568 marked this conversation as resolved.
Show resolved Hide resolved
// SerialPort.FLOWCONTROL_RTSCTS_OUT);
serialPort.enableReceiveTimeout(100);
serialPort.enableReceiveThreshold(1);
inputStream = new DataInputStream(new BufferedInputStream(serialPort.getInputStream()));
outputStream = serialPort.getOutputStream();
logger.debug("port opened: " + port);
9037568 marked this conversation as resolved.
Show resolved Hide resolved
} catch (PortInUseException e) {
throw new InitializationException(e);
} catch (UnsupportedCommOperationException e) {
throw new InitializationException(e);
} catch (IOException e) {
throw new InitializationException(e);
}

} catch (NoSuchPortException e) {
StringBuilder sb = new StringBuilder();
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
CommPortIdentifier id = (CommPortIdentifier) portList.nextElement();
if (id.getPortType() == CommPortIdentifier.PORT_SERIAL) {
sb.append(id.getName() + "\n");
} catch (NoSuchPortException e) {
StringBuilder sb = new StringBuilder();
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
CommPortIdentifier id = (CommPortIdentifier) portList.nextElement();
if (id.getPortType() == CommPortIdentifier.PORT_SERIAL) {
sb.append(id.getName() + "\n");
}
}
}

throw new InitializationException(
"Serial port '" + port + "' could not be found. Available ports are:\n" + sb.toString());
throw new InitializationException(
"Serial port '" + port + "' could not be found. Available ports are:\n" + sb.toString());
}
} else {
try {
ipSocket = new Socket(hostName, ipPortNumber);
inputStream = ipSocket.getInputStream();
outputStream = ipSocket.getOutputStream();
logger.debug("ipSocket opened: " + hostName + " on port " + ipPortNumber);
9037568 marked this conversation as resolved.
Show resolved Hide resolved
} catch (UnknownHostException e) {
throw new InitializationException("UnknownHost '" + hostName);
9037568 marked this conversation as resolved.
Show resolved Hide resolved
} catch (IOException e) {
throw new InitializationException("IO error with '" + hostName + " on port " + ipPortNumber);
9037568 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

Expand All @@ -197,8 +273,17 @@ public void closePort() {
} catch (IOException e) {
e.printStackTrace();
}
serialPort.close();
logger.debug("port closed: " + port);
if (typeIsSerial) {
serialPort.close();
logger.debug("port closed: " + port);
9037568 marked this conversation as resolved.
Show resolved Hide resolved
} else {
try {
ipSocket.close();
logger.debug("ipSocket closed: " + hostName + " on port " + ipPortNumber);
9037568 marked this conversation as resolved.
Show resolved Hide resolved
} catch (IOException e) {
e.printStackTrace();
9037568 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

protected void resetAfterError() {
Expand Down Expand Up @@ -240,9 +325,10 @@ public byte[] readResponse() throws IOException {
try {
// add wait states around reading the stream, so that
// interrupted transmissions are merged
Thread.sleep(200);
Thread.sleep(readResponseWaitTime);
} catch (InterruptedException e) {
// ignore interruption
logger.debug("InterruptedException");
}

} while (inputStream.available() > 0);
Expand Down