Adding Harmony Hub Control directly into the Bridge. First iteration

updates the ui harness. Also, updated settings in the configuration
page.
This commit is contained in:
Admin
2015-10-26 16:35:51 -05:00
parent c872f3543d
commit 295b1e1a30
15 changed files with 387 additions and 73 deletions

View File

@@ -5,7 +5,7 @@ To customize and build it yourself, build a new jar with maven:
```
mvn install
```
Otherwise go to http://www.bwssystems.com/apps.html to download the latest jar file.
Otherwise, downloads are available at https://github.com/bwssytems/ha-bridge/releases.
## Run
Then locate the jar and start the server with:
```
@@ -22,6 +22,12 @@ The server defaults to running on port 8080. If you're already running a server
The default location for the db to contain the devices as they are added is "data/devices.db". If you would like a different filename or directory, specify -Dupnp.devices.db=`<directory>/<filename> or <filename>` if it is the same directory.
### -Dupnp.response.port=`<port>`
The upnp response port that will be used. The default is 50000.
### -Dharmony.address=`<ip address>`
The argument for the Harmony Hub address should be given as the system does not have a way to find the address. Supply -Dharmony.address=X.Y.Z.A on the command line to provide it. If a Harmony Hub is not used, do not set it.
### -Dharmony.user=`<username>`
The user name of the MyHarmony.com account for the Harmony Hub. This needs to be given if you are using the Harmony Hub Features, provide -Dharmony.user=`<username>` on the command line.
### -Dharmony.pwd=`<password>`
The password for the user name of the MyHarmony.com account for the Harmony Hub. This needs to be given if you are using the Harmony Hub Features, provide -Dharmony.pwd=`<password>` on the command line.
### -Dupnp.strict=`<true|false>`
Upnp has been very closed on this platform to try and respond as a hue and there is now a setting to control if it is more open or strict, Add -Dupnp.strict=`<true|false>` to your command line to have the emulator respond to what it thinks is an echo to a hue or any other device. The default is upnp.strict=true.
### -Dtrace.upnp=`<true|false>`

View File

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

View File

@@ -6,6 +6,9 @@ public class BridgeSettings {
private String upnpresponseport;
private String upnpdevicedb;
private String veraaddress;
private String harmonyaddress;
private String harmonyuser;
private String harmonypwd;
private boolean upnpstrict;
private boolean traceupnp;
private boolean vtwocompatibility;
@@ -41,6 +44,24 @@ public class BridgeSettings {
this.veraaddress = veraAddress;
}
public String getHarmonyAddress() {
return harmonyaddress;
}
public void setHarmonyAddress(String harmonyaddress) {
this.harmonyaddress = harmonyaddress;
}
public String getHarmonyUser() {
return harmonyuser;
}
public void setHarmonyUser(String harmonyuser) {
this.harmonyuser = harmonyuser;
}
public String getHarmonyPwd() {
return harmonypwd;
}
public void setHarmonyPwd(String harmonypwd) {
this.harmonypwd = harmonypwd;
}
public boolean isUpnpStrict() {
return upnpstrict;
}
@@ -66,4 +87,9 @@ public class BridgeSettings {
return false;
return true;
}
public Boolean isValidHarmony() {
if(this.harmonyaddress.contains(Configuration.DEFAULT_HARMONY_ADDRESS))
return false;
return true;
}
}

View File

@@ -4,5 +4,8 @@ public class Configuration {
public final static String DEVICE_DB_DIRECTORY = "data/device.db";
public final static String UPNP_RESPONSE_PORT = "50000";
public final static String DEFAULT_VERA_ADDRESS = "1.1.1.1";
public final static String DEFAULT_HARMONY_ADDRESS = "1.1.1.1";
public final static String DEFAULT_HARMONY_USER = "";
public final static String DEFAULT_HARMONY_PWD = "";
public final static String DFAULT_WEB_PORT = "8080";
}

View File

@@ -40,7 +40,7 @@ public class HABridge {
String addressString;
BridgeSettings bridgeSettings;
log.info("HA Bridge (v0.4.10) starting setup....");
log.info("HA Bridge (v1.0.0) starting setup....");
//get ip address for upnp requests
try {
address = InetAddress.getLocalHost();
@@ -55,6 +55,9 @@ public class HABridge {
bridgeSettings.setUpnpDeviceDb(System.getProperty("upnp.device.db", Configuration.DEVICE_DB_DIRECTORY));
bridgeSettings.setUpnpResponsePort(System.getProperty("upnp.response.port", Configuration.UPNP_RESPONSE_PORT));
bridgeSettings.setVeraAddress(System.getProperty("vera.address", Configuration.DEFAULT_VERA_ADDRESS));
bridgeSettings.setHarmonyAddress(System.getProperty("harmony.address", Configuration.DEFAULT_HARMONY_ADDRESS));
bridgeSettings.setHarmonyUser(System.getProperty("harmony.user", Configuration.DEFAULT_HARMONY_USER));
bridgeSettings.setHarmonyPwd(System.getProperty("harmony.pwd", Configuration.DEFAULT_HARMONY_PWD));
bridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "true")));
bridgeSettings.setTraceupnp(Boolean.parseBoolean(System.getProperty("trace.upnp", "false")));
bridgeSettings.setVtwocompatibility(Boolean.parseBoolean(System.getProperty("vtwo.compatibility", "false")));

View File

@@ -0,0 +1,5 @@
package com.bwssystems.harmony;
public class HarmonyActivities {
}

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.10</a></li>
<li><a href="">HA Bridge Version 1.0.0</a></li>
</ul>
</li>
</ul>

View File

@@ -4,6 +4,9 @@ var app = angular.module('habridge', [
app.config(function ($routeProvider) {
$routeProvider.when('/#', {
templateUrl: 'views/nonconfiguration.html',
controller: 'ViewingController'
}).when('/show', {
templateUrl: 'views/configuration.html',
controller: 'ViewingController'
}).when('/editor', {
@@ -18,8 +21,11 @@ app.config(function ($routeProvider) {
}).when('/verascenes', {
templateUrl: 'views/verascene.html',
controller: 'AddingController'
}).when('/harmonyactivities', {
templateUrl: 'views/harmonyactivity.html',
controller: 'AddingController'
}).otherwise({
templateUrl: 'views/configuration.html',
templateUrl: 'views/nonconfiguration.html',
controller: 'ViewingController'
})
});
@@ -37,6 +43,7 @@ app.factory('BridgeSettings', function() {
BridgeSettings.upnpdevicedb = "";
BridgeSettings.upnpresponseport = "";
BridgeSettings.veraaddress = "";
BridgeSettings.harmonyaddress = "";
BridgeSettings.upnpstrict = "";
BridgeSettings.traceupnp = "";
BridgeSettings.vtwocompatibility = "";
@@ -60,6 +67,9 @@ app.factory('BridgeSettings', function() {
BridgeSettings.setveraaddress = function(averaaddress){
BridgeSettings.veraaddress = averaaddress;
};
BridgeSettings.setharmonyaddress = function(aharmonyaddress){
BridgeSettings.harmonyaddress = aharmonyaddress;
};
BridgeSettings.setupnpstrict = function(aupnpstrict){
BridgeSettings.upnpstrict = aupnpstrict;
};
@@ -76,7 +86,7 @@ app.factory('BridgeSettings', function() {
app.service('bridgeService', function ($http, $window, BridgeSettings) {
var self = this;
self.BridgeSettings = BridgeSettings;
this.state = {base: window.location.origin + "/api/devices", upnpbase: window.location.origin + "/upnp/settings", devices: [], device: [], error: "", showVera: false};
this.state = {base: window.location.origin + "/api/devices", upnpbase: window.location.origin + "/upnp/settings", devices: [], device: [], error: "", showVera: false, showHarmony: false};
this.viewDevices = function () {
this.state.error = "";
@@ -105,6 +115,7 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
self.BridgeSettings.setupnpdevicedb(response.data.upnpdevicedb);
self.BridgeSettings.setupnpresponseport(response.data.upnpresponseport);
self.BridgeSettings.setveraaddress(response.data.veraaddress);
self.BridgeSettings.setharmonyaddress(response.data.harmonyaddress);
self.BridgeSettings.settraceupnp(response.data.traceupnp);
self.BridgeSettings.setupnpstrict(response.data.upnpstrict);
self.BridgeSettings.setvtwocompatibility(response.data.vtwocompatibility);
@@ -112,6 +123,10 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
self.state.showVera = false;
else
self.state.showVera = true;
if(self.BridgeSettings.harmonyaddress == "1.1.1.1" || self.BridgeSettings.harmonyaddress == "")
self.state.showHarmony = false;
else
self.state.showHarmony = true;
},
function (error) {
if (error.data) {
@@ -132,6 +147,14 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
return;
}
this.updateShowHarmony = function () {
if(self.BridgeSettings.harmonyaddress == "1.1.1.1" || self.BridgeSettings.harmonyaddress == "")
self.state.showHarmony = false;
else
self.state.showHarmony = true;
return;
}
this.viewVeraDevices = function () {
this.state.error = "";
if(BridgeSettings.veraaddress == "1.1.1.1" || BridgeSettings.veraaddress == "")
@@ -246,6 +269,7 @@ app.controller('ViewingController', function ($scope, $location, $http, $window,
bridgeService.viewDevices();
$scope.bridge = bridgeService.state;
bridgeService.updateShowVera();
bridgeService.updateShowHarmony();
$scope.predicate = '';
$scope.reverse = true;
$scope.order = function(predicate) {
@@ -321,6 +345,7 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
bridgeService.viewVeraScenes();
$scope.bridge = bridgeService.state;
bridgeService.updateShowVera();
bridgeService.updateShowHarmony();
$scope.device = bridgeService.state.device;
$scope.predicate = '';
$scope.reverse = true;
@@ -397,6 +422,20 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
+ verascene.id;
};
$scope.buildActivityUrls = function (harmonyactivity) {
if ($scope.vera.base.indexOf("http") < 0) {
$scope.vera.base = "http://" + $scope.vera.base;
}
$scope.device.deviceType = "scene";
$scope.device.name = verascene.name;
$scope.device.onUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunScene&SceneNum="
+ verascene.id;
$scope.device.offUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunScene&SceneNum="
+ verascene.id;
};
$scope.testUrl = function (url) {
if(type == "on") {
if(device.httpVerb == "PUT")

View File

@@ -2,72 +2,10 @@
<li role="presentation" class="active"><a href="#">Configuration</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
<li role="presentation"><a href="#/editor">Manual Add</a></li>
</ul>
<div class="panel panel-default bridgeServer">
<div class="panel-heading">
<h1 class="panel-title">Bridge settings</h1>
</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label class="col-xs-12 col-sm-3 control-label" for="bridge-base">Bridge
server</label>
<div class="col-xs-8 col-sm-7">
<input id="bridge-base" class="form-control" type="text"
ng-model="bridge.base" placeholder="URL to bridge">
</div>
<button type="submit" class="col-xs-2 col-sm-1 btn btn-primary"
ng-click="setBridgeUrl(bridge.base)">Load</button>
<button type="submit" class="col-xs-2 col-sm-1 btn btn-primary"
ng-click="testUrl(bridge.base)">Go</button>
</div>
</form>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Setting</th>
<th>Value</th>
</tr>
</thead>
<tr>
<td>upnp.config.address</td>
<td>{{BridgeSettings.upnpconfigaddress}}</td>
</tr>
<tr>
<td>server.port</td>
<td>{{BridgeSettings.serverport}}</td>
</tr>
<tr>
<td>upnp.devices.db</td>
<td>{{BridgeSettings.upnpdevicedb}}</td>
</tr>
<tr>
<td>upnp.response.port</td>
<td>{{BridgeSettings.upnpresponseport}}</td>
</tr>
<tr>
<td>vera.address</td>
<td>{{BridgeSettings.veraaddress}}</td>
</tr>
<tr>
<td>upnp.strict</td>
<td>{{BridgeSettings.upnpstrict}}</td>
</tr>
<tr>
<td>trace.upnp</td>
<td>{{BridgeSettings.traceupnp}}</td>
</tr>
<tr>
<td>vtwo.compatibility</td>
<td>{{BridgeSettings.vtwocompatibility}}</td>
</tr>
</table>
</div>
</div>
<div ng-controller="ErrorsController">
<div ng-if="bridge.error"
@@ -118,3 +56,72 @@
</tr>
</table>
</div>
<div class="panel panel-default bridgeServer">
<div class="panel-heading">
<a href="#/"><span class="glyphicon glyphicon-minus" aria-hidden="true"></span></a>
<h1 class="panel-title">Bridge settings</h1>
</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label class="col-xs-12 col-sm-3 control-label" for="bridge-base">Bridge
server</label>
<div class="col-xs-8 col-sm-7">
<input id="bridge-base" class="form-control" type="text"
ng-model="bridge.base" placeholder="URL to bridge">
</div>
<button type="submit" class="col-xs-2 col-sm-1 btn btn-primary"
ng-click="setBridgeUrl(bridge.base)">Load</button>
<button type="submit" class="col-xs-2 col-sm-1 btn btn-primary"
ng-click="testUrl(bridge.base)">Go</button>
</div>
</form>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Setting</th>
<th>Value</th>
</tr>
</thead>
<tr>
<td>upnp.config.address</td>
<td>{{BridgeSettings.upnpconfigaddress}}</td>
</tr>
<tr>
<td>server.port</td>
<td>{{BridgeSettings.serverport}}</td>
</tr>
<tr>
<td>upnp.devices.db</td>
<td>{{BridgeSettings.upnpdevicedb}}</td>
</tr>
<tr>
<td>upnp.response.port</td>
<td>{{BridgeSettings.upnpresponseport}}</td>
</tr>
<tr>
<td>vera.address</td>
<td>{{BridgeSettings.veraaddress}}</td>
</tr>
<tr>
<td>harmony.address</td>
<td>{{BridgeSettings.harmonyaddress}}</td>
</tr>
<tr>
<td>upnp.strict</td>
<td>{{BridgeSettings.upnpstrict}}</td>
</tr>
<tr>
<td>trace.upnp</td>
<td>{{BridgeSettings.traceupnp}}</td>
</tr>
<tr>
<td>vtwo.compatibility</td>
<td>{{BridgeSettings.vtwocompatibility}}</td>
</tr>
</table>
</div>
</div>

View File

@@ -2,6 +2,7 @@
<li role="presentation"><a href="#">Configuration</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
<li role="presentation"><a href="#/editor">Manual Add</a></li>
<li role="presentation" class="active"><a href="#/editdevice">Edit Device</a></li>
</ul>

View File

@@ -2,10 +2,11 @@
<li role="presentation"><a href="#">Configuration</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
<li role="presentation" class="active"><a href="#/editor">Manual Add</a></li>
</ul>
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
<div class="panel panel-default bridgeServer" ng-if="bridge.showVera">
<div class="panel-heading">
<h2 class="panel-title">Generate a new device/scene/control point</h2>
</div>

View File

@@ -0,0 +1,158 @@
<ul class="nav nav-pills" role="tablist">
<li role="presentation"><a href="#">Configuration</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
<li role="presentation" class="active"><a href="#/harmonyactivities">Harmony Activities</a></li>
<li role="presentation"><a href="#/editor">Manual Add</a></li>
</ul>
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
<div class="panel-heading">
<h2 class="panel-title">Harmony Activity List</h2>
</div>
<ul class="list-group">
<li class="list-group-item">
<p class="text-muted">You can select a Harmony Activity and generate
the add activity box selections automatically.</p>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>
<a href="" ng-click="order('name')">Name</a>
<span class="sortorder" ng-show="predicate === 'name'" ng-class="{reverse:reverse}"></span>
</th>
<th>
<a href="" ng-click="order('id')">Id</a>
<span class="sortorder" ng-show="predicate === 'id'" ng-class="{reverse:reverse}"></span>
</th>
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="harmonyactivitye in bridge.harmonyactivities | orderBy:predicate:reverse">
<td>{{harmonyactivity.name}}</td>
<td>{{harmonyactivity.id}}</td>
<td>
<button class="btn btn-success" type="submit"
ng-click="buildActivityUrls(harmonyactivity)">Generate
Activity URLs</button>
</td>
</tr>
</table>
</li>
</ul>
</div>
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
<div class="panel-heading">
<h2 class="panel-title">Add a Harmony Activity</h2>
</div>
<ul class="list-group">
<li class="list-group-item">
<form class="form-horizontal" ng-submit="addDevice()">
<div class="form-group">
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
</label>
<div class="col-xs-8 col-sm-7">
<input type="text" class="form-control" id="device-name"
ng-model="device.name" placeholder="Device Name">
</div>
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary">
Add Activity</button>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
URL </label>
<div class="col-xs-8 col-sm-7">
<textarea rows="3" class="form-control" id="device-on-url"
ng-model="device.onUrl" placeholder="URL to turn device on"></textarea>
</div>
<div class="clearfix visible-xs"></div>
<button class="col-xs-4 col-sm-2 btn btn-success" type="button"
ng-click="testUrl(device, 'on')">Test</button>
</div>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-12 col-sm-2 control-label"
for="device-off-url">Off URL </label>
<div class="col-xs-8 col-sm-7">
<textarea rows="3" class="form-control" id="device-off-url"
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
</div>
<div class="clearfix visible-xs"></div>
<button class="col-xs-4 col-sm-2 btn btn-success" type="button"
ng-click="testUrl(device, 'off')">Test</button>
</div>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-12 col-sm-2 control-label" for="device-http-verb">Http Verb
</label>
<div class="col-xs-8 col-sm-7">
<select name="device-http-verb" id="device-http-verb" ng-model="device.httpVerb">
<option value="">---Please select---</option> <!-- not selected / blank option -->
<option value="GET">GET</option>
<option value="PUT">PUT</option>
<option value="POST">POST</option>
</select>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-12 col-sm-2 control-label" for="device-content-type">Content Type
</label>
<div class="col-xs-8 col-sm-7">
<select name="device-content-type" id="device-content-type" ng-model="device.contentType">
<option value="">---Please select---</option> <!-- not selected / blank option -->
<option value="application/atom+xml">application/atom+xml</option>
<option value="application/x-www-form-urlencoded">application/x-www-form-urlencoded</option>
<option value="application/json">application/json</option>
<option value="application/octet-stream">application/octet-stream</option>
<option value="application/svg+xml">application/svg+xml</option>
<option value="application/xhtml+xml">application/xhtml+xml</option>
<option value="application/xml">application/xml</option>
<option value="*">*</option>
<option value="multipart/form-data">multipart/form-data</option>
<option value="text/html">text/html</option>
<option value="text/plain">text/plain</option>
<option value="text/xml">text/xml</option>
<option value="*/*">*/*</option>
</select>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-12 col-sm-2 control-label"
for="device-content-body">Content Body On</label>
<div class="col-xs-8 col-sm-7">
<textarea rows="3" class="form-control" id="device-content-body"
ng-model="device.contentBody" placeholder="Content Body On for specific GET/PUT/POST type"></textarea>
</div>
<div class="clearfix visible-xs"></div>
</div>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-12 col-sm-2 control-label"
for="device-content-body-off">Content Body Off</label>
<div class="col-xs-8 col-sm-7">
<textarea rows="3" class="form-control" id="device-content-body-off"
ng-model="device.contentBodyOff" placeholder="Content Body Off for specific GET/PUT/POST type"></textarea>
</div>
<div class="clearfix visible-xs"></div>
</div>
</div>
</form>
</li>
</ul>
</div>

View File

@@ -0,0 +1,63 @@
<ul class="nav nav-pills" role="tablist">
<li role="presentation" class="active"><a href="#">Configuration</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
<li role="presentation"><a href="#/editor">Manual Add</a></li>
</ul>
<div ng-controller="ErrorsController">
<div ng-if="bridge.error"
class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert"
aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h2 ng-show='bridge.error != ""'>ERROR</h2>
<div ng-show='bridge.error != ""'>{{bridge.error}}</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">Current devices</h2>
</div>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>
<a href="" ng-click="order('id')">ID</a>
<span class="sortorder" ng-show="predicate === 'id'" ng-class="{reverse:reverse}"></span></th>
<th>
<a href="" ng-click="order('name')">Name</a>
<span class="sortorder" ng-show="predicate === 'name'" ng-class="{reverse:reverse}"></span></th>
<th>
<a href="" ng-click="order('deviceType')">Type</a>
<span class="sortorder" ng-show="predicate === 'deviceType'" ng-class="{reverse:reverse}"></span></th>
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="device in bridge.devices | orderBy:predicate:reverse">
<td>{{device.id}}</td>
<td>{{device.name}}</td>
<td>{{device.deviceType}}</td>
<td>
<button class="btn btn-info" type="submit"
ng-click="testUrl(device, 'on')">Test ON</button>
<button class="btn btn-info" type="submit"
ng-click="testUrl(device, 'off')">Test OFF</button>
<button class="btn btn-warning" type="submit"
ng-click="editDevice(device)">Edit</button>
<button class="btn btn-danger" type="submit"
ng-click="deleteDevice(device)">Delete</button>
</td>
</tr>
</table>
</div>
<div class="panel panel-default bridgeServer">
<div class="panel-heading">
<a href="#/show"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></a>
<h1 class="panel-title">Bridge settings</h1>
</div>
</div>

View File

@@ -2,6 +2,7 @@
<li role="presentation"><a href="#">Configuration</a></li>
<li role="presentation" class="active"><a href="#/veradevices">Vera Devices</a></li>
<li role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
<li role="presentation"><a href="#/editor">Manual Add</a></li>
</ul>

View File

@@ -2,6 +2,7 @@
<li role="presentation"><a href="#">Configuration</a></li>
<li role="presentation"><a href="#/veradevices">Vera Devices</a></li>
<li role="presentation" class="active"><a href="#/verascenes">Vera Scenes</a></li>
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
<li role="presentation"><a href="#/editor">Manual Add</a></li>
</ul>
@@ -12,7 +13,7 @@
<ul class="list-group">
<li class="list-group-item">
<p class="text-muted">You can select a Vera scene and generate
the add device box selections automatically.</p>
the add scene box selections automatically.</p>
<table class="table table-bordered table-striped table-hover">
<thead>