added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.autelis-${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-autelis" description="Autelis Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<feature>openhab-transport-upnp</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.autelis/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* 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.autelis.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link AutelisBinding} class defines common constants, which are used
|
||||
* across the whole binding.
|
||||
*
|
||||
* @author Dan Cunningham - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class AutelisBindingConstants {
|
||||
|
||||
public static final String BINDING_ID = "autelis";
|
||||
|
||||
// poolcontrol is here for backwards compatibility before we had separate things for jandy and pentair
|
||||
public static final ThingTypeUID POOLCONTROL_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "poolcontrol");
|
||||
public static final ThingTypeUID PENTAIR_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "pentair");
|
||||
public static final ThingTypeUID JANDY_THING_TYPE_UID = new ThingTypeUID(BINDING_ID, "jandy");
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.unmodifiableSet(Stream
|
||||
.of(POOLCONTROL_THING_TYPE_UID, PENTAIR_THING_TYPE_UID, JANDY_THING_TYPE_UID).collect(Collectors.toSet()));
|
||||
|
||||
public static final String CMD_LIGHTS = "lightscmd";
|
||||
public static final String CMD_REBOOT = "reboot";
|
||||
public static final String CMD_EQUIPMENT = "equipment";
|
||||
public static final String CMD_TEMP = "temp";
|
||||
public static final String CMD_CHEM = "chem";
|
||||
public static final String CMD_PUMPS = "pumps";
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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.autelis.internal;
|
||||
|
||||
import static org.openhab.binding.autelis.internal.AutelisBindingConstants.SUPPORTED_THING_TYPES_UIDS;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.autelis.internal.handler.AutelisHandler;
|
||||
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.Component;
|
||||
|
||||
/**
|
||||
* The {@link AutelisHandlerFactory} is responsible for creating things and
|
||||
* thing handlers.
|
||||
*
|
||||
* @author Dan Cunningham - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.autelis")
|
||||
public class AutelisHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
||||
return new AutelisHandler(thing);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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.autelis.internal.config;
|
||||
|
||||
/**
|
||||
* Configuration properties for connecting to a Autelis Controller
|
||||
*
|
||||
* @author Dan Cunningham - Initial contribution
|
||||
*
|
||||
*/
|
||||
public class AutelisConfiguration {
|
||||
|
||||
/**
|
||||
* Host of the Autelis controller
|
||||
*/
|
||||
public String host;
|
||||
/**
|
||||
* port of the Autelis controller
|
||||
*/
|
||||
public Integer port;
|
||||
|
||||
/**
|
||||
* user to us when connecting to the Autelis controller
|
||||
*/
|
||||
public String user;
|
||||
|
||||
/**
|
||||
* password to us when connecting to the Autelis controller
|
||||
*/
|
||||
public String password;
|
||||
|
||||
/**
|
||||
* Rate we poll for new data
|
||||
*/
|
||||
public Integer refresh;
|
||||
}
|
||||
@@ -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.autelis.internal.discovery;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.jupnp.model.meta.RemoteDevice;
|
||||
import org.openhab.binding.autelis.internal.AutelisBindingConstants;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||
import org.openhab.core.config.discovery.upnp.UpnpDiscoveryParticipant;
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* Discovery Service for Autelis Pool Controllers.
|
||||
*
|
||||
* @author Dan Cunningham - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true)
|
||||
public class AutelisDiscoveryParticipant implements UpnpDiscoveryParticipant {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(AutelisDiscoveryParticipant.class);
|
||||
|
||||
private static final String MANUFACTURER = "autelis";
|
||||
private static final String MODEL_PENTAIR = "pc100p";
|
||||
private static final String MODEL_JANDY = "pc100j";
|
||||
|
||||
@Override
|
||||
public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
|
||||
return AutelisBindingConstants.SUPPORTED_THING_TYPES_UIDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable DiscoveryResult createResult(RemoteDevice device) {
|
||||
ThingUID uid = getThingUID(device);
|
||||
if (uid != null) {
|
||||
Map<String, Object> properties = new HashMap<>(3);
|
||||
|
||||
URL url = device.getDetails().getBaseURL();
|
||||
String label = device.getDetails().getFriendlyName();
|
||||
int port = url.getPort() > 0 ? url.getPort() : 80;
|
||||
|
||||
properties.put("host", url.getHost());
|
||||
properties.put("user", "admin");
|
||||
properties.put("password", "admin");
|
||||
properties.put("port", new Integer(port));
|
||||
|
||||
DiscoveryResult result = DiscoveryResultBuilder.create(uid).withProperties(properties).withLabel(label)
|
||||
.build();
|
||||
|
||||
logger.debug("Created a DiscoveryResult for device '{}' with UDN '{}'",
|
||||
device.getDetails().getFriendlyName(), device.getIdentity().getUdn().getIdentifierString());
|
||||
return result;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ThingUID getThingUID(RemoteDevice device) {
|
||||
if (device.getDetails().getManufacturerDetails().getManufacturer() != null
|
||||
&& device.getDetails().getModelDetails().getModelNumber() != null) {
|
||||
logger.trace("UPNP {} : {}", device.getDetails().getManufacturerDetails().getManufacturer(),
|
||||
device.getDetails().getModelDetails().getModelNumber());
|
||||
if (device.getDetails().getManufacturerDetails().getManufacturer().toLowerCase().startsWith(MANUFACTURER)) {
|
||||
logger.debug("Autelis Pool Control Found at {}", device.getDetails().getBaseURL());
|
||||
String id = device.getIdentity().getUdn().getIdentifierString().replaceAll(":", "").toUpperCase();
|
||||
if (device.getDetails().getModelDetails().getModelNumber().toLowerCase().startsWith(MODEL_PENTAIR)) {
|
||||
return new ThingUID(AutelisBindingConstants.PENTAIR_THING_TYPE_UID, id);
|
||||
}
|
||||
if (device.getDetails().getModelDetails().getModelNumber().toLowerCase().startsWith(MODEL_JANDY)) {
|
||||
return new ThingUID(AutelisBindingConstants.JANDY_THING_TYPE_UID, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,554 @@
|
||||
/**
|
||||
* 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.autelis.internal.handler;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.openhab.binding.autelis.internal.AutelisBindingConstants;
|
||||
import org.openhab.binding.autelis.internal.config.AutelisConfiguration;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.IncreaseDecreaseType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Channel;
|
||||
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.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
*
|
||||
* Autelis Pool Control Binding
|
||||
*
|
||||
* Autelis controllers allow remote access to many common pool systems. This
|
||||
* binding allows openHAB to both monitor and control a pool system through
|
||||
* these controllers.
|
||||
*
|
||||
* @see <a href="http://Autelis.com">http://autelis.com</a>
|
||||
* @see <a href="http://www.autelis.com/wiki/index.php?title=Pool_Control_HTTP_Command_Reference"</a> for Jandy API
|
||||
* @see <a href="http://www.autelis.com/wiki/index.php?title=Pool_Control_(PI)_HTTP_Command_Reference"</a> for Pentair
|
||||
* API
|
||||
*
|
||||
* The {@link AutelisHandler} is responsible for handling commands, which
|
||||
* are sent to one of the channels.
|
||||
*
|
||||
* @author Dan Cunningham - Initial contribution
|
||||
* @author Svilen Valkanov - Replaced Apache HttpClient with Jetty
|
||||
*/
|
||||
public class AutelisHandler extends BaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(AutelisHandler.class);
|
||||
|
||||
/**
|
||||
* Default timeout for http connections to a Autelis controller
|
||||
*/
|
||||
static final int TIMEOUT_SECONDS = 5;
|
||||
|
||||
/**
|
||||
* Autelis controllers will not update their XML immediately after we change
|
||||
* a value. To compensate we cache previous values for a {@link Channel}
|
||||
* using the item name as a key. After a polling run has been executed we
|
||||
* only update an channel if the value is different then what's in the
|
||||
* cache. This cache is cleared after a fixed time period when commands are
|
||||
* sent.
|
||||
*/
|
||||
private Map<String, State> stateMap = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
/**
|
||||
* Clear our state every hour
|
||||
*/
|
||||
private static final int NORMAL_CLEARTIME_SECONDS = 60 * 60;
|
||||
|
||||
/**
|
||||
* Default poll rate rate, this is derived from the Autelis web UI
|
||||
*/
|
||||
private static final int DEFAULT_REFRESH_SECONDS = 3;
|
||||
|
||||
/**
|
||||
* How long should we wait to poll after we send an update, derived from trial and error
|
||||
*/
|
||||
private static final int COMMAND_UPDATE_TIME_SECONDS = 6;
|
||||
|
||||
/**
|
||||
* The autelis unit will 'loose' commands if sent to fast
|
||||
*/
|
||||
private static final int THROTTLE_TIME_MILLISECONDS = 500;
|
||||
|
||||
/**
|
||||
* Autelis web port
|
||||
*/
|
||||
private static final int WEB_PORT = 80;
|
||||
|
||||
/**
|
||||
* Pentair values for pump response
|
||||
*/
|
||||
private static final String[] PUMP_TYPES = { "watts", "rpm", "gpm", "filer", "error" };
|
||||
|
||||
/**
|
||||
* Matcher for pump channel names for Pentair
|
||||
*/
|
||||
private static final Pattern PUMPS_PATTERN = Pattern.compile("(pumps/pump\\d?)-(watts|rpm|gpm|filter|error)");
|
||||
|
||||
/**
|
||||
* Holds the next clear time in millis
|
||||
*/
|
||||
private long clearTime;
|
||||
|
||||
/**
|
||||
* Constructed URL consisting of host and port
|
||||
*/
|
||||
private String baseURL;
|
||||
|
||||
/**
|
||||
* Our poll rate
|
||||
*/
|
||||
private int refresh;
|
||||
|
||||
/**
|
||||
* The http client used for polling requests
|
||||
*/
|
||||
private HttpClient client = new HttpClient();
|
||||
|
||||
/**
|
||||
* last time we finished a request
|
||||
*/
|
||||
private long lastRequestTime = 0;
|
||||
|
||||
/**
|
||||
* Authentication for login
|
||||
*/
|
||||
private String basicAuthentication;
|
||||
|
||||
/**
|
||||
* Regex expression to match XML responses from the Autelis, this is used to
|
||||
* combine similar XML docs into a single document, {@link XPath} is still
|
||||
* used for XML querying
|
||||
*/
|
||||
private Pattern responsePattern = Pattern.compile("<response>(.+?)</response>", Pattern.DOTALL);
|
||||
|
||||
/**
|
||||
* Future to poll for updated
|
||||
*/
|
||||
private ScheduledFuture<?> pollFuture;
|
||||
|
||||
public AutelisHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
startHttpClient(client);
|
||||
configure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Handler disposed.");
|
||||
clearPolling();
|
||||
stopHttpClient(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelLinked(ChannelUID channelUID) {
|
||||
// clear our cached values so the new channel gets updated
|
||||
clearState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
logger.debug("handleCommand channel: {} command: {}", channelUID.getId(), command);
|
||||
if (AutelisBindingConstants.CMD_LIGHTS.equals(channelUID.getId())) {
|
||||
/*
|
||||
* lighting command possible values, but we will let anything
|
||||
* through. alloff, allon, csync, cset, cswim, party, romance,
|
||||
* caribbean, american, sunset, royalty, blue, green, red, white,
|
||||
* magenta, hold, recall
|
||||
*/
|
||||
getUrl(baseURL + "/lights.cgi?val=" + command.toString(), TIMEOUT_SECONDS);
|
||||
} else if (AutelisBindingConstants.CMD_REBOOT.equals(channelUID.getId()) && command == OnOffType.ON) {
|
||||
getUrl(baseURL + "/userreboot.cgi?do=true" + command.toString(), TIMEOUT_SECONDS);
|
||||
updateState(channelUID, OnOffType.OFF);
|
||||
} else {
|
||||
String[] args = channelUID.getId().split("-");
|
||||
if (args.length < 2) {
|
||||
logger.warn("Unown channel {} for command {}", channelUID, command);
|
||||
return;
|
||||
}
|
||||
String type = args[0];
|
||||
String name = args[1];
|
||||
|
||||
if (AutelisBindingConstants.CMD_EQUIPMENT.equals(type)) {
|
||||
String cmd = "value";
|
||||
int value;
|
||||
if (command == OnOffType.OFF) {
|
||||
value = 0;
|
||||
} else if (command == OnOffType.ON) {
|
||||
value = 1;
|
||||
} else if (command instanceof DecimalType) {
|
||||
value = ((DecimalType) command).intValue();
|
||||
if (!isJandy() && value >= 3) {
|
||||
// this is a autelis dim type. not sure what 2 does
|
||||
cmd = "dim";
|
||||
}
|
||||
} else {
|
||||
logger.error("command type {} is not supported", command);
|
||||
return;
|
||||
}
|
||||
String response = getUrl(baseURL + "/set.cgi?name=" + name + "&" + cmd + "=" + value, TIMEOUT_SECONDS);
|
||||
logger.debug("equipment set {} {} {} : result {}", name, cmd, value, response);
|
||||
} else if (AutelisBindingConstants.CMD_TEMP.equals(type)) {
|
||||
String value;
|
||||
if (command == IncreaseDecreaseType.INCREASE) {
|
||||
value = "up";
|
||||
} else if (command == IncreaseDecreaseType.DECREASE) {
|
||||
value = "down";
|
||||
} else if (command == OnOffType.OFF) {
|
||||
value = "0";
|
||||
} else if (command == OnOffType.ON) {
|
||||
value = "1";
|
||||
} else {
|
||||
value = command.toString();
|
||||
}
|
||||
|
||||
String cmd;
|
||||
// name ending in sp are setpoints, ht are heater?
|
||||
if (name.endsWith("sp")) {
|
||||
cmd = "temp";
|
||||
} else if (name.endsWith("ht")) {
|
||||
cmd = "hval";
|
||||
} else {
|
||||
logger.error("Unknown temp type {}", name);
|
||||
return;
|
||||
}
|
||||
String response = getUrl(baseURL + "/set.cgi?wait=1&name=" + name + "&" + cmd + "=" + value,
|
||||
TIMEOUT_SECONDS);
|
||||
logger.debug("temp set name:{} cmd:{} value:{} : result {}", name, cmd, value, response);
|
||||
} else if (AutelisBindingConstants.CMD_CHEM.equals(type)) {
|
||||
String response = getUrl(baseURL + "/set.cgi?name=" + name + "&chem=" + command.toString(),
|
||||
TIMEOUT_SECONDS);
|
||||
logger.debug("chlrp {} {}: result {}", name, command, response);
|
||||
} else if (AutelisBindingConstants.CMD_PUMPS.equals(type)) {
|
||||
String response = getUrl(baseURL + "/set.cgi?name=" + name + "&speed=" + command.toString(),
|
||||
TIMEOUT_SECONDS);
|
||||
logger.debug("pumps {} {}: result {}", name, command, response);
|
||||
} else {
|
||||
logger.error("Unsupported type {}", type);
|
||||
}
|
||||
}
|
||||
clearState(true);
|
||||
// reset the schedule for our next poll which at that time will reflect if our command was successful or not.
|
||||
initPolling(COMMAND_UPDATE_TIME_SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures this thing
|
||||
*/
|
||||
private void configure() {
|
||||
clearPolling();
|
||||
|
||||
AutelisConfiguration configuration = getConfig().as(AutelisConfiguration.class);
|
||||
Integer refreshOrNull = configuration.refresh;
|
||||
Integer portOrNull = configuration.port;
|
||||
String host = configuration.host;
|
||||
String username = configuration.user;
|
||||
String password = configuration.password;
|
||||
|
||||
if (StringUtils.isBlank(username)) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "username must not be empty");
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(password)) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "password must not be empty");
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(host)) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "hostname must not be empty");
|
||||
return;
|
||||
}
|
||||
|
||||
refresh = DEFAULT_REFRESH_SECONDS;
|
||||
if (refreshOrNull != null) {
|
||||
refresh = refreshOrNull.intValue();
|
||||
}
|
||||
|
||||
int port = WEB_PORT;
|
||||
if (portOrNull != null) {
|
||||
port = portOrNull.intValue();
|
||||
}
|
||||
|
||||
baseURL = "http://" + host + ":" + port;
|
||||
basicAuthentication = "Basic " + B64Code.encode(username + ":" + password, StringUtil.__ISO_8859_1);
|
||||
logger.debug("Autelius binding configured with base url {} and refresh period of {}", baseURL, refresh);
|
||||
|
||||
initPolling(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts/Restarts polling with an initial delay. This allows changes in the poll cycle for when commands are sent
|
||||
* and we need to poll sooner then the next refresh cycle.
|
||||
*/
|
||||
private synchronized void initPolling(int initalDelay) {
|
||||
clearPolling();
|
||||
pollFuture = scheduler.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
pollAutelisController();
|
||||
} catch (Exception e) {
|
||||
logger.debug("Exception during poll", e);
|
||||
}
|
||||
}, initalDelay, DEFAULT_REFRESH_SECONDS, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops/clears this thing's polling future
|
||||
*/
|
||||
private void clearPolling() {
|
||||
if (pollFuture != null && !pollFuture.isCancelled()) {
|
||||
logger.trace("Canceling future");
|
||||
pollFuture.cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll the Autelis controller for updates. This will retrieve various xml documents and update channel states from
|
||||
* its contents.
|
||||
*/
|
||||
private void pollAutelisController() {
|
||||
logger.trace("Connecting to {}", baseURL);
|
||||
|
||||
// clear our cached stated IF it is time.
|
||||
clearState(false);
|
||||
|
||||
// we will reconstruct the document with all the responses combined for XPATH
|
||||
StringBuilder sb = new StringBuilder("<response>");
|
||||
|
||||
// pull down the three xml documents
|
||||
String[] statuses = { "status", "chem", "pumps" };
|
||||
|
||||
for (String status : statuses) {
|
||||
String response = getUrl(baseURL + "/" + status + ".xml", TIMEOUT_SECONDS);
|
||||
logger.trace("{}/{}.xml \n {}", baseURL, status, response);
|
||||
if (response == null) {
|
||||
// all models and versions have the status.xml endpoint
|
||||
if (status.equals("status")) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR);
|
||||
return;
|
||||
} else {
|
||||
// not all models have the other endpoints, so we ignore errors
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// get the xml data between the response tags and append to our main
|
||||
// doc
|
||||
Matcher m = responsePattern.matcher(response);
|
||||
if (m.find()) {
|
||||
sb.append(m.group(1));
|
||||
}
|
||||
}
|
||||
// finish our "new" XML Document
|
||||
sb.append("</response>");
|
||||
|
||||
if (!ThingStatus.ONLINE.equals(getThing().getStatus())) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
/*
|
||||
* This xmlDoc will now contain the three XML documents we retrieved
|
||||
* wrapped in response tags for easier querying in XPath.
|
||||
*/
|
||||
HashMap<String, String> pumps = new HashMap<>();
|
||||
String xmlDoc = sb.toString();
|
||||
for (Channel channel : getThing().getChannels()) {
|
||||
String key = channel.getUID().getId().replaceFirst("-", "/");
|
||||
XPathFactory xpathFactory = XPathFactory.newInstance();
|
||||
XPath xpath = xpathFactory.newXPath();
|
||||
try {
|
||||
InputSource is = new InputSource(new StringReader(xmlDoc));
|
||||
String value = null;
|
||||
|
||||
/**
|
||||
* Work around for Pentair pumps. Rather then have child XML elements, the response rather uses commas
|
||||
* on the pump response to separate the different values like so:
|
||||
*
|
||||
* watts,rpm,gpm,filter,error
|
||||
*
|
||||
* Also, some pools will only report the first 3 out of the 5 values.
|
||||
*/
|
||||
|
||||
Matcher matcher = PUMPS_PATTERN.matcher(key);
|
||||
if (matcher.matches()) {
|
||||
if (!pumps.containsKey(key)) {
|
||||
String pumpValue = xpath.evaluate("response/" + matcher.group(1), is);
|
||||
String[] values = pumpValue.split(",");
|
||||
for (int i = 0; i < PUMP_TYPES.length; i++) {
|
||||
|
||||
// this will be something like pump/pump1-rpm
|
||||
String newKey = matcher.group(1) + '-' + PUMP_TYPES[i];
|
||||
|
||||
// some Pentair models only have the first 3 values
|
||||
if (i < values.length) {
|
||||
pumps.put(newKey, values[i]);
|
||||
} else {
|
||||
pumps.put(newKey, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
value = pumps.get(key);
|
||||
} else {
|
||||
value = xpath.evaluate("response/" + key, is);
|
||||
|
||||
// Convert pentair salt levels to PPM.
|
||||
if ("chlor/salt".equals(key)) {
|
||||
try {
|
||||
value = String.valueOf(Integer.parseInt(value) * 50);
|
||||
} catch (NumberFormatException ignored) {
|
||||
logger.debug("Failed to parse pentair salt level as integer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty((value))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
State state = toState(channel.getAcceptedItemType(), value);
|
||||
State oldState = stateMap.put(channel.getUID().getAsString(), state);
|
||||
if (!state.equals(oldState)) {
|
||||
logger.trace("updating channel {} with state {} (old state {})", channel.getUID(), state, oldState);
|
||||
updateState(channel.getUID(), state);
|
||||
}
|
||||
} catch (XPathExpressionException e) {
|
||||
logger.error("could not parse xml", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple logic to perform a authenticated GET request
|
||||
*
|
||||
* @param url
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
private synchronized String getUrl(String url, int timeout) {
|
||||
// throttle commands for a very short time to avoid 'loosing' them
|
||||
long now = System.currentTimeMillis();
|
||||
long nextReq = lastRequestTime + THROTTLE_TIME_MILLISECONDS;
|
||||
if (nextReq > now) {
|
||||
try {
|
||||
logger.trace("Throttling request for {} mills", nextReq - now);
|
||||
Thread.sleep(nextReq - now);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
String getURL = url + (url.contains("?") ? "&" : "?") + "timestamp=" + System.currentTimeMillis();
|
||||
logger.trace("Getting URL {} ", getURL);
|
||||
Request request = client.newRequest(getURL).timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
request.header(HttpHeader.AUTHORIZATION, basicAuthentication);
|
||||
try {
|
||||
ContentResponse response = request.send();
|
||||
int statusCode = response.getStatus();
|
||||
if (statusCode != HttpStatus.OK_200) {
|
||||
logger.trace("Method failed: {}", response.getStatus() + " " + response.getReason());
|
||||
return null;
|
||||
}
|
||||
lastRequestTime = System.currentTimeMillis();
|
||||
return response.getContentAsString();
|
||||
} catch (Exception e) {
|
||||
logger.debug("Could not make http connection", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link String} value to a {@link State} for a given
|
||||
* {@link String} accepted type
|
||||
*
|
||||
* @param itemType
|
||||
* @param value
|
||||
* @return {@link State}
|
||||
*/
|
||||
private State toState(String type, String value) throws NumberFormatException {
|
||||
if ("Number".equals(type)) {
|
||||
return new DecimalType(value);
|
||||
} else if ("Switch".equals(type)) {
|
||||
return Integer.parseInt(value) > 0 ? OnOffType.ON : OnOffType.OFF;
|
||||
} else {
|
||||
return StringType.valueOf(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears our state if it is time
|
||||
*/
|
||||
private void clearState(boolean force) {
|
||||
if (force || System.currentTimeMillis() >= clearTime) {
|
||||
stateMap.clear();
|
||||
clearTime = System.currentTimeMillis() + (NORMAL_CLEARTIME_SECONDS * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private void startHttpClient(HttpClient client) {
|
||||
if (!client.isStarted()) {
|
||||
try {
|
||||
client.start();
|
||||
} catch (Exception e) {
|
||||
logger.error("Could not stop HttpClient", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void stopHttpClient(HttpClient client) {
|
||||
if (client != null) {
|
||||
client.getAuthenticationStore().clearAuthentications();
|
||||
client.getAuthenticationStore().clearAuthenticationResults();
|
||||
if (client.isStarted()) {
|
||||
try {
|
||||
client.stop();
|
||||
} catch (Exception e) {
|
||||
logger.error("Could not stop HttpClient", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isJandy() {
|
||||
return getThing().getThingTypeUID() == AutelisBindingConstants.JANDY_THING_TYPE_UID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="autelis" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>Autelis Pool Control Binding</name>
|
||||
<description>This is the binding for a Autelis pool controller.</description>
|
||||
<author>Dan Cunningham</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,485 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="autelis"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="jandy">
|
||||
<label>Jandy Pool Controller</label>
|
||||
<description>A Jandy pool control thing represents a Autelis pool controller for Jandy systems</description>
|
||||
<channels>
|
||||
<channel id="system-runstate" typeId="system-runstate"/>
|
||||
<channel id="system-model" typeId="system-model"/>
|
||||
<channel id="system-dip" typeId="system-dip"/>
|
||||
<channel id="system-opmode" typeId="system-opmode"/>
|
||||
<channel id="system-vbat" typeId="system-vbat"/>
|
||||
<channel id="system-lowbat" typeId="system-lowbat"/>
|
||||
<channel id="system-time" typeId="system-time"/>
|
||||
<channel id="equipment-pump" typeId="equipment-switch">
|
||||
<label>Pump</label>
|
||||
<description>The current state of the pump</description>
|
||||
</channel>
|
||||
<channel id="equipment-pumplo" typeId="equipment-switch">
|
||||
<label>Lowspeed Pump</label>
|
||||
<description>The current state of the lowspeed pump</description>
|
||||
</channel>
|
||||
<channel id="equipment-spa" typeId="equipment-switch">
|
||||
<label>Spa Pump</label>
|
||||
<description>The current state of the spa pump</description>
|
||||
</channel>
|
||||
<channel id="equipment-waterfall" typeId="equipment-switch">
|
||||
<label>Waterfall Pump</label>
|
||||
<description>The current state of the waterfall pump</description>
|
||||
</channel>
|
||||
<channel id="equipment-cleaner" typeId="equipment-switch">
|
||||
<label>Cleaner Pump</label>
|
||||
<description>The current state of the cleaner pump</description>
|
||||
</channel>
|
||||
<channel id="equipment-poolht" typeId="equipment-ht">
|
||||
<label>Pool Heater</label>
|
||||
<description>The current state of the pool heater</description>
|
||||
</channel>
|
||||
<channel id="equipment-poolht2" typeId="equipment-ht">
|
||||
<label>Pool Heater @</label>
|
||||
<description>The current state of the pool heater 2</description>
|
||||
</channel>
|
||||
<channel id="equipment-spaht" typeId="equipment-ht">
|
||||
<label>Spa Heater</label>
|
||||
<description>The current state of the spa heater</description>
|
||||
</channel>
|
||||
<channel id="equipment-solarht" typeId="equipment-ht">
|
||||
<label>Solar Heater</label>
|
||||
<description>The current state of the solar heater</description>
|
||||
</channel>
|
||||
<channel id="equipment-htpmp" typeId="equipment-switch">
|
||||
<label>Heat Pump</label>
|
||||
<description>The current state of the heat pump</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux1" typeId="equipment-aux">
|
||||
<label>Auxiliary 1</label>
|
||||
<description>The current state of auxiliary 1</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux2" typeId="equipment-aux">
|
||||
<label>Auxiliary 2</label>
|
||||
<description>The current state of auxiliary 2</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux3" typeId="equipment-aux">
|
||||
<label>Auxiliary 3</label>
|
||||
<description>The current state of auxiliary 3</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux4" typeId="equipment-aux">
|
||||
<label>Auxiliary 4</label>
|
||||
<description>The current state of auxiliary 4</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux5" typeId="equipment-aux">
|
||||
<label>Auxiliary 5</label>
|
||||
<description>The current state of auxiliary 5</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux6" typeId="equipment-aux">
|
||||
<label>Auxiliary 6</label>
|
||||
<description>The current state of auxiliary 6</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux7" typeId="equipment-aux">
|
||||
<label>Auxiliary 7</label>
|
||||
<description>The current state of auxiliary 7</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux8" typeId="equipment-aux">
|
||||
<label>Auxiliary 8</label>
|
||||
<description>The current state of auxiliary 8</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux9" typeId="equipment-aux">
|
||||
<label>Auxiliary 9</label>
|
||||
<description>The current state of auxiliary 9</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux10" typeId="equipment-aux">
|
||||
<label>Auxiliary 10</label>
|
||||
<description>The current state of auxiliary 10</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux11" typeId="equipment-aux">
|
||||
<label>Auxiliary 11</label>
|
||||
<description>The current state of auxiliary 11</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux12" typeId="equipment-aux">
|
||||
<label>Auxiliary 12</label>
|
||||
<description>The current state of auxiliary 12</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux13" typeId="equipment-aux">
|
||||
<label>Auxiliary 13</label>
|
||||
<description>The current state of auxiliary 13</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux14" typeId="equipment-aux">
|
||||
<label>Auxiliary 14</label>
|
||||
<description>The current state of auxiliary 14</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux15" typeId="equipment-aux">
|
||||
<label>Auxiliary 15</label>
|
||||
<description>The current state of auxiliary 15</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux16" typeId="equipment-aux">
|
||||
<label>Auxiliary 16</label>
|
||||
<description>The current state of auxiliary 16</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux17" typeId="equipment-aux">
|
||||
<label>Auxiliary 17</label>
|
||||
<description>The current state of auxiliary 17</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux18" typeId="equipment-aux">
|
||||
<label>Auxiliary 18</label>
|
||||
<description>The current state of auxiliary 18</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux19" typeId="equipment-aux">
|
||||
<label>Auxiliary 19</label>
|
||||
<description>The current state of auxiliary 19</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux20" typeId="equipment-aux">
|
||||
<label>Auxiliary 20</label>
|
||||
<description>The current state of auxiliary 20</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux21" typeId="equipment-aux">
|
||||
<label>Auxiliary 21</label>
|
||||
<description>The current state of auxiliary 21</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux22" typeId="equipment-aux">
|
||||
<label>Auxiliary 22</label>
|
||||
<description>The current state of auxiliary 22</description>
|
||||
</channel>
|
||||
<channel id="equipment-aux23" typeId="equipment-aux">
|
||||
<label>Auxiliary 23</label>
|
||||
<description>The current state of auxiliary 23</description>
|
||||
</channel>
|
||||
<channel id="temp-poolsp" typeId="temp-sp">
|
||||
<label>Pool Setpoint</label>
|
||||
<description>The current pool setpoint</description>
|
||||
</channel>
|
||||
<channel id="temp-poolsp2" typeId="temp-sp">
|
||||
<label>Pool Setpoint 2</label>
|
||||
<description>The current pool setpoint 2</description>
|
||||
</channel>
|
||||
<channel id="temp-spasp" typeId="temp-sp">
|
||||
<label>Spa Setpoint</label>
|
||||
<description>The current spa setpoint</description>
|
||||
</channel>
|
||||
<channel id="temp-pooltemp" typeId="temp-temperature">
|
||||
<label>Pool Temperature</label>
|
||||
<description>The current pool temperature. Note: Only accurate when pool is running</description>
|
||||
</channel>
|
||||
<channel id="temp-spatemp" typeId="temp-temperature">
|
||||
<label>Spa Temperature</label>
|
||||
<description>The current spa temperature. Note: Only accurate when spa is running</description>
|
||||
</channel>
|
||||
<channel id="temp-airtemp" typeId="temp-temperature">
|
||||
<label>Air Temperature</label>
|
||||
<description>The current air temperature</description>
|
||||
</channel>
|
||||
<channel id="temp-solartemp" typeId="temp-temperature">
|
||||
<label>Solar Temperature</label>
|
||||
<description>The current solar temperature</description>
|
||||
</channel>
|
||||
<channel id="temp-tempunits" typeId="temp-tempunits"/>
|
||||
<channel id="pumps-vsp1" typeId="pumps-vsp1"/>
|
||||
<channel id="pumps-vsp2" typeId="pumps-vsp2"/>
|
||||
<channel id="pumps-vsp3" typeId="pumps-vsp3"/>
|
||||
<channel id="pumps-vsp4" typeId="pumps-vsp4"/>
|
||||
<channel id="chem-avail" typeId="chem-avail"/>
|
||||
<channel id="chem-chlrp" typeId="chem-chlrp"/>
|
||||
<channel id="chem-saltp" typeId="chem-saltp"/>
|
||||
<channel id="chem-chlrs" typeId="chem-chlrs"/>
|
||||
<channel id="chem-salts" typeId="chem-salts"/>
|
||||
<channel id="chem-orp1" typeId="chem-orp1"/>
|
||||
<channel id="chem-orp2" typeId="chem-orp2"/>
|
||||
<channel id="chem-ph1" typeId="chem-ph1"/>
|
||||
<channel id="chem-ph2" typeId="chem-ph2"/>
|
||||
<channel id="chem-orpfd1" typeId="chem-orpfd1"/>
|
||||
<channel id="chem-orpfd2" typeId="chem-orpfd2"/>
|
||||
<channel id="chem-phfd1" typeId="chem-phfd1"/>
|
||||
<channel id="chem-phfd2" typeId="chem-phfd2"/>
|
||||
<channel id="reboot" typeId="reboot"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="host" type="text" required="true">
|
||||
<context>network-address</context>
|
||||
<label>Host or IP</label>
|
||||
<description>The host name or IP address of the Autelis Controller.</description>
|
||||
</parameter>
|
||||
<parameter name="port" type="integer" min="1" max="65535" required="false">
|
||||
<context>network-address</context>
|
||||
<label>Port</label>
|
||||
<description>The port the Autelis Controller is listening on.</description>
|
||||
<default>80</default>
|
||||
</parameter>
|
||||
<parameter name="user" type="text" required="true">
|
||||
<label>User Name</label>
|
||||
<description>The user name to use when connecting to a Autelis Controller.</description>
|
||||
</parameter>
|
||||
<parameter name="password" type="text" required="true">
|
||||
<label>Password</label>
|
||||
<description>The password to use when connecting to a Autelis Controller.</description>
|
||||
</parameter>
|
||||
<parameter name="refresh" type="integer" required="false">
|
||||
<label>Refresh Interval</label>
|
||||
<description>Specifies the refresh interval in seconds</description>
|
||||
<default>5</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<!-- System Channels -->
|
||||
|
||||
<channel-type id="system-runstate" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Runstate</label>
|
||||
<description>The controller's runstate. 1 = Not Connected, 2-7 = Startup Initialization Sequence, 8 = Connected and
|
||||
Ready, 9-12 = Connected and Busy Executing Command
|
||||
</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-model" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Model</label>
|
||||
<description>The model number of the Aqualink® controller</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-dip" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Dip Switches</label>
|
||||
<description>The current state of the Aqualink® controller's dip switches. Possible values: 8 binary digits
|
||||
representing S1-S8 from left to right
|
||||
</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-opmode">
|
||||
<item-type>Number</item-type>
|
||||
<label>Operation Mode</label>
|
||||
<description>The current state of the Aqualink® controller</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="0">Auto</option>
|
||||
<option value="1">Service</option>
|
||||
<option value="2">Timeout</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-vbat">
|
||||
<item-type>Number</item-type>
|
||||
<label>Battery Voltage</label>
|
||||
<description>The voltage of the Aqualink® controller's battery</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-lowbat">
|
||||
<item-type>Number</item-type>
|
||||
<label>Battery State</label>
|
||||
<description>The current state of the Aqualink® controller's battery</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Normal</option>
|
||||
<option value="1">Low</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-version" advanced="true">
|
||||
<item-type>String</item-type>
|
||||
<label>Version</label>
|
||||
<description>The firmware version of the Pool Control device </description>
|
||||
</channel-type>
|
||||
<channel-type id="system-time" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Time</label>
|
||||
<description>The time as kept by the Pool Control device</description>
|
||||
</channel-type>
|
||||
|
||||
<!-- Equipment Channels -->
|
||||
|
||||
<channel-type id="equipment-switch">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Equipment Switch</label>
|
||||
<description>The current state of a equipment switch</description>
|
||||
</channel-type>
|
||||
<channel-type id="equipment-ht">
|
||||
<item-type>Number</item-type>
|
||||
<label>Heater</label>
|
||||
<description>The current state of the heater</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="0">Off</option>
|
||||
<option value="1">Enabled</option>
|
||||
<option value="2">On</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="equipment-aux">
|
||||
<item-type>Number</item-type>
|
||||
<label>Auxiliary</label>
|
||||
<description>The current state of auxiliary channel</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="0">Off</option>
|
||||
<option value="1">On</option>
|
||||
<option value="25">25%</option>
|
||||
<option value="50">50%</option>
|
||||
<option value="75">75%</option>
|
||||
<option value="100">100%</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<!-- Temperature Channels -->
|
||||
|
||||
<channel-type id="temp-sp">
|
||||
<item-type>Number</item-type>
|
||||
<label>Setpoint</label>
|
||||
<description>The current setpoint</description>
|
||||
<category>Temperature</category>
|
||||
</channel-type>
|
||||
<channel-type id="temp-temperature">
|
||||
<item-type>Number</item-type>
|
||||
<label>Temperature</label>
|
||||
<description>The current temperature. Note: Only accurate when pool is running</description>
|
||||
<category>Temperature</category>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="temp-airtemp">
|
||||
<item-type>Number</item-type>
|
||||
<label>Air Temperature</label>
|
||||
<description>The current air temperature</description>
|
||||
<category>Temperature</category>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="temp-tempunits" advanced="true">
|
||||
<item-type>String</item-type>
|
||||
<label>Temperature Units</label>
|
||||
<description>The selected units for temperature</description>
|
||||
<state>
|
||||
<options>
|
||||
<option value="F">Fahrenheit</option>
|
||||
<option value="C">Celsius</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<!-- Pump Channels -->
|
||||
|
||||
<channel-type id="pumps-vsp1">
|
||||
<item-type>String</item-type>
|
||||
<label>Pump 1</label>
|
||||
<description>Pump 1</description>
|
||||
</channel-type>
|
||||
<channel-type id="pumps-vsp2">
|
||||
<item-type>String</item-type>
|
||||
<label>Pump 2</label>
|
||||
<description>Pump 2</description>
|
||||
</channel-type>
|
||||
<channel-type id="pumps-vsp3">
|
||||
<item-type>String</item-type>
|
||||
<label>Pump 3</label>
|
||||
<description>Pump 3</description>
|
||||
</channel-type>
|
||||
<channel-type id="pumps-vsp4">
|
||||
<item-type>String</item-type>
|
||||
<label>Pump 4</label>
|
||||
<description>Pump 4</description>
|
||||
</channel-type>
|
||||
|
||||
<!-- Chem Channels -->
|
||||
|
||||
<channel-type id="chem-avail" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Equipment Is Available</label>
|
||||
<description>Indicates what equipment is available</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-chlrp" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pool Chlorination Setpoint</label>
|
||||
<description>Pool chlorination setpoint</description>
|
||||
</channel-type>
|
||||
<channel-type id="chem-saltp" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pool Salt Level</label>
|
||||
<description>Pool salt level</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-chlrs" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Spa Chlorination Setpoint</label>
|
||||
<description>Spa chlorination setpoint</description>
|
||||
</channel-type>
|
||||
<channel-type id="chem-salts" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Spa Salt Level</label>
|
||||
<description>Spa salt level</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-orp1" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>ORP Unit 1</label>
|
||||
<description>ORP reading from unit 1</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-orp2" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>ORP Unit 2</label>
|
||||
<description>ORP reading from unit 2</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-ph1" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>PH Unit 1</label>
|
||||
<description>PH reading from unit 1</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-ph2" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>PH Unit 2</label>
|
||||
<description>PH reading from unit 2</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-orpfd1" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>ORP Feed Unit 1</label>
|
||||
<description>ORP feed from unit 1</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-orpfd2" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>ORP Feed Unit 2</label>
|
||||
<description>ORP feed from unit 2</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-phfd1" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>PH Feed Unit 1</label>
|
||||
<description>PH feed from unit 1</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chem-phfd2" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>PH Feed Unit 2</label>
|
||||
<description>PH feed from unit 2</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<!-- Misc Channels -->
|
||||
|
||||
<channel-type id="reboot">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Reboot Autelis Device</label>
|
||||
<description>Reboots the Autelis device. This will not reboot any actual pool equipment.</description>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,507 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="autelis"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
<thing-type id="pentair">
|
||||
<label>Pentair Pool Controller</label>
|
||||
<description>A Pentair pool control thing represents an Autelis pool controller for Pentair systems</description>
|
||||
<channels>
|
||||
<channel id="system-runstate" typeId="system-runstate"/>
|
||||
<channel id="system-model" typeId="system-model"/>
|
||||
<channel id="system-haddr" typeId="system-haddr"/>
|
||||
<channel id="system-opmode" typeId="system-opmode"/>
|
||||
<channel id="system-freeze" typeId="system-freeze"/>
|
||||
<channel id="system-sensor1" typeId="system-sensor">
|
||||
<label>Sensor 1</label>
|
||||
<description>The state of sensor 1 (water sensor)</description>
|
||||
</channel>
|
||||
<channel id="system-sensor2" typeId="system-sensor">
|
||||
<label>Sensor 2</label>
|
||||
<description>The state of sensor 2 (water sensor)</description>
|
||||
</channel>
|
||||
<channel id="system-sensor3" typeId="system-sensor">
|
||||
<label>Sensor 3</label>
|
||||
<description>The state of sensor 3 (water sensor)</description>
|
||||
</channel>
|
||||
<channel id="system-sensor4" typeId="system-sensor">
|
||||
<label>Sensor 4</label>
|
||||
<description>The state of sensor 4 (water sensor)</description>
|
||||
</channel>
|
||||
<channel id="system-sensor5" typeId="system-sensor">
|
||||
<label>Sensor 5</label>
|
||||
<description>The state of sensor 5 (water sensor)</description>
|
||||
</channel>
|
||||
<channel id="system-version" typeId="system-version"/>
|
||||
<channel id="system-time" typeId="system-time"/>
|
||||
<channel id="equipment-circuit1" typeId="equipment-circuit">
|
||||
<label>Circuit 1</label>
|
||||
<description>The current state of circuit 1 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-circuit2" typeId="equipment-circuit">
|
||||
<label>Circuit 2</label>
|
||||
<description>The current state of circuit 2 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-circuit3" typeId="equipment-circuit">
|
||||
<label>Circuit 3</label>
|
||||
<description>The current state of circuit 3 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-circuit4" typeId="equipment-circuit">
|
||||
<label>Circuit 4</label>
|
||||
<description>The current state of circuit 4 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-circuit5" typeId="equipment-circuit">
|
||||
<label>Circuit 5</label>
|
||||
<description>The current state of circuit 5 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-circuit6" typeId="equipment-circuit">
|
||||
<label>Circuit 6</label>
|
||||
<description>The current state of circuit 6 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-circuit7" typeId="equipment-circuit">
|
||||
<label>Circuit 7</label>
|
||||
<description>The current state of circuit 7 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-circuit8" typeId="equipment-circuit">
|
||||
<label>Circuit 8</label>
|
||||
<description>The current state of circuit 8 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-circuit9" typeId="equipment-circuit">
|
||||
<label>Circuit 9</label>
|
||||
<description>The current state of circuit 9 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-circuit10" typeId="equipment-circuit">
|
||||
<label>Circuit 10</label>
|
||||
<description>The current state of circuit 10 (Spa or Lo-Temp)</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature1" typeId="equipment-feature">
|
||||
<label>Feature 1</label>
|
||||
<description>The current state of feature/macro 1</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature2" typeId="equipment-feature">
|
||||
<label>Feature 2</label>
|
||||
<description>The current state of feature/macro 2</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature3" typeId="equipment-feature">
|
||||
<label>Feature 3</label>
|
||||
<description>The current state of feature/macro 3</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature4" typeId="equipment-feature">
|
||||
<label>Feature 4</label>
|
||||
<description>The current state of feature/macro 4</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature5" typeId="equipment-feature">
|
||||
<label>Feature 5</label>
|
||||
<description>The current state of feature/macro 5</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature6" typeId="equipment-feature">
|
||||
<label>Feature 6</label>
|
||||
<description>The current state of feature/macro 6</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature7" typeId="equipment-feature">
|
||||
<label>Feature 7</label>
|
||||
<description>The current state of feature/macro 7</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature8" typeId="equipment-feature">
|
||||
<label>Feature 8</label>
|
||||
<description>The current state of feature/macro 8</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature9" typeId="equipment-feature">
|
||||
<label>Feature 9</label>
|
||||
<description>The current state of feature/macro 9</description>
|
||||
</channel>
|
||||
<channel id="equipment-feature10" typeId="equipment-feature">
|
||||
<label>Feature 10</label>
|
||||
<description>The current state of feature/macro 10</description>
|
||||
</channel>
|
||||
<channel id="temp-poolht" typeId="temp-ht">
|
||||
<label>Pool Heater Status</label>
|
||||
<description>The current pool/hi-temp heater settings</description>
|
||||
</channel>
|
||||
<channel id="temp-spaht" typeId="temp-ht">
|
||||
<label>Spa Heater Status</label>
|
||||
<description>The current spa/hi-temp heater settings</description>
|
||||
</channel>
|
||||
<channel id="temp-htstatus" typeId="temp-htstatus"/>
|
||||
<channel id="temp-poolsp" typeId="temp-poolsp"/>
|
||||
<channel id="temp-spasp" typeId="temp-spasp"/>
|
||||
<channel id="temp-pooltemp" typeId="temp-pooltemp"/>
|
||||
<channel id="temp-spatemp" typeId="temp-spatemp"/>
|
||||
<channel id="temp-airtemp" typeId="temp-airtemp"/>
|
||||
<channel id="temp-soltemp" typeId="temp-soltemp"/>
|
||||
<channel id="temp-tempunits" typeId="temp-tempunits"/>
|
||||
<channel id="temp-htpump" typeId="temp-htpump"/>
|
||||
<channel id="pumps-pump1" typeId="pumps-pump1"/>
|
||||
<channel id="pumps-pump1-watts" typeId="pumps-pump1-watts"/>
|
||||
<channel id="pumps-pump1-rpm" typeId="pumps-pump1-rpm"/>
|
||||
<channel id="pumps-pump1-gpm" typeId="pumps-pump1-gpm"/>
|
||||
<channel id="pumps-pump1-filter" typeId="pumps-pump1-filter"/>
|
||||
<channel id="pumps-pump1-error" typeId="pumps-pump1-error"/>
|
||||
<channel id="pumps-pump2" typeId="pumps-pump">
|
||||
<label>Pump 2</label>
|
||||
<description>Pump 2</description>
|
||||
</channel>
|
||||
<channel id="pumps-pump3" typeId="pumps-pump">
|
||||
<label>Pump 3</label>
|
||||
<description>Pump 3</description>
|
||||
</channel>
|
||||
<channel id="pumps-pump4" typeId="pumps-pump">
|
||||
<label>Pump 4</label>
|
||||
<description>Pump 4</description>
|
||||
</channel>
|
||||
<channel id="pumps-pump5" typeId="pumps-pump">
|
||||
<label>Pump 5</label>
|
||||
<description>Pump 5</description>
|
||||
</channel>
|
||||
<channel id="pumps-pump6" typeId="pumps-pump">
|
||||
<label>Pump 6</label>
|
||||
<description>Pump 6</description>
|
||||
</channel>
|
||||
<channel id="pumps-pump7" typeId="pumps-pump">
|
||||
<label>Pump 7</label>
|
||||
<description>Pump 7</description>
|
||||
</channel>
|
||||
<channel id="pumps-pump8" typeId="pumps-pump">
|
||||
<label>Pump 8</label>
|
||||
<description>Pump 8</description>
|
||||
</channel>
|
||||
<channel id="chlor-chloren" typeId="chlor-chloren"/>
|
||||
<channel id="chlor-poolsp" typeId="chlor-poolsp"/>
|
||||
<channel id="chlor-spasp" typeId="chlor-spasp"/>
|
||||
<channel id="chlor-salt" typeId="chlor-salt"/>
|
||||
<channel id="chlor-super" typeId="chlor-super"/>
|
||||
<channel id="chlor-chlorerr" typeId="chlor-chlorerr"/>
|
||||
<channel id="chlor-chlorname" typeId="chlor-chlorname"/>
|
||||
<channel id="lightscmd" typeId="lightscmd"/>
|
||||
<channel id="reboot" typeId="reboot"/>
|
||||
</channels>
|
||||
<config-description>
|
||||
<parameter name="host" type="text" required="true">
|
||||
<context>network-address</context>
|
||||
<label>Host or IP</label>
|
||||
<description>The host name or IP address of the Autelis Controller.</description>
|
||||
</parameter>
|
||||
<parameter name="port" type="integer" min="1" max="65535" required="false">
|
||||
<context>network-address</context>
|
||||
<label>Port</label>
|
||||
<description>The port the Autelis Controller is listening on.</description>
|
||||
<default>80</default>
|
||||
</parameter>
|
||||
<parameter name="user" type="text" required="true">
|
||||
<label>User Name</label>
|
||||
<description>The user name to use when connecting to a Autelis Controller.</description>
|
||||
</parameter>
|
||||
<parameter name="password" type="text" required="true">
|
||||
<label>Password</label>
|
||||
<description>The password to use when connecting to a Autelis Controller.</description>
|
||||
</parameter>
|
||||
<parameter name="refresh" type="integer" required="false">
|
||||
<label>Refresh Interval</label>
|
||||
<description>Specifies the refresh interval in seconds</description>
|
||||
<default>5</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<!-- System Channels -->
|
||||
|
||||
<channel-type id="system-runstate" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Runstate</label>
|
||||
<description>The controller's runstate. 1 = Starting Up, 2-49 = Getting Data, 50 = Ready</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-model" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Model</label>
|
||||
<description>The model of the Intellitouch® controller</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-haddr" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Hardware Address</label>
|
||||
<description>The controller's harware address</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-opmode">
|
||||
<item-type>Number</item-type>
|
||||
<label>Operation Mode</label>
|
||||
<description>The current state of the Intellitouch® controller</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Auto</option>
|
||||
<option value="1">Service/Timeout</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-freeze">
|
||||
<item-type>Number</item-type>
|
||||
<label>Freeze State</label>
|
||||
<description>The state of freeze protect</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">Off</option>
|
||||
<option value="1">On</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-sensor">
|
||||
<item-type>Number</item-type>
|
||||
<label>Sensor</label>
|
||||
<description>The state of a sensor (water sensor)</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="0">OK</option>
|
||||
<option value="1">ERROR</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="system-version" advanced="true">
|
||||
<item-type>String</item-type>
|
||||
<label>Version</label>
|
||||
<description>The firmware version of the Pool Control device </description>
|
||||
</channel-type>
|
||||
<channel-type id="system-time" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Time</label>
|
||||
<description>The time as kept by the Pool Control device</description>
|
||||
</channel-type>
|
||||
|
||||
<!-- Equipment Channels -->
|
||||
|
||||
<channel-type id="equipment-circuit">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Circuit 1</label>
|
||||
<description>The current state of a circuit (Spa or Lo-Temp)</description>
|
||||
</channel-type>
|
||||
<channel-type id="equipment-feature">
|
||||
<item-type>Number</item-type>
|
||||
<label>Feature</label>
|
||||
<description>The current state of a feature/macro</description>
|
||||
</channel-type>
|
||||
|
||||
<!-- Temperature Channels -->
|
||||
|
||||
<channel-type id="temp-ht">
|
||||
<item-type>Number</item-type>
|
||||
<label>Heater Status</label>
|
||||
<description>The current hi-temp heater settings</description>
|
||||
<category>Temperature</category>
|
||||
<state>
|
||||
<options>
|
||||
<option value="0">Off</option>
|
||||
<option value="1">Heater</option>
|
||||
<option value="2">Solar Preferred</option>
|
||||
<option value="3">Solar Only</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="temp-htstatus" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Heat Status</label>
|
||||
<description>Heat Status</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="temp-poolsp">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pool Heat Setpoint</label>
|
||||
<description>The current pool/hi-temp setpoint</description>
|
||||
<category>Temperature</category>
|
||||
</channel-type>
|
||||
<channel-type id="temp-spasp">
|
||||
<item-type>Number</item-type>
|
||||
<label>Spa Heat Setpoint</label>
|
||||
<description>The current spa/lo-temp setpoint</description>
|
||||
<category>Temperature</category>
|
||||
</channel-type>
|
||||
<channel-type id="temp-pooltemp">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pool Temp</label>
|
||||
<description>The current pool temperature. Note: Only accurate when pool is running</description>
|
||||
<category>Temperature</category>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="temp-spatemp">
|
||||
<item-type>Number</item-type>
|
||||
<label>Spa Temperature</label>
|
||||
<description>The current spa temperature. Note: Only accurate when spa is running</description>
|
||||
<category>Temperature</category>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="temp-airtemp">
|
||||
<item-type>Number</item-type>
|
||||
<label>Air Temperature</label>
|
||||
<description>The current temperature measured by the air sensor</description>
|
||||
<category>Temperature</category>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="temp-soltemp">
|
||||
<item-type>Number</item-type>
|
||||
<label>Solar Temperature</label>
|
||||
<description>The current temperature measured by the solar sensor</description>
|
||||
<category>Temperature</category>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="temp-tempunits" advanced="true">
|
||||
<item-type>String</item-type>
|
||||
<label>Temperature Units</label>
|
||||
<description>The selected units for temperature</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="F">Fahrenheit</option>
|
||||
<option value="C">Celsius</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="temp-htpump" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Heat Pump</label>
|
||||
<description>Heat Pump</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<!-- Pump Channels -->
|
||||
|
||||
<channel-type id="pumps-pump1" advanced="true">
|
||||
<item-type>String</item-type>
|
||||
<label>Pump 1</label>
|
||||
<description>Pump 1 raw value</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="pumps-pump1-watts">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pump 1 Watts</label>
|
||||
<description>Pump 1 watts</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="pumps-pump1-rpm">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pump 1 RPM</label>
|
||||
<description>Pump 1 RPM</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="pumps-pump1-gpm">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pump 1 GPM</label>
|
||||
<description>Pump 1 GPM</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="pumps-pump1-filter">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pump 1 Filter</label>
|
||||
<description>Pump 1</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="pumps-pump1-error">
|
||||
<item-type>Number</item-type>
|
||||
<label>Pump 1 Error</label>
|
||||
<description>Pump 1 error status</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="pumps-pump">
|
||||
<item-type>String</item-type>
|
||||
<label>Pump 2</label>
|
||||
<description>Pump 2</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<!-- Chem Channels -->
|
||||
|
||||
<channel-type id="chlor-chloren" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Chlorine</label>
|
||||
<description>Chlorine</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chlor-poolsp" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Chlorine Pool Setpoint</label>
|
||||
<description>Chlorine Pool Setpoint</description>
|
||||
</channel-type>
|
||||
<channel-type id="chlor-spasp" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Chlorine Spa Setpoint</label>
|
||||
<description>Chlorine Sap Setpoint</description>
|
||||
</channel-type>
|
||||
<channel-type id="chlor-salt">
|
||||
<item-type>Number</item-type>
|
||||
<label>Chlorine Salt Level</label>
|
||||
<description>Chlorine Salt Level</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chlor-super" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Chlorine Super Level</label>
|
||||
<description>Chlorine Super Level</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chlor-chlorerr" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Chlorine Error</label>
|
||||
<description>Chlorine Error value</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="chlor-chlorname" advanced="true">
|
||||
<item-type>String</item-type>
|
||||
<label>Chlorine Model Name</label>
|
||||
<description>Chlorine Model Name</description>
|
||||
<state readOnly="true">
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="lightscmd">
|
||||
<item-type>String</item-type>
|
||||
<label>Lighting Cmd</label>
|
||||
<description>Send A lighting command</description>
|
||||
<category>ColorLight</category>
|
||||
<state>
|
||||
<options>
|
||||
<option value="alloff">All Off</option>
|
||||
<option value="allon">All On</option>
|
||||
<option value="csync">C Sync</option>
|
||||
<option value="cset">C Set</option>
|
||||
<option value="cswim">C Swim</option>
|
||||
<option value="party">Party</option>
|
||||
<option value="romance">Romance</option>
|
||||
<option value="caribbean">Caribbean</option>
|
||||
<option value="american">American</option>
|
||||
<option value="sunset">Sunset</option>
|
||||
<option value="royalty">Royalty</option>
|
||||
<option value="blue">Blue</option>
|
||||
<option value="green">Green</option>
|
||||
<option value="red">Red</option>
|
||||
<option value="white">White</option>
|
||||
<option value="magenta">Magenta</option>
|
||||
<option value="hold">Hold</option>
|
||||
<option value="recall">Recall</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<!-- Misc Channels -->
|
||||
|
||||
<channel-type id="reboot">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Reboot Autelis Device</label>
|
||||
<description>Reboots the Autelis device. This will not reboot any actual pool equipment.</description>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user