Updated the bridge to handle a new dimming and value control context,

$intensity.mat{(X*1)} for custom calculations. Also, added helpers for
generating URLS on the value contexts.
This commit is contained in:
Admin
2015-10-09 14:28:05 -05:00
parent c8fb93eeb6
commit aebde7ee48
7 changed files with 77 additions and 23 deletions

View File

@@ -1,5 +1,5 @@
# ha-bridge
Emulates philips hue api to other home automation gateways. The Amazon echo now supports wemo and philips hue.
Emulates Philips Hue api to other home automation gateways such as an Amazon Echo. The Bridge has helpers to build devices for the gateway for the Vera, Vera Lite or Vera Edge. Alternatively the Bridge supports custom calls as well. The Bridge handles basic commands such as "On", "Off" and "brightness" commands of the hue protocol.
## Build
To customize and build it yourself, build a new jar with maven:
```
@@ -44,8 +44,8 @@ POST http://host:8080/api/devices
"offUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41"
}
```
## Dimming
Dimming is also supported by using the expessions ${intensity.percent} or ${intensity.byte} for 0-100 and 0-255 respectively.
## Dimming and value passing control
Dimming is also supported by using the expressions ${intensity.percent} for 0-100 or ${intensity.byte} for 0-255 or $intensity{match(<your expression using "X" as the value to operate on>)} i.e. "$intensity.math(X/4)}".
e.g.
```
{
@@ -61,9 +61,10 @@ See the echo's documentation for the dimming phrase.
added optional fields
* contentType (currently un-validated)
* httpVerb (POST/PUT/GET only supported)
* contentBody your post/put body here
* contentBody your post/put body for onUrl here
* contentBodyOff your post/put body for offUrl here
This will allow control of any other application that may need more then GET.
This will allow control of any other application that may need more then GET. You can also use the dimming and value control commands within the URLs as well.
e.g:
```
{
@@ -73,10 +74,12 @@ e.g:
"onUrl": "http://192.168.1.201:3480/data_request?id=action&output_format=json&DeviceNum=31&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=${intensity.percent}",
"contentType" : "application/json",
"httpVerb":"POST",
"contentBody" : "{\"fooBar\":\"baz\"}"
"contentBody" : "{\"fooBar\":\"baz_on\"}"
"contentBodyOff" : "{\"fooBar\":\"baz_off\"}"
}
```
Anything that takes an action as a result of an HTTP request will probably work - like putting Vera in and out of night mode:
## Custom Usage URLs
Anything that takes an action as a result of an HTTP request will probably work and you can also use the dimming and value control commands within the URLs as well - like putting Vera in and out of night mode:
```
{
"name": "night mode",

View File

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

View File

@@ -9,7 +9,9 @@ import com.bwssystems.HABridge.dao.*;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.ScriptEngine;
import static spark.Spark.get;
import static spark.Spark.post;
import static spark.Spark.put;
@@ -42,6 +44,10 @@ public class HueMulator {
private static final Logger log = LoggerFactory.getLogger(HueMulator.class);
private static final String INTENSITY_PERCENT = "${intensity.percent}";
private static final String INTENSITY_BYTE = "${intensity.byte}";
private static final String INTENSITY_MATH = "${intensity.math(";
private static final String INTENSITY_MATH_VALUE = "X";
private static final String INTENSITY_MATH_CLOSE = ")}";
private static final String ENGINE_JAVASCRIPT = "JavaScript";
private static final String HUE_CONTEXT = "/api";
private DeviceRepository repository;
@@ -241,7 +247,18 @@ public class HueMulator {
int percentBrightness = (int) Math.round(intensity/255.0*100);
String intensityPercent = String.valueOf(percentBrightness);
request = request.replace(INTENSITY_PERCENT, intensityPercent);
}
} else if(request.contains(INTENSITY_MATH)){
String mathDescriptor = request.substring(request.indexOf(INTENSITY_MATH) + INTENSITY_MATH.length(),request.indexOf(INTENSITY_MATH_CLOSE));
String updatedMath = mathDescriptor.replace(INTENSITY_MATH_VALUE, String.valueOf(intensity));
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName(ENGINE_JAVASCRIPT);
try {
log.debug("Math eval is: " + updatedMath);
Integer endResult = (Integer) engine.eval(updatedMath);
request = request.replace(INTENSITY_MATH + mathDescriptor + INTENSITY_MATH_CLOSE, endResult.toString());
} catch (ScriptException e) {
log.error("Could not execute Math: " + updatedMath, e);
} }
return request;
}

