From 05418fdda15c64cc4b54defe922045d98723d208 Mon Sep 17 00:00:00 2001 From: Admin Date: Thu, 21 Apr 2016 15:41:06 -0500 Subject: [PATCH] Updated passthru after more testing --- .../bwssystems/HABridge/hue/HueMulator.java | 42 +++++++++----- src/main/java/com/bwssystems/hue/HueInfo.java | 44 ++------------ src/main/java/com/bwssystems/hue/HueUtil.java | 58 +++++++++++++++++++ src/main/resources/public/scripts/app.js | 12 +++- 4 files changed, 99 insertions(+), 57 deletions(-) create mode 100644 src/main/java/com/bwssystems/hue/HueUtil.java diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index fbd5403..7722e63 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -13,6 +13,7 @@ import com.bwssystems.harmony.HarmonyHandler; import com.bwssystems.harmony.HarmonyHome; import com.bwssystems.harmony.RunActivity; import com.bwssystems.hue.HueDeviceIdentifier; +import com.bwssystems.hue.HueUtil; import com.bwssystems.nest.controller.Nest; import com.bwssystems.util.JsonTransformer; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -72,6 +73,7 @@ public class HueMulator { private ObjectMapper mapper; private BridgeSettingsDescriptor bridgeSettings; private byte[] sendData; + private String hueUser; public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome, NestHome aNestHome){ @@ -88,10 +90,12 @@ public class HueMulator { else this.theNest = null; bridgeSettings = theBridgeSettings; + hueUser = null; } // This function sets up the sparkjava rest calls for the hue api public void setupServer() { + String errorString = null; log.info("Hue emulator service started...."); // http://ip_address:port/api/{userId}/lights returns json objects of all lights configured get(HUE_CONTEXT + "/:userid/lights", "application/json", (request, response) -> { @@ -343,9 +347,15 @@ public class HueMulator { { url = device.getOnUrl(); HueDeviceIdentifier deviceId = new Gson().fromJson(url, HueDeviceIdentifier.class); + if(hueUser == null) { + hueUser = userId; + if((hueUser = HueUtil.registerWithHue(httpClient, deviceId.getIpAddress(), device.getName(), errorString)) == null) { + return errorString; + } + } // make call - if (!doHttpRequest("http://"+deviceId.getIpAddress()+"/api/"+userId+"/lights/"+deviceId.getDeviceId()+"/state", HttpPut.METHOD_NAME, device.getContentType(), request.body())) { + if (!doHttpRequest("http://"+deviceId.getIpAddress()+"/api/"+hueUser+"/lights/"+deviceId.getDeviceId()+"/state", HttpPut.METHOD_NAME, device.getContentType(), request.body())) { log.warn("Error on calling url to change device state: " + url); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Error on calling url to change device state\", \"parameter\": \"/lights/" + lightId + "state\"}}]"; } @@ -605,63 +615,63 @@ public class HueMulator { if(body.contains("bri")) { if(justState) - responseString = responseString + "true}"; - responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/bri\":" + state.getBri() + "}"; + responseString = responseString + "true}}"; + responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/bri\":" + state.getBri() + "}}"; justState = false; } if(body.contains("ct")) { if(justState) - responseString = responseString + "true}"; - responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/ct\":" + state.getCt() + "}"; + responseString = responseString + "true}}"; + responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/ct\":" + state.getCt() + "}}"; justState = false; } if(body.contains("xy")) { if(justState) - responseString = responseString + "true}"; - responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/xy\":" + state.getXy() + "}"; + responseString = responseString + "true}}"; + responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/xy\":" + state.getXy() + "}}"; justState = false; } if(body.contains("hue")) { if(justState) - responseString = responseString + "true}"; - responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/hue\":" + state.getHue() + "}"; + responseString = responseString + "true}}"; + responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/hue\":" + state.getHue() + "}}"; justState = false; } if(body.contains("sat")) { if(justState) - responseString = responseString + "true}"; - responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/sat\":" + state.getSat() + "}"; + responseString = responseString + "true}}"; + responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/sat\":" + state.getSat() + "}}"; justState = false; } if(body.contains("colormode")) { if(justState) - responseString = responseString + "true}"; - responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/colormode\":" + state.getColormode() + "}"; + responseString = responseString + "true}}"; + responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/colormode\":" + state.getColormode() + "}}"; justState = false; } if(justState) { if (state.isOn()) { - responseString = responseString + "true}"; + responseString = responseString + "true}}"; state.setBri(255); } else if (body.contains("false")) { - responseString = responseString + "false}"; + responseString = responseString + "false}}"; state.setBri(0); } } - responseString = responseString + "}]"; + responseString = responseString + "]"; return responseString; diff --git a/src/main/java/com/bwssystems/hue/HueInfo.java b/src/main/java/com/bwssystems/hue/HueInfo.java index 4ce8c9f..f3cb48c 100644 --- a/src/main/java/com/bwssystems/hue/HueInfo.java +++ b/src/main/java/com/bwssystems/hue/HueInfo.java @@ -5,17 +5,12 @@ import java.nio.charset.Charset; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bwssystems.HABridge.NamedIP; -import com.bwssystems.HABridge.api.SuccessUserResponse; -import com.bwssystems.HABridge.api.UserCreateRequest; import com.bwssystems.HABridge.api.hue.HueApiResponse; import com.google.gson.Gson; @@ -23,25 +18,21 @@ import com.google.gson.Gson; public class HueInfo { private static final Logger log = LoggerFactory.getLogger(HueInfo.class); private HttpClient httpClient; - private static final String HUE_REQUEST = "/api"; private NamedIP hueAddress; - private UserCreateRequest theLogin; private String theUser; public HueInfo(NamedIP addressName) { super(); httpClient = HttpClients.createDefault(); hueAddress = addressName; - theLogin = new UserCreateRequest(); - theLogin.setDevicetype("HA Bridge"); - theLogin.setUsername("habridge"); - theUser = theLogin.getUsername(); + theUser = "habridge"; } public HueApiResponse getHueApiResponse() { HueApiResponse theHueApiResponse = null; + String errorString = null; - String theUrl = "http://" + hueAddress.getIp() + HUE_REQUEST + "/" + theLogin.getUsername(); + String theUrl = "http://" + hueAddress.getIp() + HueUtil.HUE_REQUEST + "/" + theUser; String theData; boolean loopControl = true; int retryCount = 0; @@ -51,14 +42,14 @@ public class HueInfo { loopControl = false; break; } - theUrl = "http://" + hueAddress.getIp() + HUE_REQUEST + "/" + theUser; + theUrl = "http://" + hueAddress.getIp() + HueUtil.HUE_REQUEST + "/" + theUser; theData = doHttpGETRequest(theUrl); if(theData != null) { log.debug("GET HueApiResponse - data: " + theData); if(theData.contains("[{\"error\":")) { if(theData.contains("unauthorized user")) { - if(!registerWithHue()) { - log.warn("Register to Hue for " + hueAddress.getName() + " - returned error."); + if((theUser = HueUtil.registerWithHue(httpClient, hueAddress.getIp(), hueAddress.getName(), errorString)) == null) { + log.warn("Register to Hue for " + hueAddress.getName() + " returned error: " + errorString); return null; } retryCount++; @@ -100,29 +91,6 @@ public class HueInfo { return theContent; } - private boolean registerWithHue() { - boolean responseValue = false; - HttpPost postRequest = new HttpPost("http://" + hueAddress.getIp() + HUE_REQUEST); - ContentType parsedContentType = ContentType.parse("application/json"); - StringEntity requestBody = new StringEntity(new Gson().toJson(theLogin), parsedContentType); - HttpResponse response = null; - postRequest.setEntity(requestBody); - try { - response = httpClient.execute(postRequest); - log.debug("POST execute on URL responded: " + response.getStatusLine().getStatusCode()); - if(response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300){ - String theBody = EntityUtils.toString(response.getEntity()); - log.debug("registerWithHue response data: " + theBody); - SuccessUserResponse[] theResponses = new Gson().fromJson(theBody, SuccessUserResponse[].class); //read content for data, SuccessUserResponse[].class); - theUser = theResponses[0].getSuccess().getUsername(); - responseValue = true; - } - EntityUtils.consume(response.getEntity()); //close out inputstream ignore content - } catch (IOException e) { - log.warn("Error loggin into HUE: IOException in log", e); - } - return responseValue; - } public NamedIP getHueAddress() { return hueAddress; } diff --git a/src/main/java/com/bwssystems/hue/HueUtil.java b/src/main/java/com/bwssystems/hue/HueUtil.java new file mode 100644 index 0000000..105cc51 --- /dev/null +++ b/src/main/java/com/bwssystems/hue/HueUtil.java @@ -0,0 +1,58 @@ +package com.bwssystems.hue; + +import java.io.IOException; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bwssystems.HABridge.api.SuccessUserResponse; +import com.bwssystems.HABridge.api.UserCreateRequest; +import com.google.gson.Gson; + +public class HueUtil { + private static final Logger log = LoggerFactory.getLogger(HueUtil.class); + public static final String HUE_REQUEST = "/api"; + + public static final String registerWithHue(HttpClient anHttpClient, String ipAddress, String aName, String errorString) { + UserCreateRequest theLogin; + String theUser = null; + theLogin = new UserCreateRequest(); + theLogin.setDevicetype("HA Bridge"); + theLogin.setUsername("habridge"); + HttpPost postRequest = new HttpPost("http://" + ipAddress + HUE_REQUEST); + ContentType parsedContentType = ContentType.parse("application/json"); + StringEntity requestBody = new StringEntity(new Gson().toJson(theLogin), parsedContentType); + HttpResponse response = null; + postRequest.setEntity(requestBody); + try { + response = anHttpClient.execute(postRequest); + log.debug("POST execute on URL responded: " + response.getStatusLine().getStatusCode()); + if(response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300){ + String theBody = EntityUtils.toString(response.getEntity()); + log.debug("registerWithHue response data: " + theBody); + if(theBody.contains("[{\"error\":")) { + if(theBody.contains("link button not")) { + log.warn("registerWithHue needs link button pressed on HUE bridge: " + aName); + } + else + log.warn("registerWithHue returned an unexpected error: " + theBody); + errorString = theBody; + } + else { + SuccessUserResponse[] theResponses = new Gson().fromJson(theBody, SuccessUserResponse[].class); //read content for data, SuccessUserResponse[].class); + theUser = theResponses[0].getSuccess().getUsername(); + } + } + EntityUtils.consume(response.getEntity()); //close out inputstream ignore content + } catch (IOException e) { + log.warn("Error logging into HUE: IOException in log", e); + } + return theUser; + } +} diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 02d7e69..3ed0454 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -101,6 +101,8 @@ app.service('bridgeService', function ($http, $window, ngToast) { }; this.clearDevice = function () { + if(self.state.device == null) + self.state.device = []; self.state.device.id = ""; self.state.device.mapType = null; self.state.device.mapId = null; @@ -704,13 +706,15 @@ app.controller('ViewingController', function ($scope, $location, $http, $window, var dialogNeeded = false; if((type == "on" && (bridgeService.aContainsB(device.onUrl, "${intensity.byte}") || bridgeService.aContainsB(device.onUrl, "${intensity.percent}") || - bridgeService.aContainsB(device.onUrl, "${intensity.math("))) || + bridgeService.aContainsB(device.onUrl, "${intensity.math(")) || (type == "off" && (bridgeService.aContainsB(device.offUrl, "${intensity.byte}") || bridgeService.aContainsB(device.offUrl, "${intensity.percent}") || bridgeService.aContainsB(device.offUrl, "${intensity.math("))) || (type == "dim" && (bridgeService.aContainsB(device.dimUrl, "${intensity.byte}") || bridgeService.aContainsB(device.dimUrl, "${intensity.percent}") || - bridgeService.aContainsB(device.dimUrl, "${intensity.math(")))) { + bridgeService.aContainsB(device.dimUrl, "${intensity.math(") || + bridgeService.aContainsB(device.deviceType, "passthru") || + bridgeService.aContainsB(device.mapType, "hueDevice"))))) { $scope.bridge.device = device; $scope.bridge.type = type; ngDialog.open({ @@ -1135,7 +1139,9 @@ app.controller('HueController', function ($scope, $location, $http, bridgeServic $scope.buildDeviceUrls = function (huedevice) { bridgeService.clearDevice(); - $scope.device.deviceType = "switch"; + if($scope.device == null) + $scope.device = $scope.bridge.device; + $scope.device.deviceType = "passthru"; $scope.device.name = huedevice.device.name; $scope.device.targetDevice = huedevice.huename; $scope.device.contentType = "application/json";