Completed Hue passthru

This commit is contained in:
Admin
2016-04-18 16:41:15 -05:00
parent 7a0946e3b7
commit 3ba8f56db2
12 changed files with 161 additions and 57 deletions

View File

@@ -154,6 +154,7 @@ public class BridgeSettings extends BackupHandler {
theBridgeSettings.setVeraconfigured(theBridgeSettings.isValidVera());
theBridgeSettings.setHarmonyconfigured(theBridgeSettings.isValidHarmony());
theBridgeSettings.setNestConfigured(theBridgeSettings.isValidNest());
theBridgeSettings.setHueconfigured(theBridgeSettings.isValidHue());
if(serverPortOverride != null)
theBridgeSettings.setServerPort(serverPortOverride);
setupParams(Paths.get(theBridgeSettings.getConfigfile()), ".cfgbk", "habridge.config-");
@@ -189,6 +190,8 @@ public class BridgeSettings extends BackupHandler {
theBridgeSettings.setNestConfigured(aBridgeSettings.isValidNest());
theBridgeSettings.setNumberoflogmessages(aBridgeSettings.getNumberoflogmessages());
theBridgeSettings.setFarenheit(aBridgeSettings.isFarenheit());
theBridgeSettings.setHueaddress(aBridgeSettings.getHueaddress());
theBridgeSettings.setHueconfigured(aBridgeSettings.isValidHue());
}
public void save(BridgeSettingsDescriptor newBridgeSettings) {

View File

@@ -11,6 +11,7 @@ import com.bwssystems.HABridge.upnp.UpnpListener;
import com.bwssystems.HABridge.upnp.UpnpSettingsResource;
import com.bwssystems.NestBridge.NestHome;
import com.bwssystems.harmony.HarmonyHome;
import com.bwssystems.hue.HueHome;
public class HABridge {
@@ -34,6 +35,7 @@ public class HABridge {
DeviceResource theResources;
HarmonyHome harmonyHome;
NestHome nestHome;
HueHome hueHome;
HueMulator theHueMulator;
UpnpSettingsResource theSettingResponder;
UpnpListener theUpnpListener;
@@ -62,8 +64,10 @@ public class HABridge {
harmonyHome = new HarmonyHome(bridgeSettings.getBridgeSettingsDescriptor());
//setup the nest connection if available
nestHome = new NestHome(bridgeSettings.getBridgeSettingsDescriptor());
//setup the hue passtrhu configuration if available
hueHome = new HueHome(bridgeSettings.getBridgeSettingsDescriptor());
// setup the class to handle the resource setup rest api
theResources = new DeviceResource(bridgeSettings.getBridgeSettingsDescriptor(), harmonyHome, nestHome);
theResources = new DeviceResource(bridgeSettings.getBridgeSettingsDescriptor(), harmonyHome, nestHome, hueHome);
// setup the class to handle the hue emulator rest api
theHueMulator = new HueMulator(bridgeSettings.getBridgeSettingsDescriptor(), theResources.getDeviceRepository(), harmonyHome, nestHome);
theHueMulator.setupServer();
@@ -77,6 +81,8 @@ public class HABridge {
theUpnpListener = new UpnpListener(bridgeSettings.getBridgeSettingsDescriptor(), bridgeSettings.getBridgeControl());
if(theUpnpListener.startListening())
log.info("HA Bridge (v" + theVersion.getVersion() + ") reinitialization requessted....");
else
bridgeSettings.getBridgeControl().setStop(true);
bridgeSettings.getBridgeControl().setReinit(false);
stop();

View File

@@ -42,7 +42,7 @@ public class DeviceResource {
private HueHome hueHome;
private static final Set<String> supportedVerbs = new HashSet<>(Arrays.asList("get", "put", "post"));
public DeviceResource(BridgeSettingsDescriptor theSettings, HarmonyHome theHarmonyHome, NestHome aNestHome) {
public DeviceResource(BridgeSettingsDescriptor theSettings, HarmonyHome theHarmonyHome, NestHome aNestHome, HueHome aHueHome) {
this.deviceRepository = new DeviceRepository(theSettings.getUpnpDeviceDb());
if(theSettings.isValidVera())
@@ -61,7 +61,7 @@ public class DeviceResource {
this.nestHome = null;
if(theSettings.isValidHue())
this.hueHome = new HueHome(theSettings);
this.hueHome = aHueHome;
else
this.hueHome = null;
setupEndpoints();

View File

@@ -345,7 +345,7 @@ public class HueMulator {
HueDeviceIdentifier deviceId = new Gson().fromJson(url, HueDeviceIdentifier.class);
// make call
if (!doHttpRequest("http://"+deviceId.getIpAddress()+"/api/"+userId+"/lights/"+deviceId.getDeviceId(), HttpPut.METHOD_NAME, device.getContentType(), request.body())) {
if (!doHttpRequest("http://"+deviceId.getIpAddress()+"/api/"+userId+"/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 +605,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;

View File

@@ -94,8 +94,10 @@ public class UpnpListener {
log.info("UPNP Discovery Listener - ended, restart found");
if(bridgeControl.isStop())
log.info("UPNP Discovery Listener - ended, stop found");
if(!bridgeControl.isStop()&& !bridgeControl.isReinit())
if(!bridgeControl.isStop()&& !bridgeControl.isReinit()) {
log.info("UPNP Discovery Listener - ended, error found");
return false;
}
return bridgeControl.isReinit();
}

View File

@@ -5,24 +5,24 @@ import com.bwssystems.HABridge.api.hue.DeviceResponse;
public class HueDevice {
private DeviceResponse device;
private String hubaddress;
private String hubname;
private String hueaddress;
private String huename;
public DeviceResponse getDevice() {
return device;
}
public void setDevice(DeviceResponse device) {
this.device = device;
public void setDevice(DeviceResponse adevice) {
this.device = adevice;
}
public String getHubaddress() {
return hubaddress;
public String getHueaddress() {
return hueaddress;
}
public void setHubaddress(String hubaddress) {
this.hubaddress = hubaddress;
public void setHueaddress(String ahueaddress) {
this.hueaddress = ahueaddress;
}
public String getHubname() {
return hubname;
public String getHuename() {
return huename;
}
public void setHubname(String hubname) {
this.hubname = hubname;
public void setHuename(String ahuename) {
this.huename = ahuename;
}
}

View File

@@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory;
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
import com.bwssystems.HABridge.NamedIP;
import com.bwssystems.HABridge.api.hue.DeviceResponse;
import com.bwssystems.HABridge.api.hue.HueApiResponse;
public class HueHome {
private static final Logger log = LoggerFactory.getLogger(HueHome.class);
@@ -21,7 +22,7 @@ public class HueHome {
hues = new HashMap<String, HueInfo>();
if(!bridgeSettings.isValidHue())
return;
Iterator<NamedIP> theList = bridgeSettings.getVeraAddress().getDevices().iterator();
Iterator<NamedIP> theList = bridgeSettings.getHueaddress().getDevices().iterator();
while(theList.hasNext()) {
NamedIP aHue = theList.next();
hues.put(aHue.getName(), new HueInfo(aHue));
@@ -34,13 +35,16 @@ public class HueHome {
ArrayList<HueDevice> deviceList = new ArrayList<HueDevice>();
while(keys.hasNext()) {
String key = keys.next();
Map<String, DeviceResponse> theDevices = hues.get(key).getHueApiResponse().getLights();
HueApiResponse theResponse = hues.get(key).getHueApiResponse();
if(theResponse != null) {
Map<String, DeviceResponse> theDevices = theResponse.getLights();
if(theDevices != null) {
Iterator<String> deviceKeys = theDevices.keySet().iterator();
while(deviceKeys.hasNext()) {
HueDevice aNewHueDevice = new HueDevice();
aNewHueDevice.setDevice(theDevices.get(deviceKeys.next()));
aNewHueDevice.setHubaddress("");
aNewHueDevice.setHueaddress(hues.get(key).getHueAddress().getIp());
aNewHueDevice.setHuename(key);
deviceList.add(aNewHueDevice);
}
}
@@ -49,6 +53,9 @@ public class HueHome {
break;
}
}
else
log.warn("Cannot get lights for Hue with name: " + key);
}
return deviceList;
}
}

View File

@@ -18,7 +18,7 @@ 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/habridge/config";
private static final String HUE_REQUEST = "/api/habridge";
private NamedIP hueAddress;
public HueInfo(NamedIP addressName) {
@@ -58,4 +58,12 @@ public class HueInfo {
}
return theContent;
}
public NamedIP getHueAddress() {
return hueAddress;
}
public void setHueAddress(NamedIP hueAddress) {
this.hueAddress = hueAddress;
}
}

View File

@@ -31,6 +31,9 @@ app.config(function ($routeProvider) {
}).when('/nest', {
templateUrl: 'views/nestactions.html',
controller: 'NestController'
}).when('/huedevices', {
templateUrl: 'views/huedevice.html',
controller: 'HueController'
}).otherwise({
templateUrl: 'views/configuration.html',
controller: 'ViewingController'
@@ -48,8 +51,12 @@ app.service('bridgeService', function ($http, $window, ngToast) {
this.displayWarn = function(errorTitle, error) {
var toastContent = errorTitle;
if(error != null && typeof(error) != 'undefined')
if(error != null && typeof(error) != 'undefined') {
if(error.data != null)
toastContent = toastContent + " " + error.data.message + " with status: " + error.statusText + " - " + error.status;
else
toastContent = error;
}
ngToast.create({
className: "warning",
dismissButton: true,
@@ -589,6 +596,22 @@ app.controller('SystemController', function ($scope, $location, $http, $window,
}
}
};
$scope.addHuetoSettings = function (newhuename, newhueip) {
if($scope.bridge.settings.hueaddress == null) {
$scope.bridge.settings.hueaddress = { devices: [] };
}
var newhue = {name: newhuename, ip: newhueip }
$scope.bridge.settings.hueaddress.devices.push(newhue);
$scope.newhuename = null;
$scope.newhueip = null;
};
$scope.removeHuetoSettings = function (huename, hueip) {
for(var i = $scope.bridge.settings.hueaddress.devices.length - 1; i >= 0; i--) {
if($scope.bridge.settings.hueaddress.devices[i].name === huename && $scope.bridge.settings.hueaddress.devices[i].ip === hueip) {
$scope.bridge.settings.hueaddress.devices.splice(i, 1);
}
}
};
$scope.bridgeReinit = function () {
$scope.isInControl = false;
bridgeService.reinit();
@@ -1113,13 +1136,12 @@ app.controller('HueController', function ($scope, $location, $http, bridgeServic
$scope.buildDeviceUrls = function (huedevice) {
bridgeService.clearDevice();
$scope.device.deviceType = "switch";
$scope.device.name = huedevice.name;
$scope.device.name = huedevice.device.name;
$scope.device.targetDevice = huedevice.huename;
$scope.device.contentType = "application/json";
$scope.device.mapType = "hueDevice";
$scope.device.mapId = huedevice.id;
$scope.device.onUrl = "http://" + veradevice.veraaddress + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum="
+ veradevice.id;
$scope.device.mapId = huedevice.device.uniqueid;
$scope.device.onUrl = "{\"ipAddress\":\"" + huedevice.hueaddress + "\",\"deviceId\":\"" + huedevice.device.uniqueid +"\"}";
};
$scope.addDevice = function () {
@@ -1400,6 +1422,34 @@ app.filter('unavailableNestItemId', function(bridgeService) {
}
});
app.filter('availableHueDeviceId', function(bridgeService) {
return function(input) {
var out = [];
if(input == null)
return out;
for (var i = 0; i < input.length; i++) {
if(!bridgeService.findDeviceByMapId(input[i].device.uniqueid, input[i].huename, "hueDevice")){
out.push(input[i]);
}
}
return out;
}
});
app.filter('unavailableHueDeviceId', function(bridgeService) {
return function(input) {
var out = [];
if(input == null)
return out;
for (var i = 0; i < input.length; i++) {
if(bridgeService.findDeviceByMapId(input[i].device.uniqueid, input[i].huename, "hueDevice")){
out.push(input[i]);
}
}
return out;
}
});
app.filter('configuredButtons', function() {
return function(input) {
var out = [];

View File

@@ -57,6 +57,7 @@
<option value="harmonyButton">Harmony Button</option>
<option value="nestHomeAway">Nest Home Status</option>
<option value="nestThermoSet">Nest Thermostat</option>
<option value="hueDevice">Hue Device</option>
</select>
</div>
<button class="btn btn-danger" ng-click="clearDevice()">

View File

@@ -36,8 +36,8 @@
</thead>
<tr ng-repeat="huedevice in bridge.huedevices | availableHueDeviceId">
<td>{{$index+1}}</td>
<td><input type="checkbox" name="bulk.devices[]" value="{{huedevice.id}}" ng-checked="bulk.devices.indexOf(huedevice.id) > -1" ng-click="toggleSelection(huedevice.id)"> {{huedevice.name}}</td>
<td>{{huedevice.uniqueid}}</td>
<td><input type="checkbox" name="bulk.devices[]" value="{{huedevice.id}}" ng-checked="bulk.devices.indexOf(huedevice.id) > -1" ng-click="toggleSelection(huedevice.id)"> {{huedevice.device.name}}</td>
<td>{{huedevice.device.uniqueid}}</td>
<td>{{huedevice.huename}}</td>
<td>
<button class="btn btn-success" type="submit"
@@ -71,8 +71,8 @@
</thead>
<tr ng-repeat="huedevice in bridge.huedevices | unavailableHueDeviceId">
<td>{{$index+1}}</td>
<td>{{huedevice.name}}</td>
<td>{{huedevice.uniqueid}}</td>
<td>{{huedevice.device.name}}</td>
<td>{{huedevice.device.uniqueid}}</td>
<td>{{huedevice.huename}}</td>
<td>
<button class="btn btn-danger" type="submit"

View File

@@ -143,6 +143,33 @@
<td><input id="bridge-settings-harmonypwd" class="form-control" type="password"
ng-model="bridge.settings.harmonypwd" placeholder="thepassword"></td>
</tr>
<tr>
<td>Hue Names and IP Addresses</td>
<td><table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>IP</th>
<th>Manage</th>
</tr>
</thead>
<tr ng-repeat="hue in bridge.settings.hueaddress.devices">
<td>{{hue.name}}</td>
<td>{{hue.ip}}</td>
<td><button class="btn btn-danger" type="submit"
ng-click="removeHuetoSettings(hue.name, hue.ip)">Del</button></td>
</tr>
<tr>
<td><input id="bridge-settings-next-hue-name" class="form-control" type="text"
ng-model="newhuename" placeholder="A Hue"></td>
<td><input id="bridge-settings-next-hue-ip" class="form-control" type="text"
ng-model="newhueip" placeholder="192.168.1.3"></td>
<td><button class="btn btn-success" type="submit"
ng-click="addHuetoSettings(newhuename, newhueip)">Add</button></td>
</tr>
</table>
</td>
</tr>
<tr>
<td>Button Press Sleep Interval (ms)</td>
<td><input id="bridge-settings-buttonsleep" class="form-control" type="number" name="input"