Skip to content

Commit

Permalink
Finished implementing and testing state change and bug fixes from
Browse files Browse the repository at this point in the history
testing

Fixes #44
Fixes #60
Fixes #61
Fixes #63
Fixes #66
Fixes #69
  • Loading branch information
bwssytems committed Mar 21, 2016
1 parent 926a7f5 commit 9c3d95f
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 10 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,30 @@ A response to a successful PUT request contains confirmation of the arguments pa
{"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
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.
```
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId>
<version>1.4.1d</version>
<version>1.4.2</version>
<packaging>jar</packaging>

<name>HA Bridge</name>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/bwssystems/HABridge/SystemControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ public void setupServer() {
}
else
log.warn("No filename given for restore backup.");
return null;
return bridgeSettings.getBridgeSettingsDescriptor();
}, new JsonTransformer());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public DeviceRepository(String deviceDb) {
super();
gson =
new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
repositoryPath = null;
repositoryPath = Paths.get(deviceDb);
Expand Down Expand Up @@ -81,7 +82,7 @@ private void put(String id, DeviceDescriptor aDescriptor) {
public void save(DeviceDescriptor[] descriptors) {
String theNames = "";
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());
else
descriptors[i].setId(String.valueOf(random.nextInt(Integer.MAX_VALUE)));
Expand Down
55 changes: 55 additions & 0 deletions src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,61 @@ public void setupServer() {
return lightResponse;
}, 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
options(HUE_CONTEXT + "/:userid/lights/:id/state", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
Expand Down
23 changes: 16 additions & 7 deletions src/main/resources/public/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ app.service('bridgeService', function ($http, $window, ngToast) {
filename: afilename
}).then(
function (response) {
self.state.settings = response.data;
self.viewConfigs();
self.viewDevices();
},
Expand Down Expand Up @@ -765,6 +766,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
};

$scope.buildDeviceUrls = function (veradevice, dim_control) {
bridgeService.clearDevice();
$scope.device.deviceType = "switch";
$scope.device.name = veradevice.name;
$scope.device.targetDevice = veradevice.veraname;
Expand All @@ -789,6 +791,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
};

$scope.buildSceneUrls = function (verascene) {
bridgeService.clearDevice();
$scope.device.deviceType = "scene";
$scope.device.name = verascene.name;
$scope.device.targetDevice = verascene.veraname;
Expand All @@ -813,6 +816,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
bridgeService.viewVeraScenes();
},
function (error) {
bridgeService.displayWarn("Error adding device: " + $scope.device.name, error)
}
);

Expand Down Expand Up @@ -892,6 +896,7 @@ app.controller('HarmonyController', function ($scope, $location, $http, bridgeSe
};

$scope.buildActivityUrls = function (harmonyactivity) {
bridgeService.clearDevice();
$scope.device.deviceType = "activity";
$scope.device.targetDevice = harmonyactivity.hub;
$scope.device.name = harmonyactivity.activity.label;
Expand All @@ -902,6 +907,7 @@ app.controller('HarmonyController', function ($scope, $location, $http, bridgeSe
};

$scope.buildButtonUrls = function (harmonydevice, onbutton, offbutton) {
bridgeService.clearDevice();
var currentOn = $scope.device.onUrl;
var currentOff = $scope.device.offUrl;
var actionOn = angular.fromJson(onbutton);
Expand Down Expand Up @@ -966,6 +972,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
};

$scope.buildNestHomeUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "home";
$scope.device.name = nestitem.name;
$scope.device.targetDevice = nestitem.name;
Expand All @@ -976,6 +983,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
};

$scope.buildNestTempUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Temperature";
$scope.device.targetDevice = nestitem.location;
Expand All @@ -986,6 +994,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
};

$scope.buildNestHeatUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Heat";
$scope.device.targetDevice = nestitem.location;
Expand All @@ -996,6 +1005,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
};

$scope.buildNestCoolUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Cool";
$scope.device.targetDevice = nestitem.location;
Expand All @@ -1006,6 +1016,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
};

$scope.buildNestRangeUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Range";
$scope.device.targetDevice = nestitem.location;
Expand All @@ -1016,6 +1027,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
};

$scope.buildNestOffUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Thermostat";
$scope.device.targetDevice = nestitem.location;
Expand All @@ -1026,6 +1038,7 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
};

$scope.buildNestFanUrls = function (nestitem) {
bridgeService.clearDevice();
$scope.device.deviceType = "thermo";
$scope.device.name = nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Fan";
$scope.device.targetDevice = nestitem.location;
Expand Down Expand Up @@ -1072,7 +1085,7 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
$scope.device_dim_control = "";
$scope.bulk = { devices: [] };
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: ""};
else
$scope.vera = {base: "http://", port: "3480", id: ""};
Expand All @@ -1084,9 +1097,7 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
};

$scope.buildUrlsUsingDevice = function (dim_control) {
if ($scope.vera.base.indexOf("http") < 0) {
$scope.vera.base = "http://" + $scope.vera.base;
}
bridgeService.clearDevice();
$scope.device.deviceType = "switch";
$scope.device.targetDevice = "Encapsulated";
$scope.device.mapType = "veraDevice";
Expand All @@ -1110,9 +1121,7 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
};

$scope.buildUrlsUsingScene = function () {
if ($scope.vera.base.indexOf("http") < 0) {
$scope.vera.base = "http://" + $scope.vera.base;
}
bridgeService.clearDevice();
$scope.device.deviceType = "scene";
$scope.device.targetDevice = "Encapsulated";
$scope.device.mapType = "veraScene";
Expand Down

0 comments on commit 9c3d95f

Please sign in to comment.