mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-18 16:17:30 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09787fe08d | ||
|
|
37d346f558 | ||
|
|
ac59398aa0 | ||
|
|
87073435fc | ||
|
|
8687f3482a | ||
|
|
32a5f26ddd | ||
|
|
c28f07d628 | ||
|
|
d3cc961dfb | ||
|
|
1b3d826f28 | ||
|
|
c8f4d89a45 |
16
pom.xml
16
pom.xml
@@ -5,11 +5,11 @@
|
||||
|
||||
<groupId>com.bwssystems.HABridge</groupId>
|
||||
<artifactId>ha-bridge</artifactId>
|
||||
<version>1.2.3</version>
|
||||
<version>1.3.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>HA Bridge</name>
|
||||
<description>Emulates a Philips Hue bridge to allow the Amazon Echo to hook up to other HA systems, i.e. Vera or Harmony Hub, using lightweight frameworks</description>
|
||||
<description>Emulates a Philips Hue bridge to allow the Amazon Echo to hook up to other HA systems, i.e. Vera or Harmony Hub or Nest, using lightweight frameworks</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
@@ -30,6 +30,11 @@
|
||||
<artifactId>harmony-java-client</artifactId>
|
||||
<version>1.0.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.bwssytems</groupId>
|
||||
<artifactId>nest-controller</artifactId>
|
||||
<version>1.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sparkjava</groupId>
|
||||
<artifactId>spark-core</artifactId>
|
||||
@@ -38,8 +43,13 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.3.6</version>
|
||||
<version>4.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>4.4.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
|
||||
@@ -15,6 +15,9 @@ public class BridgeSettings {
|
||||
private boolean upnpstrict;
|
||||
private boolean traceupnp;
|
||||
private boolean devmode;
|
||||
private String nestuser;
|
||||
private String nestpwd;
|
||||
private boolean nestconfigured;
|
||||
|
||||
public String getUpnpConfigAddress() {
|
||||
return upnpconfigaddress;
|
||||
@@ -88,14 +91,32 @@ public class BridgeSettings {
|
||||
public void setDevMode(boolean devmode) {
|
||||
this.devmode = devmode;
|
||||
}
|
||||
public String getNestuser() {
|
||||
return nestuser;
|
||||
}
|
||||
public void setNestuser(String nestuser) {
|
||||
this.nestuser = nestuser;
|
||||
}
|
||||
public String getNestpwd() {
|
||||
return nestpwd;
|
||||
}
|
||||
public void setNestpwd(String nestpwd) {
|
||||
this.nestpwd = nestpwd;
|
||||
}
|
||||
public boolean isNestConfigured() {
|
||||
return nestconfigured;
|
||||
}
|
||||
public void setNestConfigured(boolean isNestConfigured) {
|
||||
this.nestconfigured = isNestConfigured;
|
||||
}
|
||||
public Boolean isValidVera() {
|
||||
if(this.veraaddress.contains(Configuration.DEFAULT_VERA_ADDRESS))
|
||||
if(this.veraaddress.contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
public Boolean isValidHarmony() {
|
||||
List<NamedIP> devicesList = this.harmonyaddress.getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_HARMONY_ADDRESS))
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
if(this.harmonypwd == null || this.harmonypwd == "")
|
||||
return false;
|
||||
@@ -103,4 +124,11 @@ public class BridgeSettings {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
public Boolean isValidNest() {
|
||||
if(this.nestpwd == null || this.nestpwd == "")
|
||||
return false;
|
||||
if(this.nestuser == null || this.nestuser == "")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,11 @@ public class Configuration {
|
||||
public final static String DEVICE_DB_DIRECTORY = "data/device.db";
|
||||
public final static String UPNP_RESPONSE_PORT = "50000";
|
||||
public final static String UPNP_RESPONSE_DEVICES = "30";
|
||||
public final static String DEFAULT_VERA_ADDRESS = "1.1.1.1";
|
||||
public final static String DEFAULT_HARMONY_ADDRESS = "1.1.1.1";
|
||||
public final static String DEFAULT_ADDRESS = "1.1.1.1";
|
||||
public final static String LOOP_BACK_ADDRESS = "127.0.0.1";
|
||||
public final static String LOOP_BACK_INTERFACE = "lo";
|
||||
public final static String DEFAULT_HARMONY_ADDRESS_LIST = "{devices:[{name:default,ip:1.1.1.1}]}";
|
||||
public final static String DEFAULT_HARMONY_USER = "";
|
||||
public final static String DEFAULT_HARMONY_PWD = "";
|
||||
public final static String DEFAULT_USER = "";
|
||||
public final static String DEFAULT_PWD = "";
|
||||
public final static String DFAULT_WEB_PORT = "8080";
|
||||
}
|
||||
|
||||
@@ -3,8 +3,11 @@ package com.bwssystems.HABridge;
|
||||
import static spark.Spark.*;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import org.apache.http.conn.util.InetAddressUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -12,6 +15,7 @@ import com.bwssystems.HABridge.devicemanagmeent.*;
|
||||
import com.bwssystems.HABridge.hue.HueMulator;
|
||||
import com.bwssystems.HABridge.upnp.UpnpListener;
|
||||
import com.bwssystems.HABridge.upnp.UpnpSettingsResource;
|
||||
import com.bwssystems.NestBridge.NestHome;
|
||||
import com.bwssystems.harmony.HarmonyHome;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
@@ -36,51 +40,77 @@ public class HABridge {
|
||||
Logger log = LoggerFactory.getLogger(HABridge.class);
|
||||
DeviceResource theResources;
|
||||
HarmonyHome harmonyHome;
|
||||
NestHome nestHome;
|
||||
HueMulator theHueMulator;
|
||||
UpnpSettingsResource theSettingResponder;
|
||||
UpnpListener theUpnpListener;
|
||||
InetAddress address;
|
||||
String addressString;
|
||||
InetAddress address = null;
|
||||
String addressString = null;
|
||||
BridgeSettings bridgeSettings;
|
||||
Version theVersion;
|
||||
|
||||
theVersion = new Version();
|
||||
|
||||
log.info("HA Bridge (v" + theVersion.getVersion() + ") starting setup....");
|
||||
//get ip address for upnp requests
|
||||
try {
|
||||
address = InetAddress.getLocalHost();
|
||||
addressString = address.getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
log.error("Cannot get ip address of this host, Exiting with message: " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
bridgeSettings = new BridgeSettings();
|
||||
bridgeSettings.setServerPort(System.getProperty("server.port", Configuration.DFAULT_WEB_PORT));
|
||||
bridgeSettings.setUpnpConfigAddress(System.getProperty("upnp.config.address", addressString));
|
||||
bridgeSettings.setUpnpConfigAddress(System.getProperty("upnp.config.address", Configuration.DEFAULT_ADDRESS));
|
||||
if(bridgeSettings.getUpnpConfigAddress().equalsIgnoreCase(Configuration.DEFAULT_ADDRESS)) {
|
||||
try {
|
||||
log.info("Getting an IP address for this host....");
|
||||
Enumeration<NetworkInterface> ifs = NetworkInterface.getNetworkInterfaces();
|
||||
|
||||
while (ifs.hasMoreElements() && addressString == null) {
|
||||
NetworkInterface xface = ifs.nextElement();
|
||||
Enumeration<InetAddress> addrs = xface.getInetAddresses();
|
||||
String name = xface.getName();
|
||||
int IPsPerNic = 0;
|
||||
|
||||
while (addrs.hasMoreElements() && IPsPerNic == 0) {
|
||||
address = addrs.nextElement();
|
||||
if (InetAddressUtils.isIPv4Address(address.getHostAddress())) {
|
||||
log.debug(name + " ... has IPV4 addr " + address);
|
||||
if(!name.equalsIgnoreCase(Configuration.LOOP_BACK_INTERFACE)|| !address.getHostAddress().equalsIgnoreCase(Configuration.LOOP_BACK_ADDRESS)) {
|
||||
IPsPerNic++;
|
||||
addressString = address.getHostAddress();
|
||||
log.info("Adding " + addressString + " from interface " + name + " as our default upnp config address.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SocketException e) {
|
||||
log.error("Cannot get ip address of this host, Exiting with message: " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
bridgeSettings.setUpnpConfigAddress(addressString);
|
||||
}
|
||||
|
||||
bridgeSettings.setUpnpDeviceDb(System.getProperty("upnp.device.db", Configuration.DEVICE_DB_DIRECTORY));
|
||||
bridgeSettings.setUpnpResponsePort(System.getProperty("upnp.response.port", Configuration.UPNP_RESPONSE_PORT));
|
||||
bridgeSettings.setVeraAddress(System.getProperty("vera.address", Configuration.DEFAULT_VERA_ADDRESS));
|
||||
bridgeSettings.setVeraAddress(System.getProperty("vera.address", Configuration.DEFAULT_ADDRESS));
|
||||
IpList theHarmonyList;
|
||||
|
||||
try {
|
||||
theHarmonyList = new Gson().fromJson(System.getProperty("harmony.address", Configuration.DEFAULT_HARMONY_ADDRESS_LIST), IpList.class);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
theHarmonyList = new Gson().fromJson("{devices:[{name:default,ip:" + System.getProperty("harmony.address", Configuration.DEFAULT_HARMONY_ADDRESS) + "}]}", IpList.class);
|
||||
theHarmonyList = new Gson().fromJson("{devices:[{name:default,ip:" + System.getProperty("harmony.address", Configuration.DEFAULT_ADDRESS) + "}]}", IpList.class);
|
||||
} catch (Exception et) {
|
||||
log.error("Cannot parse harmony.address, Exiting with message: " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bridgeSettings.setHarmonyAddress(theHarmonyList);
|
||||
bridgeSettings.setHarmonyUser(System.getProperty("harmony.user", Configuration.DEFAULT_HARMONY_USER));
|
||||
bridgeSettings.setHarmonyPwd(System.getProperty("harmony.pwd", Configuration.DEFAULT_HARMONY_PWD));
|
||||
bridgeSettings.setHarmonyUser(System.getProperty("harmony.user", Configuration.DEFAULT_USER));
|
||||
bridgeSettings.setHarmonyPwd(System.getProperty("harmony.pwd", Configuration.DEFAULT_PWD));
|
||||
bridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "true")));
|
||||
bridgeSettings.setTraceupnp(Boolean.parseBoolean(System.getProperty("trace.upnp", "false")));
|
||||
bridgeSettings.setDevMode(Boolean.parseBoolean(System.getProperty("dev.mode", "false")));
|
||||
bridgeSettings.setUpnpResponseDevices(Integer.parseInt(System.getProperty("upnp.response.devices", Configuration.UPNP_RESPONSE_DEVICES)));
|
||||
bridgeSettings.setNestuser(System.getProperty("nest.user", Configuration.DEFAULT_USER));
|
||||
bridgeSettings.setNestpwd(System.getProperty("nest.pwd", Configuration.DEFAULT_PWD));
|
||||
|
||||
// sparkjava config directive to set ip address for the web server to listen on
|
||||
// ipAddress("0.0.0.0"); // not used
|
||||
@@ -90,10 +120,12 @@ public class HABridge {
|
||||
staticFileLocation("/public");
|
||||
//setup the harmony connection if available
|
||||
harmonyHome = new HarmonyHome(bridgeSettings);
|
||||
//setup the nest connection if available
|
||||
nestHome = new NestHome(bridgeSettings);
|
||||
// setup the class to handle the resource setup rest api
|
||||
theResources = new DeviceResource(bridgeSettings, theVersion, harmonyHome);
|
||||
theResources = new DeviceResource(bridgeSettings, theVersion, harmonyHome, nestHome);
|
||||
// setup the class to handle the hue emulator rest api
|
||||
theHueMulator = new HueMulator(bridgeSettings, theResources.getDeviceRepository(), harmonyHome);
|
||||
theHueMulator = new HueMulator(bridgeSettings, theResources.getDeviceRepository(), harmonyHome, nestHome);
|
||||
theHueMulator.setupServer();
|
||||
// setup the class to handle the upnp response rest api
|
||||
theSettingResponder = new UpnpSettingsResource(bridgeSettings);
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.bwssystems.HABridge.JsonTransformer;
|
||||
import com.bwssystems.HABridge.Version;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.dao.DeviceRepository;
|
||||
import com.bwssystems.NestBridge.NestHome;
|
||||
import com.bwssystems.harmony.HarmonyHome;
|
||||
import com.bwssystems.luupRequests.Sdata;
|
||||
import com.bwssystems.vera.VeraInfo;
|
||||
@@ -36,15 +37,21 @@ public class DeviceResource {
|
||||
private VeraInfo veraInfo;
|
||||
private Version version;
|
||||
private HarmonyHome myHarmonyHome;
|
||||
private NestHome nestHome;
|
||||
private static final Set<String> supportedVerbs = new HashSet<>(Arrays.asList("get", "put", "post"));
|
||||
|
||||
public DeviceResource(BridgeSettings theSettings, Version theVersion, HarmonyHome theHarmonyHome) {
|
||||
public DeviceResource(BridgeSettings theSettings, Version theVersion, HarmonyHome theHarmonyHome, NestHome aNestHome) {
|
||||
this.deviceRepository = new DeviceRepository(theSettings.getUpnpDeviceDb());
|
||||
this.veraInfo = new VeraInfo(theSettings.getVeraAddress(), theSettings.isValidVera());
|
||||
if(theSettings.isValidHarmony())
|
||||
this.myHarmonyHome = theHarmonyHome;
|
||||
else
|
||||
this.myHarmonyHome = null;
|
||||
|
||||
if(theSettings.isValidNest())
|
||||
this.nestHome = aNestHome;
|
||||
else
|
||||
this.nestHome = null;
|
||||
this.version = theVersion;
|
||||
setupEndpoints();
|
||||
}
|
||||
@@ -218,5 +225,14 @@ public class DeviceResource {
|
||||
return myHarmonyHome.getDevices();
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/nest/items", "application/json", (request, response) -> {
|
||||
log.debug("Get nest items");
|
||||
if(nestHome == null) {
|
||||
response.status(HttpStatus.SC_NOT_FOUND);
|
||||
return null;
|
||||
}
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return nestHome.getItems();
|
||||
}, new JsonTransformer());
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,13 @@ import com.bwssystems.HABridge.api.hue.DeviceResponse;
|
||||
import com.bwssystems.HABridge.api.hue.DeviceState;
|
||||
import com.bwssystems.HABridge.api.hue.HueApiResponse;
|
||||
import com.bwssystems.HABridge.dao.*;
|
||||
import com.bwssystems.NestBridge.NestInstruction;
|
||||
import com.bwssystems.NestBridge.NestHome;
|
||||
import com.bwssystems.harmony.ButtonPress;
|
||||
import com.bwssystems.harmony.HarmonyHandler;
|
||||
import com.bwssystems.harmony.HarmonyHome;
|
||||
import com.bwssystems.harmony.RunActivity;
|
||||
import com.bwssystems.nest.controller.Nest;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
@@ -63,13 +66,14 @@ public class HueMulator {
|
||||
|
||||
private DeviceRepository repository;
|
||||
private HarmonyHome myHarmonyHome;
|
||||
private Nest theNest;
|
||||
private HttpClient httpClient;
|
||||
private ObjectMapper mapper;
|
||||
private BridgeSettings bridgeSettings;
|
||||
private byte[] sendData;
|
||||
|
||||
|
||||
public HueMulator(BridgeSettings theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome){
|
||||
public HueMulator(BridgeSettings theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome, NestHome aNestHome){
|
||||
httpClient = HttpClients.createDefault();
|
||||
mapper = new ObjectMapper(); //armzilla: work around Echo incorrect content type and breaking mapping. Map manually
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
@@ -78,6 +82,10 @@ public class HueMulator {
|
||||
this.myHarmonyHome = theHarmonyHome;
|
||||
else
|
||||
this.myHarmonyHome = null;
|
||||
if(theBridgeSettings.isValidNest())
|
||||
this.theNest = aNestHome.getTheNest();
|
||||
else
|
||||
this.theNest = null;
|
||||
bridgeSettings = theBridgeSettings;
|
||||
}
|
||||
|
||||
@@ -313,7 +321,7 @@ public class HueMulator {
|
||||
|
||||
if(device.getDeviceType().toLowerCase().contains("activity") || (device.getMapType() != null && device.getMapType().equalsIgnoreCase("harmonyActivity")))
|
||||
{
|
||||
log.debug("executing activity to Harmony: " + url);
|
||||
log.debug("executing HUE api request to change activity to Harmony: " + url);
|
||||
RunActivity anActivity = new Gson().fromJson(url, RunActivity.class);
|
||||
HarmonyHandler myHarmony = myHarmonyHome.getHarmonyHandler(device.getTargetDevice());
|
||||
if(myHarmony == null)
|
||||
@@ -326,7 +334,7 @@ public class HueMulator {
|
||||
}
|
||||
else if(device.getDeviceType().toLowerCase().contains("button") || (device.getMapType() != null && device.getMapType().equalsIgnoreCase("harmonyButton")))
|
||||
{
|
||||
log.debug("executing button press to Harmony: " + url);
|
||||
log.debug("executing HUE api request to button press to Harmony: " + url);
|
||||
ButtonPress aDeviceButton = new Gson().fromJson(url, ButtonPress.class);
|
||||
HarmonyHandler myHarmony = myHarmonyHome.getHarmonyHandler(device.getTargetDevice());
|
||||
if(myHarmony == null)
|
||||
@@ -337,8 +345,52 @@ public class HueMulator {
|
||||
else
|
||||
myHarmony.pressButton(aDeviceButton);
|
||||
}
|
||||
else if(device.getDeviceType().toLowerCase().contains("home") || (device.getMapType() != null && device.getMapType().equalsIgnoreCase("nestHomeAway")))
|
||||
{
|
||||
log.debug("executing HUE api request to set away for nest home: " + url);
|
||||
NestInstruction homeAway = new Gson().fromJson(url, NestInstruction.class);
|
||||
if(theNest == null)
|
||||
{
|
||||
log.warn("Should not get here, no Nest available");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + ",\"description\": \"Should not get here, no Nest available\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
|
||||
}
|
||||
else
|
||||
theNest.getHome(homeAway.getName()).setAway(homeAway.getAway());
|
||||
}
|
||||
else if(device.getDeviceType().toLowerCase().contains("thermo") || (device.getMapType() != null && device.getMapType().equalsIgnoreCase("nestThermoSet")))
|
||||
{
|
||||
log.debug("executing HUE api request to set thermostat for nest: " + url);
|
||||
NestInstruction thermoSetting = new Gson().fromJson(url, NestInstruction.class);
|
||||
if(theNest == null)
|
||||
{
|
||||
log.warn("Should not get here, no Nest available");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + ",\"description\": \"Should not get here, no Nest available\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
|
||||
}
|
||||
else {
|
||||
if(thermoSetting.getControl().equalsIgnoreCase("temp")) {
|
||||
if(request.body().contains("bri")) {
|
||||
thermoSetting.setTemp(String.valueOf(Math.round((Integer.parseInt(replaceIntensityValue(thermoSetting.getTemp(), state.getBri())) - 32)/1.8)));
|
||||
log.debug("Setting thermostat: " + thermoSetting.getName() + " to " + thermoSetting.getTemp() + "C");
|
||||
theNest.getThermostat(thermoSetting.getName()).setTargetTemperature(Float.parseFloat(thermoSetting.getTemp()));
|
||||
}
|
||||
}
|
||||
else if (thermoSetting.getControl().contains("range") ||thermoSetting.getControl().contains("heat") ||thermoSetting.getControl().contains("cool") ||thermoSetting.getControl().contains("off")) {
|
||||
log.debug("Setting thermostat target type: " + thermoSetting.getName() + " to " + thermoSetting.getControl());
|
||||
theNest.getThermostat(thermoSetting.getName()).setTargetType(thermoSetting.getControl());
|
||||
}
|
||||
else if(thermoSetting.getControl().contains("fan")) {
|
||||
log.debug("Setting thermostat fan mode: " + thermoSetting.getName() + " to " + thermoSetting.getControl().substring(4));
|
||||
theNest.getThermostat(thermoSetting.getName()).setFanMode(thermoSetting.getControl().substring(4));
|
||||
}
|
||||
else {
|
||||
log.warn("no valid Nest control info: " + thermoSetting.getControl());
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + ",\"description\": \"no valid Nest control info\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(url.startsWith("udp://"))
|
||||
{
|
||||
log.debug("executing HUE api request to UDP: " + url);
|
||||
try {
|
||||
String intermediate = url.substring(6);
|
||||
String ipAddr = intermediate.substring(0, intermediate.indexOf(':'));
|
||||
@@ -361,7 +413,7 @@ public class HueMulator {
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("executing activity to Http " + (device.getHttpVerb() == null?"GET":device.getHttpVerb()) + ": " + url);
|
||||
log.debug("executing HUE api request to Http " + (device.getHttpVerb() == null?"GET":device.getHttpVerb()) + ": " + url);
|
||||
// quick template
|
||||
String body;
|
||||
url = replaceIntensityValue(url, state.getBri());
|
||||
@@ -412,7 +464,8 @@ public class HueMulator {
|
||||
request = request.replace(INTENSITY_MATH + mathDescriptor + INTENSITY_MATH_CLOSE, endResult.toString());
|
||||
} catch (Exception e) {
|
||||
log.warn("Could not execute Math: " + mathDescriptor, e);
|
||||
} }
|
||||
}
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ public class UpnpSettingsResource {
|
||||
this.theSettings.setUpnpResponsePort(theBridgeSettings.getUpnpResponsePort());
|
||||
this.theSettings.setUpnpStrict(theBridgeSettings.isUpnpStrict());
|
||||
this.theSettings.setVeraAddress(theBridgeSettings.getVeraAddress());
|
||||
this.theSettings.setNestConfigured(theBridgeSettings.isValidNest());
|
||||
}
|
||||
|
||||
public void setupServer() {
|
||||
|
||||
101
src/main/java/com/bwssystems/NestBridge/NestHome.java
Normal file
101
src/main/java/com/bwssystems/NestBridge/NestHome.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package com.bwssystems.NestBridge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettings;
|
||||
import com.bwssystems.nest.controller.Home;
|
||||
import com.bwssystems.nest.controller.Nest;
|
||||
import com.bwssystems.nest.controller.NestSession;
|
||||
import com.bwssystems.nest.controller.Thermostat;
|
||||
import com.bwssystems.nest.protocol.error.LoginException;
|
||||
import com.bwssystems.nest.protocol.status.WhereDetail;
|
||||
import com.bwssystems.nest.protocol.status.WhereItem;
|
||||
|
||||
public class NestHome {
|
||||
private static final Logger log = LoggerFactory.getLogger(NestHome.class);
|
||||
private NestSession theSession;
|
||||
private Nest theNest;
|
||||
private ArrayList<NestItem> nestItems;
|
||||
|
||||
public NestHome(BridgeSettings bridgeSettings) {
|
||||
theSession = null;
|
||||
theNest = null;
|
||||
nestItems = null;
|
||||
|
||||
if(!bridgeSettings.isValidNest()) {
|
||||
log.info("not a valid nest");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
theSession = new NestSession(bridgeSettings.getNestuser(), bridgeSettings.getNestpwd());
|
||||
theNest = new Nest(theSession);
|
||||
} catch (LoginException e) {
|
||||
log.error("Caught Login Exception, exiting....");
|
||||
theSession = null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<NestItem> getItems() {
|
||||
if(theNest == null)
|
||||
return null;
|
||||
|
||||
if(nestItems == null) {
|
||||
nestItems = new ArrayList<NestItem>();
|
||||
Set<String> homeNames = theNest.getHomeNames();
|
||||
Home aHome = null;
|
||||
NestItem anItem = null;
|
||||
for(String name : homeNames) {
|
||||
aHome = theNest.getHome(name);
|
||||
anItem = new NestItem();
|
||||
anItem.setId(name);
|
||||
anItem.setName(aHome.getDetail().getName());
|
||||
anItem.setType("Home");
|
||||
anItem.setLocation(aHome.getDetail().getLocation());
|
||||
nestItems.add(anItem);
|
||||
}
|
||||
Thermostat thermo = null;
|
||||
Set<String> thermoNames = theNest.getThermostatNames();
|
||||
for(String name : thermoNames) {
|
||||
thermo = theNest.getThermostat(name);
|
||||
anItem = new NestItem();
|
||||
anItem.setId(name);
|
||||
anItem.setType("Thermostat");
|
||||
String where = null;
|
||||
String homeName= null;
|
||||
Boolean found = false;
|
||||
for(String aHomeName : homeNames) {
|
||||
WhereDetail aDetail = theNest.getWhere(aHomeName);
|
||||
ListIterator<WhereItem> anIterator = aDetail.getWheres().listIterator();
|
||||
while(anIterator.hasNext()) {
|
||||
WhereItem aWhereItem = (WhereItem) anIterator.next();
|
||||
if(aWhereItem.getWhereId().equals(thermo.getDeviceDetail().getWhereId())) {
|
||||
where = aWhereItem.getName();
|
||||
homeName = theNest.getHome(aHomeName).getDetail().getName();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
break;
|
||||
}
|
||||
anItem.setName(where + "(" + name.substring(name.length() - 4) + ")");
|
||||
anItem.setLocation(where + " - " + homeName);
|
||||
nestItems.add(anItem);
|
||||
}
|
||||
}
|
||||
|
||||
return nestItems;
|
||||
}
|
||||
|
||||
public Nest getTheNest() {
|
||||
return theNest;
|
||||
}
|
||||
}
|
||||
|
||||
33
src/main/java/com/bwssystems/NestBridge/NestInstruction.java
Normal file
33
src/main/java/com/bwssystems/NestBridge/NestInstruction.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.bwssystems.NestBridge;
|
||||
|
||||
public class NestInstruction {
|
||||
private String name;
|
||||
private Boolean away;
|
||||
private String control;
|
||||
private String temp;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public Boolean getAway() {
|
||||
return away;
|
||||
}
|
||||
public void setAway(Boolean away) {
|
||||
this.away = away;
|
||||
}
|
||||
public String getControl() {
|
||||
return control;
|
||||
}
|
||||
public void setControl(String control) {
|
||||
this.control = control;
|
||||
}
|
||||
public String getTemp() {
|
||||
return temp;
|
||||
}
|
||||
public void setTemp(String temp) {
|
||||
this.temp = temp;
|
||||
}
|
||||
}
|
||||
32
src/main/java/com/bwssystems/NestBridge/NestItem.java
Normal file
32
src/main/java/com/bwssystems/NestBridge/NestItem.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package com.bwssystems.NestBridge;
|
||||
|
||||
public class NestItem {
|
||||
private String name;
|
||||
private String id;
|
||||
private String type;
|
||||
private String location;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(String anid) {
|
||||
id = anid;
|
||||
}
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,9 @@ app.config(function ($routeProvider) {
|
||||
}).when('/harmonyactivities', {
|
||||
templateUrl: 'views/harmonyactivity.html',
|
||||
controller: 'AddingController'
|
||||
}).when('/nest', {
|
||||
templateUrl: 'views/nestactions.html',
|
||||
controller: 'AddingController'
|
||||
}).otherwise({
|
||||
templateUrl: 'views/configuration.html',
|
||||
controller: 'ViewingController'
|
||||
@@ -34,6 +37,7 @@ app.run( function (bridgeService) {
|
||||
bridgeService.loadBridgeSettings();
|
||||
bridgeService.updateShowVera();
|
||||
bridgeService.updateShowHarmony();
|
||||
bridgeService.updateShowNest();
|
||||
bridgeService.getHABridgeVersion();
|
||||
});
|
||||
|
||||
@@ -49,6 +53,7 @@ app.factory('BridgeSettings', function() {
|
||||
BridgeSettings.upnpstrict = "";
|
||||
BridgeSettings.traceupnp = "";
|
||||
BridgeSettings.devmode = "";
|
||||
BridgeSettings.nestconfigured = "";
|
||||
|
||||
BridgeSettings.setupnpconfigaddress = function(aconfigaddress){
|
||||
BridgeSettings.upnpconfigaddress = aconfigaddress;
|
||||
@@ -82,13 +87,17 @@ app.factory('BridgeSettings', function() {
|
||||
BridgeSettings.devmode = adevmode;
|
||||
};
|
||||
|
||||
BridgeSettings.setnestconfigured = function(anestconfigured){
|
||||
BridgeSettings.nestconfigured = anestconfigured;
|
||||
};
|
||||
|
||||
return BridgeSettings;
|
||||
});
|
||||
|
||||
app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
||||
var self = this;
|
||||
self.BridgeSettings = BridgeSettings;
|
||||
this.state = {base: window.location.origin + "/api/devices", upnpbase: window.location.origin + "/upnp/settings", huebase: window.location.origin + "/api", devices: [], device: [], error: "", showVera: false, showHarmony: false, habridgeversion: ""};
|
||||
this.state = {base: window.location.origin + "/api/devices", upnpbase: window.location.origin + "/upnp/settings", huebase: window.location.origin + "/api", devices: [], device: [], error: "", showVera: false, showHarmony: false, showNest: false, habridgeversion: ""};
|
||||
|
||||
this.viewDevices = function () {
|
||||
this.state.error = "";
|
||||
@@ -136,6 +145,14 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateShowNest = function () {
|
||||
if(self.BridgeSettings.nestconfigured == true)
|
||||
this.state.showNest = true;
|
||||
else
|
||||
this.state.showNest = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateShowHarmony = function () {
|
||||
if(self.BridgeSettings.harmonyaddress.devices) {
|
||||
if(this.aContainsB(self.BridgeSettings.harmonyaddress.devices[0].ip, "1.1.1.1") || self.BridgeSettings.harmonyaddress == "" || self.BridgeSettings.harmonyaddress == null)
|
||||
@@ -162,6 +179,7 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
||||
self.BridgeSettings.settraceupnp(response.data.traceupnp);
|
||||
self.BridgeSettings.setupnpstrict(response.data.upnpstrict);
|
||||
self.BridgeSettings.setdevmode(response.data.devmode);
|
||||
self.BridgeSettings.setnestconfigured(response.data.nestconfigured);
|
||||
},
|
||||
function (error) {
|
||||
if (error.data) {
|
||||
@@ -174,6 +192,25 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
||||
);
|
||||
};
|
||||
|
||||
this.viewNestItems = function () {
|
||||
this.state.error = "";
|
||||
if(!this.state.showNest)
|
||||
return;
|
||||
this.state.error = "";
|
||||
return $http.get(this.state.base + "/nest/items").then(
|
||||
function (response) {
|
||||
self.state.nestitems = response.data;
|
||||
},
|
||||
function (error) {
|
||||
if (error.data) {
|
||||
$window.alert("Get Nest Items Error: " + error.data.message);
|
||||
} else {
|
||||
$window.alert("Get Nest Items Error: unknown");
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
this.viewVeraDevices = function () {
|
||||
this.state.error = "";
|
||||
if(!this.state.showVera)
|
||||
@@ -255,6 +292,14 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
||||
return false;
|
||||
};
|
||||
|
||||
this.findNestItemByMapId = function(id, type) {
|
||||
for(var i = 0; i < this.state.devices.length; i++) {
|
||||
if(this.state.devices[i].mapId == id && this.aContainsB(this.state.devices[i].mapType, type))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
this.addDevice = function (device) {
|
||||
this.state.error = "";
|
||||
if(device.httpVerb != null && device.httpVerb != "")
|
||||
@@ -333,7 +378,7 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
||||
|
||||
this.deleteDeviceByMapId = function (id, type) {
|
||||
for(var i = 0; i < this.state.devices.length; i++) {
|
||||
if(this.state.devices[i].mapId == id && this.state.devices[i].mapType == type)
|
||||
if(this.state.devices[i].mapId == id && this.aContainsB(this.state.devices[i].mapType, type))
|
||||
return self.deleteDevice(this.state.devices[i].id);
|
||||
}
|
||||
};
|
||||
@@ -375,6 +420,7 @@ app.controller('ViewingController', function ($scope, $location, $http, $window,
|
||||
$scope.bridge = bridgeService.state;
|
||||
bridgeService.updateShowVera();
|
||||
bridgeService.updateShowHarmony();
|
||||
bridgeService.updateShowNest();
|
||||
$scope.visible = false;
|
||||
$scope.imgUrl = "glyphicon glyphicon-plus";
|
||||
$scope.predicate = '';
|
||||
@@ -419,9 +465,11 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
|
||||
bridgeService.viewVeraScenes();
|
||||
bridgeService.viewHarmonyActivities();
|
||||
bridgeService.viewHarmonyDevices();
|
||||
bridgeService.viewNestItems();
|
||||
$scope.bridge = bridgeService.state;
|
||||
bridgeService.updateShowVera();
|
||||
bridgeService.updateShowHarmony();
|
||||
bridgeService.updateShowNest();
|
||||
$scope.device = bridgeService.state.device;
|
||||
$scope.activitiesVisible = false;
|
||||
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||
@@ -535,6 +583,69 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
|
||||
$scope.device.offUrl = "{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + offbutton + "\"}";
|
||||
};
|
||||
|
||||
$scope.buildNestHomeUrls = function (nestitem) {
|
||||
$scope.device.deviceType = "home";
|
||||
$scope.device.name = nestitem.name;
|
||||
$scope.device.mapType = "nestHomeAway";
|
||||
$scope.device.mapId = nestitem.id;
|
||||
$scope.device.onUrl = "{\"name\":\"" + nestitem.id + "\",\"away\":false,\"control\":\"status\"}";
|
||||
$scope.device.offUrl = "{\"name\":\"" + nestitem.id + "\",\"away\":true,\"control\":\"status\"}";
|
||||
};
|
||||
|
||||
$scope.buildNestTempUrls = function (nestitem) {
|
||||
$scope.device.deviceType = "thermo";
|
||||
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Temperature";
|
||||
$scope.device.mapType = "nestThermoSet";
|
||||
$scope.device.mapId = nestitem.id + "-SetTemp";
|
||||
$scope.device.onUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"temp\",\"temp\":\"${intensity.percent}\"}";
|
||||
$scope.device.offUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"temp\",\"temp\":\"${intensity.percent}\"}";
|
||||
};
|
||||
|
||||
$scope.buildNestHeatUrls = function (nestitem) {
|
||||
$scope.device.deviceType = "thermo";
|
||||
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Heat";
|
||||
$scope.device.mapType = "nestThermoSet";
|
||||
$scope.device.mapId = nestitem.id + "-SetHeat";
|
||||
$scope.device.onUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"heat\"}";
|
||||
$scope.device.offUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"off\"}";
|
||||
};
|
||||
|
||||
$scope.buildNestCoolUrls = function (nestitem) {
|
||||
$scope.device.deviceType = "thermo";
|
||||
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Cool";
|
||||
$scope.device.mapType = "nestThermoSet";
|
||||
$scope.device.mapId = nestitem.id + "-SetCool";
|
||||
$scope.device.onUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"cool\"}";
|
||||
$scope.device.offUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"off\"}";
|
||||
};
|
||||
|
||||
$scope.buildNestRangeUrls = function (nestitem) {
|
||||
$scope.device.deviceType = "thermo";
|
||||
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Range";
|
||||
$scope.device.mapType = "nestThermoSet";
|
||||
$scope.device.mapId = nestitem.id + "-SetRange";
|
||||
$scope.device.onUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"range\"}";
|
||||
$scope.device.offUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"off\"}";
|
||||
};
|
||||
|
||||
$scope.buildNestOffUrls = function (nestitem) {
|
||||
$scope.device.deviceType = "thermo";
|
||||
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Thermostat";
|
||||
$scope.device.mapType = "nestThermoSet";
|
||||
$scope.device.mapId = nestitem.id + "-TurnOff";
|
||||
$scope.device.onUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"range\"}";
|
||||
$scope.device.offUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"off\"}";
|
||||
};
|
||||
|
||||
$scope.buildNestFanUrls = function (nestitem) {
|
||||
$scope.device.deviceType = "thermo";
|
||||
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Fan";
|
||||
$scope.device.mapType = "nestThermoSet";
|
||||
$scope.device.mapId = nestitem.id + "-SetFan";
|
||||
$scope.device.onUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"fan-on\"}";
|
||||
$scope.device.offUrl = "{\"name\":\"" + nestitem.id + "\",\"control\":\"fan-auto\"}";
|
||||
};
|
||||
|
||||
$scope.testUrl = function (device, type) {
|
||||
bridgeService.testUrl(device, type);
|
||||
};
|
||||
@@ -683,6 +794,34 @@ return function(input) {
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('availableNestItemId', function(bridgeService) {
|
||||
return function(input) {
|
||||
var out = [];
|
||||
if(input == null)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(!bridgeService.findNestItemByMapId(input[i].id, "nestHomeAway")){
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('unavailableNestItemId', function(bridgeService) {
|
||||
return function(input) {
|
||||
var out = [];
|
||||
if(input == null)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType != null && bridgeService.aContainsB(input[i].mapType, "nest")){
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('configuredButtons', function() {
|
||||
return function(input) {
|
||||
var out = [];
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -126,6 +127,10 @@
|
||||
<td>dev.mode</td>
|
||||
<td>{{BridgeSettings.devmode}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nest.configured</td>
|
||||
<td>{{BridgeSettings.nestconfigured}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||
<li role="presentation" class="active"><a href="#/editdevice">Edit Device</a></li>
|
||||
</ul>
|
||||
@@ -12,6 +13,8 @@
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Edit a device</h2>
|
||||
</div>
|
||||
<p class="text-muted">This screen allows the modification of many fields the bridge uses. Please use care when
|
||||
updating these fields as you may break the settings used by the bridge to call a specific end point device.</p>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<form class="form-horizontal" ng-submit="addDevice()">
|
||||
@@ -24,7 +27,7 @@
|
||||
ng-model="device.name" placeholder="Device Name">
|
||||
</div>
|
||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary">
|
||||
Update Device</button>
|
||||
Update Bridge Device</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-xs-12 col-sm-2 control-label" for="device-target">Target
|
||||
@@ -47,6 +50,8 @@
|
||||
<option value="veraScene">Vera Scene</option>
|
||||
<option value="harmonyActivity">Harmony Activity</option>
|
||||
<option value="harmonyButton">Harmony Button</option>
|
||||
<option value="nestHomeAway">Nest Home Status</option>
|
||||
<option value="nestThermoSet">Nest Thermostat</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||
<li role="presentation" class="active"><a href="#/editor">Manual Add</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -73,6 +74,8 @@
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Add a new device</h2>
|
||||
</div>
|
||||
<p class="text-muted">This area allows you to create any http or udp call to an endpoint. You can use the default GET or select
|
||||
the http verb type below and configure a payload for either on or off methods. Currently, https is not supported.</p>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<form class="form-horizontal" ng-submit="addDevice()">
|
||||
@@ -86,7 +89,7 @@
|
||||
ng-model="device.name" placeholder="Device Name">
|
||||
</div>
|
||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary">
|
||||
Add Device</button>
|
||||
Add Bridge Device</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li role="presentation" class="active"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
<li role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -13,8 +14,9 @@
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<p class="text-muted">You can select a Harmony Activity and generate
|
||||
the add activity box selections automatically.</p>
|
||||
<p class="text-muted">For any Harmony Activity, use the action buttons to generate the device addition information below automatically.
|
||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
||||
The 'Already Configured Activities' list below will show what is already setup for your Harmony Hubs.</p>
|
||||
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
@@ -83,7 +85,7 @@
|
||||
</div>
|
||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Add a Harmony Activity</h2>
|
||||
<h2 class="panel-title">Add a Bridge Device for a Harmony Activity</h2>
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
@@ -97,7 +99,7 @@
|
||||
ng-model="device.name" placeholder="Device Name">
|
||||
</div>
|
||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary">
|
||||
Add Activity</button>
|
||||
Add Bridge Device</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
<li role="presentation" class="active"><a href="#/harmonydevices">Harmony Devices</a></li>
|
||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -13,8 +14,9 @@
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<p class="text-muted">You can select a Harmony Device and Button and generate
|
||||
the add button box selections automatically.</p>
|
||||
<p class="text-muted">For any Harmony Device and Buttons, use the action buttons to generate the device addition information below automatically.
|
||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
||||
The 'Already Configured Harmony Buttons' list below will show what is already setup for your Harmony Hubs.</p>
|
||||
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
@@ -106,7 +108,7 @@
|
||||
</div>
|
||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Add a Harmony Button</h2>
|
||||
<h2 class="panel-title">Add a Bridge Device for Harmony Buttons</h2>
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
@@ -120,7 +122,7 @@
|
||||
ng-model="device.name" placeholder="Device Name">
|
||||
</div>
|
||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary">
|
||||
Add Button</button>
|
||||
Add Bridge Device</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
|
||||
150
src/main/resources/public/views/nestactions.html
Normal file
150
src/main/resources/public/views/nestactions.html
Normal file
@@ -0,0 +1,150 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#">Configuration</a></li>
|
||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
||||
<li role="presentation" class="active"><a href="#/nest">Nest</a></li>
|
||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Nest Items List</h2>
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<p class="text-muted">For any Nest Item, use the action buttons to generate the device addition information below automatically.
|
||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
||||
The 'Already Configured Nest Items' list below will show what is already setup for your Nest.</p>
|
||||
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<a href="" ng-click="order('name')">Name</a>
|
||||
<span class="sortorder" ng-show="predicate === 'name'" ng-class="{reverse:reverse}"></span>
|
||||
</th>
|
||||
<th>
|
||||
<a href="" ng-click="order('type')">Type</a>
|
||||
<span class="sortorder" ng-show="predicate === 'type'" ng-class="{reverse:reverse}"></span>
|
||||
</th>
|
||||
<th>
|
||||
<a href="" ng-click="order('location')">Location</a>
|
||||
<span class="sortorder" ng-show="predicate === 'location'" ng-class="{reverse:reverse}"></span>
|
||||
</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="nestitem in bridge.nestitems | availableNestItemId | orderBy:predicate:reverse">
|
||||
<td>{{nestitem.name}}</td>
|
||||
<td>{{nestitem.type}}</td>
|
||||
<td>{{nestitem.location}}</td>
|
||||
<td>
|
||||
<ul class="list-group">
|
||||
<li ng-if="nestitem.type ==='Home' " class="list-group-item">
|
||||
<button class="btn btn-success" type="submit"
|
||||
ng-click="buildNestHomeUrls(nestitem)">Home/Away</button>
|
||||
</li>
|
||||
<li ng-if="nestitem.type ==='Thermostat' " class="list-group-item">
|
||||
<p>
|
||||
<button class="btn btn-success" type="submit"
|
||||
ng-click="buildNestTempUrls(nestitem)">Temp</button>
|
||||
<button class="btn btn-success" type="submit"
|
||||
ng-click="buildNestHeatUrls(nestitem)">Heat</button>
|
||||
<button class="btn btn-success" type="submit"
|
||||
ng-click="buildNestCoolUrls(nestitem)">Cool</button>
|
||||
</p>
|
||||
<p>
|
||||
<button class="btn btn-success" type="submit"
|
||||
ng-click="buildNestRangeUrls(nestitem)">Range</button>
|
||||
<button class="btn btn-success" type="submit"
|
||||
ng-click="buildNestOffUrls(nestitem)">Off</button>
|
||||
<button class="btn btn-success" type="submit"
|
||||
ng-click="buildNestFanUrls(nestitem)">Fan</button>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Already Configured Nest Items <a ng-click="toggleActivities()"><span class={{imgActivitiesUrl}} aria-hidden="true"></a></h2>
|
||||
</div>
|
||||
<ul ng-if="activitiesVisible" class="list-group">
|
||||
<li class="list-group-item">
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<a href="" ng-click="order('name')">Name</a>
|
||||
<span class="sortorder" ng-show="predicate === 'name'" ng-class="{reverse:reverse}"></span>
|
||||
</th>
|
||||
<th>
|
||||
<a href="" ng-click="order('id')">Id</a>
|
||||
<span class="sortorder" ng-show="predicate === 'id'" ng-class="{reverse:reverse}"></span>
|
||||
</th>
|
||||
<th>
|
||||
<a href="" ng-click="order('mapId')">mapId</a>
|
||||
<span class="sortorder" ng-show="predicate === 'mapId'" ng-class="{reverse:reverse}"></span>
|
||||
</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="device in bridge.devices | unavailableNestItemId | orderBy:predicate:reverse">
|
||||
<td>{{device.name}}</td>
|
||||
<td>{{device.id}}</td>
|
||||
<td>{{device.mapId}}</td>
|
||||
<td><button class="btn btn-danger" type="submit"
|
||||
ng-click="deleteDeviceByMapId(device.mapId, 'nest')">Delete</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Add a Bridge Device for a Nest Item</h2>
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<form class="form-horizontal" ng-submit="addDevice()">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||
</label>
|
||||
|
||||
<div class="col-xs-8 col-sm-7">
|
||||
<input type="text" class="form-control" id="device-name"
|
||||
ng-model="device.name" placeholder="Device Name">
|
||||
</div>
|
||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary">
|
||||
Add Bridge Device</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||
URL </label>
|
||||
|
||||
<div class="col-xs-8 col-sm-7">
|
||||
<textarea rows="3" class="form-control" id="device-on-url"
|
||||
ng-model="device.onUrl" placeholder="URL to turn device on"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<label class="col-xs-12 col-sm-2 control-label"
|
||||
for="device-off-url">Off URL </label>
|
||||
|
||||
<div class="col-xs-8 col-sm-7">
|
||||
<textarea rows="3" class="form-control" id="device-off-url"
|
||||
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -4,6 +4,7 @@
|
||||
<li role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -13,8 +14,9 @@
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<p class="text-muted">You can select a Vera device and generate
|
||||
the add device box selections automatically.</p><p>Also, use this select menu for which type of dim
|
||||
<p class="text-muted">For any Vera Device, use the action buttons to generate the device addition information below automatically.
|
||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
||||
The 'Already Configured Vera Devices' list below will show what is already setup for your Vera.</p><p>Also, use this select menu for which type of dim
|
||||
control you would like to be generated:
|
||||
<select name="device-dim-control" id="device-dim-control" ng-model="device_dim_control">
|
||||
<option value="">none</option>
|
||||
@@ -102,7 +104,7 @@
|
||||
</div>
|
||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Add a Vera device</h2>
|
||||
<h2 class="panel-title">Add Bridge Device for a Vera Device</h2>
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
@@ -116,7 +118,7 @@
|
||||
ng-model="device.name" placeholder="Device Name">
|
||||
</div>
|
||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary">
|
||||
Add Device</button>
|
||||
Add Bridge Device</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<li role="presentation" class="active"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -13,8 +14,9 @@
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<p class="text-muted">You can select a Vera scene and generate
|
||||
the add scene box selections automatically.</p>
|
||||
<p class="text-muted">For any Vera Scene, use the action buttons to generate the device addition information below automatically.
|
||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
||||
The 'Already Configured Vera Scenes' list below will show what is already setup for your Vera.</p>
|
||||
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
@@ -85,7 +87,7 @@
|
||||
</div>
|
||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Add a Vera scene</h2>
|
||||
<h2 class="panel-title">Add a Bridge Device for a Vera scene</h2>
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
@@ -99,7 +101,7 @@
|
||||
ng-model="device.name" placeholder="Device Name">
|
||||
</div>
|
||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary">
|
||||
Add Scene</button>
|
||||
Add Bridge Device</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
|
||||
Reference in New Issue
Block a user