Finished implementing and testing state change and bug fixes from

testing

Fixes #44
Fixes #60
Fixes #61
Fixes #63
Fixes #66
Fixes #69
This commit is contained in:
Admin
2016-03-21 16:37:13 -05:00
parent 926a7f50dc
commit 9c3d95f177
6 changed files with 99 additions and 10 deletions

View File

@@ -531,6 +531,30 @@ A response to a successful PUT request contains confirmation of the arguments pa
{"success":{"/lights/1/state/on":true}}, {"success":{"/lights/1/state/on":true}},
] ]
``` ```
### Update bridge internal light state
Allows the user to set the internal state of the light on and off, modify the brightness. This is not a HUE API call and is special to the bridge as it keeps track of the state changes to the light from the api. It is intended to allow you to sync the bridge state with your HA system state.
```
PUT http://host:port/api/<username>/lights/<id>/bridgeupdatestate
```
#### Body arguments
Name | Type | Description
-----|-------|-------------
on | bool | On/Off state of the light. On=true, Off=false. Optional
bri | uint8 | The brightness value to set the light to. Brightness is a scale from 1 (the minimum the light is capable of) to 254 (the maximum). Note: a brightness of 1 is not off. e.g. "brightness": 60 will set the light to a specific brightness. Optional
```
{
"on": true,
"bri": 200
}
```
#### Response
A response to a successful PUT request contains confirmation of the arguments passed in. Note: If the new value is too large to return in the response due to internal memory constraints then a value of "Updated." is returned.
```
[
{"success":{"/lights/1/state/bri":200}},
{"success":{"/lights/1/state/on":true}},
]
```
### Create user ### Create user
Emulates creating a new user. The link button state on the HA Bridge is always on for the purpose of responding to this request. No actual user is saved as this is for compatibility. Emulates creating a new user. The link button state on the HA Bridge is always on for the purpose of responding to this request. No actual user is saved as this is for compatibility.
``` ```

View File

@@ -5,7 +5,7 @@
<groupId>com.bwssystems.HABridge</groupId> <groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId> <artifactId>ha-bridge</artifactId>
<version>1.4.1d</version> <version>1.4.2</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>HA Bridge</name> <name>HA Bridge</name>

View File

@@ -240,7 +240,7 @@ public class SystemControl {
} }
else else
log.warn("No filename given for restore backup."); log.warn("No filename given for restore backup.");
return null; return bridgeSettings.getBridgeSettingsDescriptor();
}, new JsonTransformer()); }, new JsonTransformer());
} }

View File

