mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-16 18:24:36 +00:00
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:
17
README.md
17
README.md
@@ -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",
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()"
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user