mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-19 08:28:46 +00:00
Updated passthru after more testing
This commit is contained in:
@@ -13,6 +13,7 @@ import com.bwssystems.harmony.HarmonyHandler;
|
|||||||
import com.bwssystems.harmony.HarmonyHome;
|
import com.bwssystems.harmony.HarmonyHome;
|
||||||
import com.bwssystems.harmony.RunActivity;
|
import com.bwssystems.harmony.RunActivity;
|
||||||
import com.bwssystems.hue.HueDeviceIdentifier;
|
import com.bwssystems.hue.HueDeviceIdentifier;
|
||||||
|
import com.bwssystems.hue.HueUtil;
|
||||||
import com.bwssystems.nest.controller.Nest;
|
import com.bwssystems.nest.controller.Nest;
|
||||||
import com.bwssystems.util.JsonTransformer;
|
import com.bwssystems.util.JsonTransformer;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
@@ -72,6 +73,7 @@ public class HueMulator {
|
|||||||
private ObjectMapper mapper;
|
private ObjectMapper mapper;
|
||||||
private BridgeSettingsDescriptor bridgeSettings;
|
private BridgeSettingsDescriptor bridgeSettings;
|
||||||
private byte[] sendData;
|
private byte[] sendData;
|
||||||
|
private String hueUser;
|
||||||
|
|
||||||
|
|
||||||
public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome, NestHome aNestHome){
|
public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome, NestHome aNestHome){
|
||||||
@@ -88,10 +90,12 @@ public class HueMulator {
|
|||||||
else
|
else
|
||||||
this.theNest = null;
|
this.theNest = null;
|
||||||
bridgeSettings = theBridgeSettings;
|
bridgeSettings = theBridgeSettings;
|
||||||
|
hueUser = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function sets up the sparkjava rest calls for the hue api
|
// This function sets up the sparkjava rest calls for the hue api
|
||||||
public void setupServer() {
|
public void setupServer() {
|
||||||
|
String errorString = null;
|
||||||
log.info("Hue emulator service started....");
|
log.info("Hue emulator service started....");
|
||||||
// http://ip_address:port/api/{userId}/lights returns json objects of all lights configured
|
// http://ip_address:port/api/{userId}/lights returns json objects of all lights configured
|
||||||
get(HUE_CONTEXT + "/:userid/lights", "application/json", (request, response) -> {
|
get(HUE_CONTEXT + "/:userid/lights", "application/json", (request, response) -> {
|
||||||
@@ -343,9 +347,15 @@ public class HueMulator {
|
|||||||
{
|
{
|
||||||
url = device.getOnUrl();
|
url = device.getOnUrl();
|
||||||
HueDeviceIdentifier deviceId = new Gson().fromJson(url, HueDeviceIdentifier.class);
|
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
|
// 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);
|
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\"}}]";
|
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(body.contains("bri"))
|
||||||
{
|
{
|
||||||
if(justState)
|
if(justState)
|
||||||
responseString = responseString + "true}";
|
responseString = responseString + "true}}";
|
||||||
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/bri\":" + state.getBri() + "}";
|
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/bri\":" + state.getBri() + "}}";
|
||||||
justState = false;
|
justState = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(body.contains("ct"))
|
if(body.contains("ct"))
|
||||||
{
|
{
|
||||||
if(justState)
|
if(justState)
|
||||||
responseString = responseString + "true}";
|
responseString = responseString + "true}}";
|
||||||
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/ct\":" + state.getCt() + "}";
|
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/ct\":" + state.getCt() + "}}";
|
||||||
justState = false;
|
justState = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(body.contains("xy"))
|
if(body.contains("xy"))
|
||||||
{
|
{
|
||||||
if(justState)
|
if(justState)
|
||||||
responseString = responseString + "true}";
|
responseString = responseString + "true}}";
|
||||||
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/xy\":" + state.getXy() + "}";
|
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/xy\":" + state.getXy() + "}}";
|
||||||
justState = false;
|
justState = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(body.contains("hue"))
|
if(body.contains("hue"))
|
||||||
{
|
{
|
||||||
if(justState)
|
if(justState)
|
||||||
responseString = responseString + "true}";
|
responseString = responseString + "true}}";
|
||||||
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/hue\":" + state.getHue() + "}";
|
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/hue\":" + state.getHue() + "}}";
|
||||||
justState = false;
|
justState = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(body.contains("sat"))
|
if(body.contains("sat"))
|
||||||
{
|
{
|
||||||
if(justState)
|
if(justState)
|
||||||
responseString = responseString + "true}";
|
responseString = responseString + "true}}";
|
||||||
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/sat\":" + state.getSat() + "}";
|
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/sat\":" + state.getSat() + "}}";
|
||||||
justState = false;
|
justState = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(body.contains("colormode"))
|
if(body.contains("colormode"))
|
||||||
{
|
{
|
||||||
if(justState)
|
if(justState)
|
||||||
responseString = responseString + "true}";
|
responseString = responseString + "true}}";
|
||||||
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/colormode\":" + state.getColormode() + "}";
|
responseString = responseString + ",{\"success\":{\"/lights/" + lightId + "/state/colormode\":" + state.getColormode() + "}}";
|
||||||
justState = false;
|
justState = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(justState)
|
if(justState)
|
||||||
{
|
{
|
||||||
if (state.isOn()) {
|
if (state.isOn()) {
|
||||||
responseString = responseString + "true}";
|
responseString = responseString + "true}}";
|
||||||
state.setBri(255);
|
state.setBri(255);
|
||||||
} else if (body.contains("false")) {
|
} else if (body.contains("false")) {
|
||||||
responseString = responseString + "false}";
|
responseString = responseString + "false}}";
|
||||||
state.setBri(0);
|
state.setBri(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
responseString = responseString + "}]";
|
responseString = responseString + "]";
|
||||||
|
|
||||||
return responseString;
|
return responseString;
|
||||||
|
|
||||||
|
|||||||
@@ -5,17 +5,12 @@ import java.nio.charset.Charset;
|
|||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.HttpClient;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
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.impl.client.HttpClients;
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.bwssystems.HABridge.NamedIP;
|
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.bwssystems.HABridge.api.hue.HueApiResponse;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
@@ -23,25 +18,21 @@ import com.google.gson.Gson;
|
|||||||
public class HueInfo {
|
public class HueInfo {
|
||||||
private static final Logger log = LoggerFactory.getLogger(HueInfo.class);
|
private static final Logger log = LoggerFactory.getLogger(HueInfo.class);
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
private static final String HUE_REQUEST = "/api";
|
|
||||||
private NamedIP hueAddress;
|
private NamedIP hueAddress;
|
||||||
private UserCreateRequest theLogin;
|
|
||||||
private String theUser;
|
private String theUser;
|
||||||
|
|
||||||
public HueInfo(NamedIP addressName) {
|
public HueInfo(NamedIP addressName) {
|
||||||
super();
|
super();
|
||||||
httpClient = HttpClients.createDefault();
|
httpClient = HttpClients.createDefault();
|
||||||
hueAddress = addressName;
|
hueAddress = addressName;
|
||||||
theLogin = new UserCreateRequest();
|
theUser = "habridge";
|
||||||
theLogin.setDevicetype("HA Bridge");
|
|
||||||
theLogin.setUsername("habridge");
|
|
||||||
theUser = theLogin.getUsername();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HueApiResponse getHueApiResponse() {
|
public HueApiResponse getHueApiResponse() {
|
||||||
HueApiResponse theHueApiResponse = null;
|
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;
|
String theData;
|
||||||
boolean loopControl = true;
|
boolean loopControl = true;
|
||||||
int retryCount = 0;
|
int retryCount = 0;
|
||||||
@@ -51,14 +42,14 @@ public class HueInfo {
|
|||||||
loopControl = false;
|
loopControl = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
theUrl = "http://" + hueAddress.getIp() + HUE_REQUEST + "/" + theUser;
|
theUrl = "http://" + hueAddress.getIp() + HueUtil.HUE_REQUEST + "/" + theUser;
|
||||||
theData = doHttpGETRequest(theUrl);
|
theData = doHttpGETRequest(theUrl);
|
||||||
if(theData != null) {
|
if(theData != null) {
|
||||||
log.debug("GET HueApiResponse - data: " + theData);
|
log.debug("GET HueApiResponse - data: " + theData);
|
||||||
if(theData.contains("[{\"error\":")) {
|
if(theData.contains("[{\"error\":")) {
|
||||||
if(theData.contains("unauthorized user")) {
|
if(theData.contains("unauthorized user")) {
|
||||||
if(!registerWithHue()) {
|
if((theUser = HueUtil.registerWithHue(httpClient, hueAddress.getIp(), hueAddress.getName(), errorString)) == null) {
|
||||||
log.warn("Register to Hue for " + hueAddress.getName() + " - returned error.");
|
log.warn("Register to Hue for " + hueAddress.getName() + " returned error: " + errorString);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
retryCount++;
|
retryCount++;
|
||||||
@@ -100,29 +91,6 @@ public class HueInfo {
|
|||||||
return theContent;
|
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() {
|
public NamedIP getHueAddress() {
|
||||||
return hueAddress;
|
return hueAddress;
|
||||||
}
|
}
|
||||||
|
|||||||
58
src/main/java/com/bwssystems/hue/HueUtil.java
Normal file
58
src/main/java/com/bwssystems/hue/HueUtil.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -101,6 +101,8 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.clearDevice = function () {
|
this.clearDevice = function () {
|
||||||
|
if(self.state.device == null)
|
||||||
|
self.state.device = [];
|
||||||
self.state.device.id = "";
|
self.state.device.id = "";
|
||||||
self.state.device.mapType = null;
|
self.state.device.mapType = null;
|
||||||
self.state.device.mapId = null;
|
self.state.device.mapId = null;
|
||||||
@@ -704,13 +706,15 @@ app.controller('ViewingController', function ($scope, $location, $http, $window,
|
|||||||
var dialogNeeded = false;
|
var dialogNeeded = false;
|
||||||
if((type == "on" && (bridgeService.aContainsB(device.onUrl, "${intensity.byte}") ||
|
if((type == "on" && (bridgeService.aContainsB(device.onUrl, "${intensity.byte}") ||
|
||||||
bridgeService.aContainsB(device.onUrl, "${intensity.percent}") ||
|
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}") ||
|
(type == "off" && (bridgeService.aContainsB(device.offUrl, "${intensity.byte}") ||
|
||||||
bridgeService.aContainsB(device.offUrl, "${intensity.percent}") ||
|
bridgeService.aContainsB(device.offUrl, "${intensity.percent}") ||
|
||||||
bridgeService.aContainsB(device.offUrl, "${intensity.math("))) ||
|
bridgeService.aContainsB(device.offUrl, "${intensity.math("))) ||
|
||||||
(type == "dim" && (bridgeService.aContainsB(device.dimUrl, "${intensity.byte}") ||
|
(type == "dim" && (bridgeService.aContainsB(device.dimUrl, "${intensity.byte}") ||
|
||||||
bridgeService.aContainsB(device.dimUrl, "${intensity.percent}") ||
|
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.device = device;
|
||||||
$scope.bridge.type = type;
|
$scope.bridge.type = type;
|
||||||
ngDialog.open({
|
ngDialog.open({
|
||||||
@@ -1135,7 +1139,9 @@ app.controller('HueController', function ($scope, $location, $http, bridgeServic
|
|||||||
|
|
||||||
$scope.buildDeviceUrls = function (huedevice) {
|
$scope.buildDeviceUrls = function (huedevice) {
|
||||||
bridgeService.clearDevice();
|
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.name = huedevice.device.name;
|
||||||
$scope.device.targetDevice = huedevice.huename;
|
$scope.device.targetDevice = huedevice.huename;
|
||||||
$scope.device.contentType = "application/json";
|
$scope.device.contentType = "application/json";
|
||||||
|
|||||||
Reference in New Issue
Block a user