@@ -36,6 +36,7 @@ public class DeviceRepository extends BackupHandler {
super(); super();
gson = gson =
new GsonBuilder() new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create(); .create();
repositoryPath = null; repositoryPath = null;
repositoryPath = Paths.get(deviceDb); repositoryPath = Paths.get(deviceDb);
@@ -81,7 +82,7 @@ public class DeviceRepository extends BackupHandler {
public void save(DeviceDescriptor[] descriptors) { public void save(DeviceDescriptor[] descriptors) {
String theNames = ""; String theNames = "";
for(int i = 0; i < descriptors.length; i++) { for(int i = 0; i < descriptors.length; i++) {
if(descriptors[i].getId() != null) if(descriptors[i].getId() != null && descriptors[i].getId().length() > 0)
devices.remove(descriptors[i].getId()); devices.remove(descriptors[i].getId());
else else
descriptors[i].setId(String.valueOf(random.nextInt(Integer.MAX_VALUE))); descriptors[i].setId(String.valueOf(random.nextInt(Integer.MAX_VALUE)));

View File

@@ -256,6 +256,61 @@ public class HueMulator {
return lightResponse; return lightResponse;
}, new JsonTransformer()); }, new JsonTransformer());
// http://ip_address:port/api/:userid/lights/:id/bridgeupdatestate CORS request
options(HUE_CONTEXT + "/:userid/lights/:id/bridgeupdatestate", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html; charset=utf-8");
return "";
});
// http://ip_address:port/api/{userId}/lights/{lightId}/bridgeupdatestate uses json object to update the internal bridge lights state.
// THIS IS NOT A HUE API CALL... It is for state management if so desired.
put(HUE_CONTEXT + "/:userid/lights/:id/bridgeupdatestate", "application/json", (request, response) -> {
String userId = request.params(":userid");
String lightId = request.params(":id");
String responseString = null;
DeviceState state = null;
log.debug("Update state requested: " + userId + " from " + request.ip() + " body: " + request.body());
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json; charset=utf-8");
response.status(HttpStatus.SC_OK);
try {
state = mapper.readValue(request.body(), DeviceState.class);
} catch (IOException e) {
log.warn("Object mapper barfed on input of body.", e);
responseString = "[{\"error\":{\"type\": 2, \"address\": \"/lights/" + lightId + "\",\"description\": \"Object mapper barfed on input of body.\"}}]";
return responseString;
}
DeviceDescriptor device = repository.findOne(lightId);
if (device == null) {
log.warn("Could not find device: " + lightId + " for hue state change request: " + userId + " from " + request.ip() + " body: " + request.body());
responseString = "[{\"error\":{\"type\": 3, \"address\": \"/lights/" + lightId + "\",\"description\": \"Could not find device\", \"resource\": \"/lights/" + lightId + "\"}}]";
return responseString;
}
responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":";
if(request.body().contains("bri"))
{
responseString = responseString + "true}},{\"success\":{\"/lights/" + lightId + "/state/bri\":" + state.getBri() + "}}]";
}
else
{
if (state.isOn()) {
responseString = responseString + "true}}]";
state.setBri(255);
} else if (request.body().contains("false")) {
responseString = responseString + "false}}]";
state.setBri(0);
}
}
device.setDeviceSetValue(state.getBri());
device.setDeviceState(state.isOn());
return responseString;
});
// http://ip_address:port/api/:userid/lights/:id/state CORS request // http://ip_address:port/api/:userid/lights/:id/state CORS request
options(HUE_CONTEXT + "/:userid/lights/:id/state", "application/json", (request, response) -> { options(HUE_CONTEXT + "/:userid/lights/:id/state", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK); response.status(HttpStatus.SC_OK);

View File

@@ -450,6 +450,7 @@ app.service('bridgeService', function ($http, $window, ngToast) {
filename: afilename filename: afilename
}).then( }).then(
function (response) { function (response) {
self.state.settings = response.data;
self.viewConfigs(); self.viewConfigs();
self.viewDevices(); self.viewDevices();
}, },
@@ -765,6 +766,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildDeviceUrls = function (veradevice, dim_control) { $scope.buildDeviceUrls = function (veradevice, dim_control) {
bridgeService.clearDevice();
$scope.device.deviceType = "switch"; $scope.device.deviceType = "switch";
$scope.device.name = veradevice.name; $scope.device.name = veradevice.name;
$scope.device.targetDevice = veradevice.veraname; $scope.device.targetDevice = veradevice.veraname;
@@ -789,6 +791,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildSceneUrls = function (verascene) { $scope.buildSceneUrls = function (verascene) {
bridgeService.clearDevice();
$scope.device.deviceType = "scene"; $scope.device.deviceType = "scene";
$scope.device.name = verascene.name; $scope.device.name = verascene.name;
$scope.device.targetDevice = verascene.veraname; $scope.device.targetDevice = verascene.veraname;
@@ -813,6 +816,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
bridgeService.viewVeraScenes(); bridgeService.viewVeraScenes();
}, },
function (error) { function (error) {
bridgeService.displayWarn("Error adding device: " + $scope.device.name, error)
} }
); );
@@ -892,6 +896,7 @@ app.controller('HarmonyController', function ($scope, $location, $http, bridgeSe
}; };
$scope.buildActivityUrls = function (harmonyactivity) { $scope.buildActivityUrls = function (harmonyactivity) {
bridgeService.clearDevice();
$scope.device.deviceType = "activity"; $scope.device.deviceType = "activity";
$scope.device.targetDevice = harmonyactivity.hub; $scope.device.targetDevice = harmonyactivity.hub;
$scope.device.name = harmonyactivity.activity.label; $scope.device.name = harmonyactivity.activity.label;
@@ -902,6 +907,7 @@ app.controller('HarmonyController', function ($scope, $location, $http, bridgeSe
}; };
$scope.buildButtonUrls = function (harmonydevice, onbutton, offbutton) { $scope.buildButtonUrls = function (harmonydevice, onbutton, offbutton) {
bridgeService.clearDevice();
var currentOn = $scope.device.onUrl; var currentOn = $scope.device.onUrl;
var currentOff = $scope.device.offUrl; var currentOff = $scope.device.offUrl;
var actionOn = angular.fromJson(onbutton); var actionOn = angular.fromJson(onbutton);
@@ -966,6 +972,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildNestHomeUrls = function (nestitem) { $scope.buildNestHomeUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "home"; $scope.device.deviceType = "home";
$scope.device.name = nestitem.name; $scope.device.name = nestitem.name;
$scope.device.targetDevice = nestitem.name; $scope.device.targetDevice = nestitem.name;
@@ -976,6 +983,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildNestTempUrls = function (nestitem) { $scope.buildNestTempUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo"; $scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Temperature"; $scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Temperature";
$scope.device.targetDevice = nestitem.location; $scope.device.targetDevice = nestitem.location;
@@ -986,6 +994,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildNestHeatUrls = function (nestitem) { $scope.buildNestHeatUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo"; $scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Heat"; $scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Heat";
$scope.device.targetDevice = nestitem.location; $scope.device.targetDevice = nestitem.location;
@@ -996,6 +1005,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildNestCoolUrls = function (nestitem) { $scope.buildNestCoolUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo"; $scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Cool"; $scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Cool";
$scope.device.targetDevice = nestitem.location; $scope.device.targetDevice = nestitem.location;
@@ -1006,6 +1016,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildNestRangeUrls = function (nestitem) { $scope.buildNestRangeUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo"; $scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Range"; $scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Range";
$scope.device.targetDevice = nestitem.location; $scope.device.targetDevice = nestitem.location;
@@ -1016,6 +1027,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildNestOffUrls = function (nestitem) { $scope.buildNestOffUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo"; $scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Thermostat"; $scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Thermostat";
$scope.device.targetDevice = nestitem.location; $scope.device.targetDevice = nestitem.location;
@@ -1026,6 +1038,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildNestFanUrls = function (nestitem) { $scope.buildNestFanUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo"; $scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Fan"; $scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Fan";
$scope.device.targetDevice = nestitem.location; $scope.device.targetDevice = nestitem.location;
@@ -1072,7 +1085,7 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
$scope.device_dim_control = ""; $scope.device_dim_control = "";
$scope.bulk = { devices: [] }; $scope.bulk = { devices: [] };
var veraList = angular.fromJson($scope.bridge.settings.veraaddress); var veraList = angular.fromJson($scope.bridge.settings.veraaddress);
if(veraList != null && veraList.length > 0) if(veraList != null && veraList.devices.length > 0)
$scope.vera = {base: "http://" + veraList.devices[0].ip, port: "3480", id: ""}; $scope.vera = {base: "http://" + veraList.devices[0].ip, port: "3480", id: ""};
else else
$scope.vera = {base: "http://", port: "3480", id: ""}; $scope.vera = {base: "http://", port: "3480", id: ""};
@@ -1084,9 +1097,7 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildUrlsUsingDevice = function (dim_control) { $scope.buildUrlsUsingDevice = function (dim_control) {
if ($scope.vera.base.indexOf("http") < 0) { bridgeService.clearDevice();
$scope.vera.base = "http://" + $scope.vera.base;
}
$scope.device.deviceType = "switch"; $scope.device.deviceType = "switch";
$scope.device.targetDevice = "Encapsulated"; $scope.device.targetDevice = "Encapsulated";
$scope.device.mapType = "veraDevice"; $scope.device.mapType = "veraDevice";
@@ -1110,9 +1121,7 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
}; };
$scope.buildUrlsUsingScene = function () { $scope.buildUrlsUsingScene = function () {
if ($scope.vera.base.indexOf("http") < 0) { bridgeService.clearDevice();
$scope.vera.base = "http://" + $scope.vera.base;
}
$scope.device.deviceType = "scene"; $scope.device.deviceType = "scene";
$scope.device.targetDevice = "Encapsulated"; $scope.device.targetDevice = "Encapsulated";
$scope.device.mapType = "veraScene"; $scope.device.mapType = "veraScene";