From d3cc961dfb2dbf6497ffbc54982601820aabf813 Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 8 Jan 2016 16:14:42 -0600 Subject: [PATCH] Initial updates for nest control --- pom.xml | 7 ++- .../bwssystems/HABridge/BridgeSettings.java | 21 ++++++++ .../bwssystems/HABridge/Configuration.java | 4 +- .../com/bwssystems/HABridge/HABridge.java | 14 +++-- .../devicemanagmeent/DeviceResource.java | 28 +++++++++- .../bwssystems/HABridge/hue/HueMulator.java | 22 +++++++- .../com/bwssystems/NestBridge/HomeAway.java | 18 +++++++ .../com/bwssystems/NestBridge/NestHome.java | 51 +++++++++++++++++++ 8 files changed, 156 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/bwssystems/NestBridge/HomeAway.java create mode 100644 src/main/java/com/bwssystems/NestBridge/NestHome.java diff --git a/pom.xml b/pom.xml index b153dee..6d377e4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 1.2.3a + 1.2.3b jar HA Bridge @@ -30,6 +30,11 @@ harmony-java-client 1.0.8 + + com.github.bwssytems + nest-controller + 1.0.0 + com.sparkjava spark-core diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index eeef17d..b82a9fa 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -15,6 +15,8 @@ public class BridgeSettings { private boolean upnpstrict; private boolean traceupnp; private boolean devmode; + private String nestuser; + private String nestpwd; public String getUpnpConfigAddress() { return upnpconfigaddress; @@ -88,6 +90,18 @@ 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 isValidVera() { if(this.veraaddress.contains(Configuration.DEFAULT_VERA_ADDRESS)) return false; @@ -103,4 +117,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; + } } diff --git a/src/main/java/com/bwssystems/HABridge/Configuration.java b/src/main/java/com/bwssystems/HABridge/Configuration.java index 0bfeb3d..11d43b8 100644 --- a/src/main/java/com/bwssystems/HABridge/Configuration.java +++ b/src/main/java/com/bwssystems/HABridge/Configuration.java @@ -7,7 +7,7 @@ public class Configuration { 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_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"; } diff --git a/src/main/java/com/bwssystems/HABridge/HABridge.java b/src/main/java/com/bwssystems/HABridge/HABridge.java index 5b3e7f3..119a011 100644 --- a/src/main/java/com/bwssystems/HABridge/HABridge.java +++ b/src/main/java/com/bwssystems/HABridge/HABridge.java @@ -12,6 +12,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,6 +37,7 @@ public class HABridge { Logger log = LoggerFactory.getLogger(HABridge.class); DeviceResource theResources; HarmonyHome harmonyHome; + NestHome nestHome; HueMulator theHueMulator; UpnpSettingsResource theSettingResponder; UpnpListener theUpnpListener; @@ -75,12 +77,14 @@ public class HABridge { } } 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 +94,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); diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index 0f3fa55..2f05ebe 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -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 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,24 @@ public class DeviceResource { return myHarmonyHome.getDevices(); }, new JsonTransformer()); + get (API_CONTEXT + "/nest/homes", "application/json", (request, response) -> { + log.debug("Get nest homes"); + if(nestHome == null) { + response.status(HttpStatus.SC_NOT_FOUND); + return null; + } + response.status(HttpStatus.SC_OK); + return nestHome.getHomeNames(); + }, new JsonTransformer()); + + get (API_CONTEXT + "/nest/thermostats", "application/json", (request, response) -> { + log.debug("Get nest thermostats"); + if(nestHome == null) { + response.status(HttpStatus.SC_NOT_FOUND); + return null; + } + response.status(HttpStatus.SC_OK); + return nestHome.getThermostatNames(); + }, new JsonTransformer()); } } \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index d918ff5..2fa5ef3 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -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.HomeAway; +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; } @@ -337,6 +345,18 @@ public class HueMulator { else myHarmony.pressButton(aDeviceButton); } + else if(device.getDeviceType().toLowerCase().contains("home") || (device.getMapType() != null && device.getMapType().equalsIgnoreCase("nestHome"))) + { + log.debug("executing set away for nest home: " + url); + HomeAway homeAway = new Gson().fromJson(url, HomeAway.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(url.startsWith("udp://")) { try { diff --git a/src/main/java/com/bwssystems/NestBridge/HomeAway.java b/src/main/java/com/bwssystems/NestBridge/HomeAway.java new file mode 100644 index 0000000..32878d9 --- /dev/null +++ b/src/main/java/com/bwssystems/NestBridge/HomeAway.java @@ -0,0 +1,18 @@ +package com.bwssystems.NestBridge; + +public class HomeAway { + private String name; + private Boolean away; + 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; + } +} diff --git a/src/main/java/com/bwssystems/NestBridge/NestHome.java b/src/main/java/com/bwssystems/NestBridge/NestHome.java new file mode 100644 index 0000000..914702f --- /dev/null +++ b/src/main/java/com/bwssystems/NestBridge/NestHome.java @@ -0,0 +1,51 @@ +package com.bwssystems.NestBridge; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bwssystems.HABridge.BridgeSettings; +import com.bwssystems.nest.controller.Nest; +import com.bwssystems.nest.controller.NestSession; +import com.bwssystems.nest.protocol.error.LoginException; + +public class NestHome { + private static final Logger log = LoggerFactory.getLogger(NestHome.class); + private NestSession theSession; + private Nest theNest; + + public NestHome(BridgeSettings bridgeSettings) { + theSession = null; + theNest = null; + + if(bridgeSettings.isValidNest()) + 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 getHomeNames() { + if(theNest == null) + return null; + return new ArrayList(theNest.getHomeNames()); /* list of home structures i.e. MyHouse */ + } + + public List getThermostatNames() { + if(theNest == null) + return null; + return new ArrayList(theNest.getThermostatNames()); /* list of thermostats in all structure */ + } + + public Nest getTheNest() { + return theNest; + } +} +