added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.etherrain-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-etherrain" description="Etherrain Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.etherrain/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EtherRainBindingConstants {
|
||||
|
||||
private static final String BINDING_ID = "etherrain";
|
||||
|
||||
// List of all Thing ids
|
||||
|
||||
private static final String ETHERRAIN = "etherrain";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
|
||||
public static final ThingTypeUID ETHERRAIN_THING = new ThingTypeUID(BINDING_ID, ETHERRAIN);
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(ETHERRAIN_THING);
|
||||
|
||||
// List of internal default values
|
||||
|
||||
public static final int DEFAULT_WAIT_BEFORE_INITIAL_REFRESH = 30;
|
||||
public static final int DEFAULT_REFRESH_RATE = 60;
|
||||
public static final short DISCOVERY_SUBNET_MASK = 24;
|
||||
public static final int DISCOVERY_THREAD_POOL_SIZE = 15;
|
||||
public static final int DISCOVERY_THREAD_POOL_SHUTDOWN_WAIT_TIME_SECONDS = 300;
|
||||
public static final boolean DISCOVERY_DEFAULT_AUTO_DISCOVER = false;
|
||||
public static final int DISCOVERY_DEFAULT_TIMEOUT_RATE = 500;
|
||||
public static final int DISCOVERY_DEFAULT_IP_TIMEOUT_RATE = 750;
|
||||
|
||||
// List of all Channel ids
|
||||
|
||||
public static final String CHANNEL_ID_COMMAND_STATUS = "commandstatus";
|
||||
public static final String CHANNEL_ID_OPERATING_STATUS = "operatingstatus";
|
||||
public static final String CHANNEL_ID_OPERATING_RESULT = "operatingresult";
|
||||
public static final String CHANNEL_ID_RELAY_INDEX = "relayindex";
|
||||
public static final String CHANNEL_ID_SENSOR_RAIN = "rainsensor";
|
||||
public static final String CHANNEL_ID_START_DELAY = "startdelay";
|
||||
public static final String CHANNEL_ID_EXECUTE = "execute";
|
||||
public static final String CHANNEL_ID_CLEAR = "clear";
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainException} class defines an exception for handling
|
||||
* EtherRainExceptions
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class EtherRainException extends Exception {
|
||||
private static final long serialVersionUID = 1348095602193770716L;
|
||||
|
||||
public EtherRainException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.etherrain.internal.handler.EtherRainHandler;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
@Component(service = ThingHandlerFactory.class, immediate = true, configurationPid = "binding.etherrain")
|
||||
@NonNullByDefault
|
||||
public class EtherRainHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Activate
|
||||
public EtherRainHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
|
||||
httpClient = httpClientFactory.getCommonHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return EtherRainBindingConstants.SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (thingTypeUID.equals(EtherRainBindingConstants.ETHERRAIN_THING)) {
|
||||
return new EtherRainHandler(thing, httpClient);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainCommandResult} is the response packet for Command Result
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public enum EtherRainCommandResult {
|
||||
OK("OK"),
|
||||
RN("RN"),
|
||||
SH("SH"),
|
||||
NC("NC");
|
||||
|
||||
private final String result;
|
||||
|
||||
EtherRainCommandResult(String result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainCommandStatus} is the response packet for Command Status
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public enum EtherRainCommandStatus {
|
||||
OK("OK"),
|
||||
ER("ER"),
|
||||
NA("NA");
|
||||
|
||||
private final String status;
|
||||
|
||||
EtherRainCommandStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal.api;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.openhab.binding.etherrain.internal.EtherRainException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainCommunication} handles communication with EtherRain
|
||||
* controllers so that the API is all in one place
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class EtherRainCommunication {
|
||||
|
||||
private static final String BROADCAST_DISCOVERY_MESSAGE = "eviro_id_request1";
|
||||
private static final int BROADCAST_DISCOVERY_PORT = 8089;
|
||||
|
||||
private static final String ETHERRAIN_USERNAME = "admin";
|
||||
|
||||
private static final int HTTP_TIMEOUT = 3;
|
||||
|
||||
private static final int BROADCAST_TIMEOUT = 80;
|
||||
|
||||
private static final String RESPONSE_STATUS_PATTERN = "^\\s*(un|ma|ac|os|cs|rz|ri|rn):\\s*([a-zA-Z0-9\\.]*)(\\s*<br>)?";
|
||||
private static final String BROADCAST_RESPONSE_DISCOVER_PATTERN = "eviro t=(\\S*) n=(\\S*) p=(\\S*) a=(\\S*)";
|
||||
|
||||
private static final Pattern broadcastResponseDiscoverPattern = Pattern
|
||||
.compile(BROADCAST_RESPONSE_DISCOVER_PATTERN);
|
||||
private static final Pattern responseStatusPattern = Pattern.compile(RESPONSE_STATUS_PATTERN);
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EtherRainCommunication.class);
|
||||
private final HttpClient httpClient;
|
||||
|
||||
private final String address;
|
||||
private final int port;
|
||||
private final String password;
|
||||
|
||||
public EtherRainCommunication(String address, int port, String password, HttpClient httpClient) {
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
this.password = password;
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
public static List<EtherRainUdpResponse> autoDiscover() {
|
||||
return updBroadcast();
|
||||
}
|
||||
|
||||
public EtherRainStatusResponse commandStatus() throws EtherRainException, IOException {
|
||||
commandLogin();
|
||||
|
||||
List<String> responseList = sendGet("result.cgi?xs");
|
||||
|
||||
if (responseList.isEmpty()) {
|
||||
throw new EtherRainException("Empty Response");
|
||||
}
|
||||
|
||||
EtherRainStatusResponse response = new EtherRainStatusResponse();
|
||||
|
||||
for (String line : responseList) {
|
||||
|
||||
Matcher m = responseStatusPattern.matcher(line);
|
||||
|
||||
if (m.matches()) {
|
||||
String command = m.replaceAll("$1");
|
||||
String status = m.replaceAll("$2");
|
||||
|
||||
switch (command) {
|
||||
case "un":
|
||||
response.setUniqueName(status);
|
||||
break;
|
||||
case "ma":
|
||||
response.setMacAddress(status);
|
||||
break;
|
||||
case "ac":
|
||||
response.setServiceAccount(status);
|
||||
break;
|
||||
case "os":
|
||||
response.setOperatingStatus(EtherRainOperatingStatus.valueOf(status.toUpperCase()));
|
||||
break;
|
||||
case "cs":
|
||||
response.setLastCommandStatus(EtherRainCommandStatus.valueOf(status.toUpperCase()));
|
||||
break;
|
||||
case "rz":
|
||||
response.setLastCommandResult(EtherRainCommandResult.valueOf(status.toUpperCase()));
|
||||
break;
|
||||
case "ri":
|
||||
response.setLastActiveValue(Integer.parseInt(status));
|
||||
break;
|
||||
case "rn":
|
||||
response.setRainSensor(Integer.parseInt(status) == 1);
|
||||
break;
|
||||
default:
|
||||
logger.debug("Unknown response: {}", command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public synchronized boolean commandIrrigate(int delay, int zone1, int zone2, int zone3, int zone4, int zone5,
|
||||
int zone6, int zone7, int zone8) {
|
||||
try {
|
||||
sendGet("result.cgi?xi=" + delay + ":" + zone1 + ":" + zone2 + ":" + zone3 + ":" + zone4 + ":" + zone5 + ":"
|
||||
+ zone6 + ":" + zone7 + ":" + zone8);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not send irrigate command to etherrain: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean commandClear() {
|
||||
try {
|
||||
sendGet("/result.cgi?xr");
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not send clear command to etherrain: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean commandLogin() throws EtherRainException {
|
||||
try {
|
||||
sendGet("/ergetcfg.cgi?lu=" + ETHERRAIN_USERNAME + "&lp=" + password);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not send clear command to etherrain: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean commandLogout() {
|
||||
try {
|
||||
sendGet("/ergetcfg.cgi?m=o");
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not send logout command to etherrain: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private synchronized List<String> sendGet(String command) throws IOException {
|
||||
String url = "http://" + address + ":" + port + "/" + command;
|
||||
|
||||
ContentResponse response;
|
||||
|
||||
try {
|
||||
response = httpClient.newRequest(url).timeout(HTTP_TIMEOUT, TimeUnit.SECONDS).send();
|
||||
if (response.getStatus() != HttpURLConnection.HTTP_OK) {
|
||||
logger.warn("Etherrain return status other than HTTP_OK : {}", response.getStatus());
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} catch (InterruptedException | TimeoutException | ExecutionException e) {
|
||||
logger.warn("Could not connect to Etherrain with exception: {}", e.getMessage());
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return new BufferedReader(new StringReader(response.getContentAsString())).lines().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static List<EtherRainUdpResponse> updBroadcast() {
|
||||
List<EtherRainUdpResponse> rList = new LinkedList<>();
|
||||
|
||||
// Find the server using UDP broadcast
|
||||
|
||||
try (DatagramSocket c = new DatagramSocket()) {
|
||||
c.setSoTimeout(BROADCAST_TIMEOUT);
|
||||
c.setBroadcast(true);
|
||||
|
||||
byte[] sendData = BROADCAST_DISCOVERY_MESSAGE.getBytes("UTF-8");
|
||||
|
||||
// Try the 255.255.255.255 first
|
||||
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
|
||||
InetAddress.getByName("255.255.255.255"), BROADCAST_DISCOVERY_PORT);
|
||||
c.send(sendPacket);
|
||||
|
||||
while (true) {
|
||||
// Wait for a response
|
||||
byte[] recvBuf = new byte[15000];
|
||||
DatagramPacket receivePacket;
|
||||
try {
|
||||
receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
|
||||
c.receive(receivePacket);
|
||||
} catch (SocketTimeoutException e) {
|
||||
return rList;
|
||||
}
|
||||
|
||||
// Check if the message is correct
|
||||
String message = new String(receivePacket.getData(), "UTF-8").trim();
|
||||
|
||||
if (message.length() == 0) {
|
||||
return rList;
|
||||
}
|
||||
|
||||
String addressBC = receivePacket.getAddress().getHostAddress();
|
||||
|
||||
Matcher matcher = broadcastResponseDiscoverPattern.matcher(message);
|
||||
String deviceTypeBC = matcher.replaceAll("$1");
|
||||
String unqiueNameBC = matcher.replaceAll("$2");
|
||||
int portBC = Integer.parseInt(matcher.replaceAll("$3"));
|
||||
|
||||
// NOTE: Version 3.77 of API states that Additional Parameters (a=) are not used
|
||||
// on EtherRain
|
||||
rList.add(new EtherRainUdpResponse(deviceTypeBC, addressBC, portBC, unqiueNameBC, ""));
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
return rList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainOperatingStatus} is the response packet for Operating Status
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public enum EtherRainOperatingStatus {
|
||||
RD("RD"),
|
||||
WT("WT"),
|
||||
BZ("BZ");
|
||||
|
||||
private final String status;
|
||||
|
||||
EtherRainOperatingStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainStatusResponse} is a encapsulation of responses from the EtherRain
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class EtherRainStatusResponse {
|
||||
|
||||
private String uniqueName = "";
|
||||
private String macAddress = "";
|
||||
private String serviceAccount = "";
|
||||
|
||||
private EtherRainOperatingStatus operatingStatus = EtherRainOperatingStatus.WT;
|
||||
private EtherRainCommandStatus lastCommandStatus = EtherRainCommandStatus.ER;
|
||||
private EtherRainCommandResult lastCommandResult = EtherRainCommandResult.NC;
|
||||
|
||||
private int lastActiveValue;
|
||||
private boolean rainSensor;
|
||||
|
||||
public String getUniqueName() {
|
||||
return uniqueName;
|
||||
}
|
||||
|
||||
public void setUniqueName(String uniqueName) {
|
||||
this.uniqueName = uniqueName;
|
||||
}
|
||||
|
||||
public String getMacAddress() {
|
||||
return macAddress;
|
||||
}
|
||||
|
||||
public void setMacAddress(String macAddress) {
|
||||
this.macAddress = macAddress;
|
||||
}
|
||||
|
||||
public String getServiceAccount() {
|
||||
return serviceAccount;
|
||||
}
|
||||
|
||||
public void setServiceAccount(String serviceAccount) {
|
||||
this.serviceAccount = serviceAccount;
|
||||
}
|
||||
|
||||
public EtherRainOperatingStatus getOperatingStatus() {
|
||||
return operatingStatus;
|
||||
}
|
||||
|
||||
public void setOperatingStatus(EtherRainOperatingStatus operatingStatus) {
|
||||
this.operatingStatus = operatingStatus;
|
||||
}
|
||||
|
||||
public EtherRainCommandStatus getLastCommandStatus() {
|
||||
return lastCommandStatus;
|
||||
}
|
||||
|
||||
public void setLastCommandStatus(EtherRainCommandStatus lastCommandStatus) {
|
||||
this.lastCommandStatus = lastCommandStatus;
|
||||
}
|
||||
|
||||
public EtherRainCommandResult getLastCommandResult() {
|
||||
return lastCommandResult;
|
||||
}
|
||||
|
||||
public void setLastCommandResult(EtherRainCommandResult lastCommandResult) {
|
||||
this.lastCommandResult = lastCommandResult;
|
||||
}
|
||||
|
||||
public int getLastActiveValue() {
|
||||
return lastActiveValue;
|
||||
}
|
||||
|
||||
public void setLastActiveValue(int lastActiveValue) {
|
||||
this.lastActiveValue = lastActiveValue;
|
||||
}
|
||||
|
||||
public boolean isRainSensor() {
|
||||
return rainSensor;
|
||||
}
|
||||
|
||||
public void setRainSensor(boolean rainSensor) {
|
||||
this.rainSensor = rainSensor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal.api;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainUdpResponse} is a encapsulation of the UDP broadcast response from the EtherRain
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class EtherRainUdpResponse {
|
||||
private final boolean valid;
|
||||
private final String type;
|
||||
private final String address;
|
||||
private final int port;
|
||||
private final String uniqueName;
|
||||
private final String additionalParameters; // Note: version 3.77 of spec says this is unused
|
||||
|
||||
public EtherRainUdpResponse(String type, String address, int port, String uniqueName, String additionalParameters) {
|
||||
this.valid = true;
|
||||
this.type = type;
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
this.uniqueName = uniqueName;
|
||||
this.additionalParameters = additionalParameters;
|
||||
}
|
||||
|
||||
public EtherRainUdpResponse() {
|
||||
this.valid = false;
|
||||
this.type = "";
|
||||
this.address = "";
|
||||
this.port = 0;
|
||||
this.uniqueName = "";
|
||||
this.additionalParameters = "";
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public String getUnqiueName() {
|
||||
return uniqueName;
|
||||
}
|
||||
|
||||
public String getAdditionalParameters() {
|
||||
return additionalParameters;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal.config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainConfiguration} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class EtherRainConfiguration {
|
||||
|
||||
public static final String BINDING_ID = "etherrrain";
|
||||
|
||||
public static final ThingTypeUID ETHERRAIN_THING_TYPE = new ThingTypeUID(BINDING_ID, "etherrain");
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(ETHERRAIN_THING_TYPE);
|
||||
|
||||
/**
|
||||
* Hostname of the EtherRain API.
|
||||
*/
|
||||
public String host = "";
|
||||
|
||||
/**
|
||||
* The port the EtherRain API is listening on.
|
||||
* Default: 80 per specification
|
||||
*/
|
||||
public int port = 80;
|
||||
|
||||
/**
|
||||
* The password to connect to the EtherRain API.
|
||||
* Default: pw per specification
|
||||
*/
|
||||
public String password = "pw";
|
||||
|
||||
/**
|
||||
* Number of seconds in between refreshes from the EtherRain device.
|
||||
*/
|
||||
public int refresh = 60;
|
||||
|
||||
/**
|
||||
* Default Delay for Program Timer
|
||||
*/
|
||||
public int programDelay = 0;
|
||||
|
||||
/**
|
||||
* Default Zone on times
|
||||
*/
|
||||
public int zoneOnTime1 = 0;
|
||||
public int zoneOnTime2 = 0;
|
||||
public int zoneOnTime3 = 0;
|
||||
public int zoneOnTime4 = 0;
|
||||
public int zoneOnTime5 = 0;
|
||||
public int zoneOnTime6 = 0;
|
||||
public int zoneOnTime7 = 0;
|
||||
public int zoneOnTime8 = 0;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal.discovery;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.etherrain.internal.EtherRainBindingConstants;
|
||||
import org.openhab.binding.etherrain.internal.api.EtherRainCommunication;
|
||||
import org.openhab.binding.etherrain.internal.api.EtherRainUdpResponse;
|
||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.config.discovery.DiscoveryService;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link EtherrainDiscoveryService} class discovers Etherrain Device(s) and places them in the inbox.
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = DiscoveryService.class, immediate = true, configurationPid = "discovery.etherrain")
|
||||
public class EtherrainDiscoveryService extends AbstractDiscoveryService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EtherrainDiscoveryService.class);
|
||||
|
||||
private static final int TIMEOUT = 15;
|
||||
|
||||
public EtherrainDiscoveryService() {
|
||||
super(EtherRainBindingConstants.SUPPORTED_THING_TYPES_UIDS, TIMEOUT, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ThingTypeUID> getSupportedThingTypes() {
|
||||
return EtherRainBindingConstants.SUPPORTED_THING_TYPES_UIDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startScan() {
|
||||
for (EtherRainUdpResponse rdp : EtherRainCommunication.autoDiscover()) {
|
||||
if (rdp.isValid()) {
|
||||
ThingUID uid = new ThingUID(EtherRainBindingConstants.ETHERRAIN_THING,
|
||||
rdp.getAddress().replaceAll("[^A-Za-z0-9\\-_]", ""));
|
||||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(uid)
|
||||
.withLabel("Etherrain " + rdp.getType() + " " + rdp.getUnqiueName())
|
||||
.withProperty("host", rdp.getAddress()).withProperty("port", rdp.getPort()).build();
|
||||
thingDiscovered(discoveryResult);
|
||||
} else {
|
||||
logger.debug("Nothing responded to request");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.etherrain.internal.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.etherrain.internal.EtherRainBindingConstants;
|
||||
import org.openhab.binding.etherrain.internal.EtherRainException;
|
||||
import org.openhab.binding.etherrain.internal.api.EtherRainCommunication;
|
||||
import org.openhab.binding.etherrain.internal.api.EtherRainStatusResponse;
|
||||
import org.openhab.binding.etherrain.internal.config.EtherRainConfiguration;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link EtherRainHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Joe Inkenbrandt - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EtherRainHandler extends BaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(EtherRainHandler.class);
|
||||
|
||||
private @Nullable EtherRainCommunication device = null;
|
||||
private boolean connected = false;
|
||||
private @NonNullByDefault({}) EtherRainConfiguration config = null;
|
||||
|
||||
private @Nullable ScheduledFuture<?> updateJob = null;
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
/*
|
||||
* Constructor class. Only call the parent constructor
|
||||
*/
|
||||
public EtherRainHandler(Thing thing, HttpClient httpClient) {
|
||||
super(thing);
|
||||
this.httpClient = httpClient;
|
||||
this.updateJob = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command == RefreshType.REFRESH) {
|
||||
scheduler.execute(this::updateBridge);
|
||||
} else if (channelUID.getId().equals(EtherRainBindingConstants.CHANNEL_ID_EXECUTE)) {
|
||||
execute();
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_EXECUTE, OnOffType.OFF);
|
||||
} else if (channelUID.getId().equals(EtherRainBindingConstants.CHANNEL_ID_CLEAR)) {
|
||||
clear();
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_CLEAR, OnOffType.OFF);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean connectBridge() {
|
||||
logger.debug("Attempting to connect to Etherrain with config = (Host: {}, Port: {}, Refresh: {}).", config.host,
|
||||
config.port, config.refresh);
|
||||
|
||||
EtherRainCommunication device = new EtherRainCommunication(config.host, config.port, config.password,
|
||||
httpClient);
|
||||
|
||||
try {
|
||||
device.commandStatus();
|
||||
} catch (EtherRainException | IOException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
||||
"Could not create a connection to the EtherRain");
|
||||
logger.debug("Could not open API connection to the EtherRain device. Exception received: {}",
|
||||
e.getMessage());
|
||||
this.device = null;
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
return false;
|
||||
}
|
||||
this.device = device;
|
||||
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void startUpdateJob() {
|
||||
logger.debug("Starting Etherrain Update Job");
|
||||
this.updateJob = scheduler.scheduleWithFixedDelay(this::updateBridge, 0, config.refresh, TimeUnit.SECONDS);
|
||||
|
||||
logger.debug("EtherRain sucessfully initialized. Starting status poll at: {}", config.refresh);
|
||||
}
|
||||
|
||||
private void stopUpdateJob() {
|
||||
logger.debug("Stopping Etherrain Update Job");
|
||||
|
||||
final ScheduledFuture<?> updateJob = this.updateJob;
|
||||
if (updateJob != null && !updateJob.isDone()) {
|
||||
updateJob.cancel(false);
|
||||
}
|
||||
|
||||
this.updateJob = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
private boolean updateBridge() {
|
||||
if (!connected || device == null) {
|
||||
connected = connectBridge();
|
||||
if (!connected || device == null) {
|
||||
connected = false;
|
||||
device = null;
|
||||
logger.debug("Could not connect to Etherrain device.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EtherRainStatusResponse response;
|
||||
|
||||
try {
|
||||
response = device.commandStatus();
|
||||
} catch (EtherRainException | IOException e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR,
|
||||
"Could not create a connection to the EtherRain");
|
||||
logger.debug("Could not open API connection to the EtherRain device. Exception received: {}",
|
||||
e.getMessage());
|
||||
device = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_STATUS,
|
||||
new StringType(response.getOperatingStatus().name()));
|
||||
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_COMMAND_STATUS,
|
||||
new StringType(response.getLastCommandStatus().name()));
|
||||
|
||||
switch (response.getLastCommandResult()) {
|
||||
case OK:
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_RESULT, new StringType("OK"));
|
||||
break;
|
||||
case RN:
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_RESULT, new StringType("RAIN INTERRUPTED"));
|
||||
break;
|
||||
case SH:
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_RESULT,
|
||||
new StringType("INTERRUPPTED SHORT"));
|
||||
break;
|
||||
case NC:
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_OPERATING_RESULT, new StringType("DID NOT COMPLETE"));
|
||||
break;
|
||||
}
|
||||
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_RELAY_INDEX, new DecimalType(response.getLastActiveValue()));
|
||||
|
||||
OnOffType rs = OnOffType.from(response.isRainSensor());
|
||||
|
||||
updateState(EtherRainBindingConstants.CHANNEL_ID_SENSOR_RAIN, rs);
|
||||
|
||||
logger.debug("Completed Etherrain Update");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private synchronized boolean execute() {
|
||||
EtherRainCommunication device = this.device;
|
||||
|
||||
if (device != null) {
|
||||
device.commandIrrigate(config.programDelay, config.zoneOnTime1, config.zoneOnTime2, config.zoneOnTime3,
|
||||
config.zoneOnTime4, config.zoneOnTime5, config.zoneOnTime6, config.zoneOnTime7, config.zoneOnTime8);
|
||||
updateBridge();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean clear() {
|
||||
EtherRainCommunication device = this.device;
|
||||
if (device != null) {
|
||||
device.commandClear();
|
||||
}
|
||||
|
||||
updateBridge();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
config = getConfigAs(EtherRainConfiguration.class);
|
||||
startUpdateJob();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
stopUpdateJob();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="etherrain"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
<name>EtherRain Binding</name>
|
||||
<description>This is the binding for EtherRain</description>
|
||||
<author>Joe Inkenbrandt</author>
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bindingId="etherrain"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<!-- The EtherRain Thing Type -->
|
||||
<thing-type id="etherrain">
|
||||
<label>EtherRain</label>
|
||||
<description>This is a stand alone EtherRain device that allows sprinkler control</description>
|
||||
|
||||
<channels>
|
||||
<channel id="commandstatus" typeId="commandstatus"/>
|
||||
<channel id="operatingstatus" typeId="operatingstatus"/>
|
||||
<channel id="operatingresult" typeId="operatingresult"/>
|
||||
|
||||
<channel id="relayindex" typeId="relayindex"/>
|
||||
<channel id="rainsensor" typeId="rainsensor"/>
|
||||
|
||||
<channel id="execute" typeId="execute">
|
||||
<label>Execute</label>
|
||||
<description>Commands EtherRain device to begin watering program</description>
|
||||
</channel>
|
||||
<channel id="clear" typeId="execute">
|
||||
<label>Clear</label>
|
||||
<description>Clears the currently running program</description>
|
||||
</channel>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="host" type="text" required="true">
|
||||
<label>Host Name</label>
|
||||
<description>The host name or IP address of the EtherRain Web API interface</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
<parameter name="port" type="integer" min="1" max="65335">
|
||||
<label>Port</label>
|
||||
<description>Port of the EtherRain Web API interface</description>
|
||||
<default>80</default>
|
||||
</parameter>
|
||||
<parameter name="password" type="text">
|
||||
<label>Password</label>
|
||||
<description>The admin password used to access the Web API interface</description>
|
||||
<default>pw</default>
|
||||
</parameter>
|
||||
<parameter name="refresh" type="integer">
|
||||
<label>Refresh</label>
|
||||
<description>The amount of time, in seconds, that openHAB should poll EtherRain</description>
|
||||
<default>60</default>
|
||||
</parameter>
|
||||
|
||||
<parameter name="programDelay" type="integer">
|
||||
<label>Program Delay</label>
|
||||
<description>The amount of time, in minutes, that EtherRain will delay before starting a program</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
<parameter name="zoneOnTime1" type="integer">
|
||||
<label>Zone 1 Run Time</label>
|
||||
<description>The amount of time, in minutes, that EtherRain will run zone 1 in program</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
<parameter name="zoneOnTime2" type="integer">
|
||||
<label>Zone 2 Run Time</label>
|
||||
<description>The amount of time, in minutes, that EtherRain will run zone 2 in program</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
<parameter name="zoneOnTime3" type="integer">
|
||||
<label>Zone 3 Run Time</label>
|
||||
<description>The amount of time, in minutes, that EtherRain will run zone 3 in program</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
<parameter name="zoneOnTime4" type="integer">
|
||||
<label>Zone 4 Run Time</label>
|
||||
<description>The amount of time, in minutes, that EtherRain will run zone 4 in program</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
<parameter name="zoneOnTime5" type="integer">
|
||||
<label>Zone 5 Run Time</label>
|
||||
<description>The amount of time, in minutes, that EtherRain will run zone 5 in program</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
<parameter name="zoneOnTime6" type="integer">
|
||||
<label>Zone 6 Run Time</label>
|
||||
<description>The amount of time, in minutes, that EtherRain will run zone 6 in program</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
<parameter name="zoneOnTime7" type="integer">
|
||||
<label>Zone 7 Run Time</label>
|
||||
<description>The amount of time, in minutes, that EtherRain will run zone 7 in program</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
<parameter name="zoneOnTime8" type="integer">
|
||||
<label>Zone 8 Run Time</label>
|
||||
<description>The amount of time, in minutes, that EtherRain will run zone 8 in program</description>
|
||||
<default>0</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="commandstatus">
|
||||
<item-type>String</item-type>
|
||||
<label>Command Status</label>
|
||||
<description>Status of the last command given to the Etherrain</description>
|
||||
<category>Water</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="operatingstatus">
|
||||
<item-type>String</item-type>
|
||||
<label>Operating Status</label>
|
||||
<description>Current operating status of the Etherrain</description>
|
||||
<category>Water</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="operatingresult">
|
||||
<item-type>String</item-type>
|
||||
<label>Operating Result</label>
|
||||
<description>Result of operating status</description>
|
||||
<category>Water</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="rainsensor">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Rain</label>
|
||||
<description>Provides feedback on whether the EtherRain device has detected rain or not</description>
|
||||
<category>Sensor</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="runtime">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Runtime</label>
|
||||
<description>How long a zone will run in seconds</description>
|
||||
<category>Number</category>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="relayindex">
|
||||
<item-type>Number</item-type>
|
||||
<label>Relay Index</label>
|
||||
<description>Number of the last zone that was operating</description>
|
||||
<category>Number</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="execute">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Execute</label>
|
||||
<description>Send a command to the EtherRain Controller</description>
|
||||
<category>Switch</category>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user