View File

@@ -36,7 +36,7 @@
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a href="http://www.bwssystems.com" target="_blank">Developed by BWS Systems</a></li>
<li><a href="http://www.amazon.com/echo" target="_blank">Amazon Echo</a></li>
<li><a href="">HA Bridge Version 0.4.7</a></li>
<li><a href="">HA Bridge Version 0.4.8</a></li>
</ul>
</li>
</ul>

View File

@@ -304,18 +304,26 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
$scope.device = bridgeService.state.device;
$scope.predicate = '';
$scope.reverse = true;
$scope.device_dim_control = "";
$scope.order = function(predicate) {
$scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false;
$scope.predicate = predicate;
};
$scope.buildUrlsUsingDevice = function () {
$scope.buildUrlsUsingDevice = function (dim_control) {
if ($scope.vera.base.indexOf("http") < 0) {
$scope.vera.base = "http://" + $scope.vera.base;
}
$scope.device.onUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum="
+ $scope.vera.id;
if(dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)
$scope.device.onUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&DeviceNum="
+ $scope.vera.id
+ "&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget="
+ dim_control;
else
$scope.device.onUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum="
+ $scope.vera.id;
$scope.device.offUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum="
+ $scope.vera.id;
@@ -334,15 +342,22 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
+ $scope.vera.id;
};
$scope.buildDeviceUrls = function (veradevice) {
$scope.buildDeviceUrls = function (veradevice, dim_control) {
if ($scope.vera.base.indexOf("http") < 0) {
$scope.vera.base = "http://" + $scope.vera.base;
}
$scope.device.deviceType = "switch";
$scope.device.name = veradevice.name;
$scope.device.onUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum="
+ veradevice.id;
if(dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)
$scope.device.onUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&DeviceNum="
+ veradevice.id
+ "&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget="
+ dim_control;
else
$scope.device.onUrl = $scope.vera.base + ":" + $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.offUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum="
+ veradevice.id;

View File

@@ -44,7 +44,19 @@
</div>
</div>
<div class="form-group">
<button type="submit" ng-click="buildUrlsUsingDevice()"
<label class="col-xs-2 col-sm-2 control-label" for="device-dim-control">Device Dim Control</label>
<div class="col-xs-10 col-sm-2">
<select name="device-dim-control" id="device-dim-control" ng-model="device_dim_control">
<option value="">none</option>
<option value="${intensity..byte}">Pass-thru Value</option>
<option value="${intensity.percent}">Percentage</option>
<option value="${intensity.math(X*1)}">Custom Math</option>
</select>
</div>
</div>
<div class="form-group">
<button type="submit" ng-click="buildUrlsUsingDevice(device_dim_control)"
class="col-xs-2 col-sm-2 col-xs-offset-2 col-sm-offset-2 btn btn-success">Generate Device
URLs</button>
<button type="submit" ng-click="buildUrlsUsingScene()"

View File

@@ -12,8 +12,15 @@
<ul class="list-group">
<li class="list-group-item">
<p class="text-muted">You can select a Vera device and generate
the add device box selections automatically.</p>
the add device box selections automatically.</p><p>Also, use this select menu for which type of dim
control you would like to be generated:
<select name="device-dim-control" id="device-dim-control" ng-model="device_dim_control">
<option value="">none</option>
<option value="${intensity..byte}">Pass-thru Value</option>
<option value="${intensity.percent}">Percentage</option>
<option value="${intensity.math(X*1)}">Custom Math</option>
</select>
</p>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
@@ -43,7 +50,7 @@
<td>{{veradevice.room}}</td>
<td>
<button class="btn btn-success" type="submit"
ng-click="buildDeviceUrls(veradevice)">Generate
ng-click="buildDeviceUrls(veradevice, device_dim_control)">Generate
Device URLs</button>
</td>
</tr>