Add view setup for angular and pages.

This commit is contained in:
Admin
2015-08-13 16:29:01 -05:00
parent 29e7980939
commit 4a80ce4230
6 changed files with 328 additions and 278 deletions

View File

@@ -11,7 +11,7 @@ Then locate the jar and start the server with:
```
java -jar -Dvera.address=192.168.X.Y ha-bridge-0.X.Y.jar
```
The argument for the vera address should be given as it the system does nto have a way to find the address. Suppply -Dvera.address=X.Y.Z.A on the command line to provide it.
The argument for the vera address should be given as it the system does not have a way to find the address. Supply -Dvera.address=X.Y.Z.A on the command line to provide it.
The server defaults to the first available address on the host. Replace the -Dupnp.config.address=<ip address> value with the server ipv4 address you would like to use.

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" ng-app="habridge">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
@@ -17,22 +17,16 @@
<script type="text/javascript" src="js/html5shiv.min.js"></script>
<script type="text/javascript" src="js/respond.min.js"></script>
<![endif]-->
<script type="text/javascript" src="js/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="scripts/app.js"></script>
</head>
<body ng-app="habridge">
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse" data-target="#navbar" aria-expanded="false"
aria-controls="navbar">
<span class="sr-only">Toggle navigation</span> <span
class="icon-bar"></span> <span class="icon-bar"></span>
<button type="button" class="navbar-toggle">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">HA Bridge</a>
</div>
@@ -51,264 +45,19 @@
</li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<div ng-controller="ViewingController">
<div class="container" ng-view="">
</div>
<div class="page-header">
<h1>Configuration</h1>
</div>
<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>{{bridge.upnpconfigaddress}}</td>
</tr>
<tr>
<td>server.port</td>
<td>{{bridge.serverport}}</td>
</tr>
<tr>
<td>upnp.devices.db</td>
<td>{{bridge.upnpdevicedb}}</td>
</tr>
<tr>
<td>upnp.response.port</td>
<td>{{bridge.upnpresponseport}}</td>
</tr>
<tr>
<td>vera.address</td>
<td>{{bridge.veraaddress}}</td>
</tr>
</table>
</div>
</div>
<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>ID</th>
<th>Name</th>
<th>Type</th>
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="device in bridge.devices">
<td>{{device.id}}</td>
<td>{{device.name}}</td>
<td>{{device.deviceType}}</td>
<td>
<button class="btn btn-info" type="submit" ng-click="testUrl(device.onUrl)">Test ON</button>
<button class="btn btn-info" type="submit" ng-click="testUrl(device.offUrl)">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 ng-controller="AddingController">
<div class="page-header">
<h1>Editor</h1>
</div>
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
<div class="panel-heading">
<h2 class="panel-title">Vera Device List</h2>
</div>
<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>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Id</th>
<th>Category</th>
<th>Room</th>
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="veradevice in bridge.veradevices">
<td>{{veradevice.name}}</td>
<td>{{veradevice.id}}</td>
<td>{{veradevice.category}}</td>
<td>{{veradevice.room}}</td>
<td>
<button class="btn btn-success" type="submit"
ng-click="buildDeviceUrls(veradevice, bridge.veraaddress)">Generate Device 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">Vera Scene List</h2>
</div>
<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>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Id</th>
<th>Room</th>
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="verascene in bridge.verascenes">
<td>{{verascene.name}}</td>
<td>{{verascene.id}}</td>
<td>{{verascene.room}}</td>
<td>
<button class="btn btn-success" type="submit"
ng-click="buildSceneUrls(verascene, bridge.veraaddress)">Generate Device 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">Generate a new device</h2>
</div>
<ul class="list-group">
<li class="list-group-item">
<p class="text-muted">You can generate on/off URLs by filling in the Vera server URL, port, and
device ID; or you can fill them out manually in the lower section.</p>
<form class="form-horizontal">
<div class="form-group">
<label class="col-xs-12 col-sm-2 control-label" for="vera-base">Vera Server URL </label>
<div class="col-xs-8 col-sm-7">
<input type="text" class="form-control" id="vera-base" ng-model="vera.base"
placeholder="Vera URL (e.g. http://192.168.1.100)">
</div>
<button type="submit" ng-click="setVeraAddress(bridge.veraaddress)"
class="col-xs-4 col-sm-2 btn btn-success">
Use vera.address
</button>
</div>
<div class="form-group">
<label class="col-xs-2 col-sm-2 control-label" for="vera-port">Vera Request Port </label>
<div class="col-xs-10 col-sm-2">
<input type="text" class="form-control" id="vera-port" ng-model="vera.port"
placeholder="Vera Port (typically 3480)">
</div>
<label class="col-xs-2 col-sm-2 control-label" for="vera-id">Device ID </label>
<div class="col-xs-10 col-sm-2">
<input type="text" class="form-control" id="vera-id" ng-model="vera.id"
placeholder="ID">
</div>
<button type="submit" ng-click="buildUrls()"
class="col-xs-4 col-sm-2 btn btn-success">
Generate Device URLs
</button>
</div>
</form>
</li>
</ul>
</div>
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
<div class="panel-heading">
<h2 class="panel-title">Add a new device</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">
{{device.id ? 'Update' : 'Add' }} Device
</button>
</div>
<div class="form-group">
<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">
<input type="text" class="form-control" id="device-on-url" ng-model="device.onUrl"
placeholder="URL to turn device on">
</div>
<button class="col-xs-4 col-sm-2 btn btn-success" type="button"
ng-click="testUrl(device.onUrl)">Test
</button>
</div>
<div class="form-group">
<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">
<input type="text" class="form-control" id="device-off-url" ng-model="device.offUrl"
placeholder="URL to turn device off">
</div>
<button class="col-xs-4 col-sm-2 btn btn-success" type="button"
ng-click="testUrl(device.offUrl)">Test
</button>
</div>
</form>
</li>
</ul>
</div>
</div>
</div>
</div>
<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/angular.min.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>

View File

@@ -0,0 +1,15 @@
/*
AngularJS v1.4.3
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
(function(p,c,C){'use strict';function v(r,h,g){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,f,b,d,y){function z(){k&&(g.cancel(k),k=null);l&&(l.$destroy(),l=null);m&&(k=g.leave(m),k.then(function(){k=null}),m=null)}function x(){var b=r.current&&r.current.locals;if(c.isDefined(b&&b.$template)){var b=a.$new(),d=r.current;m=y(b,function(b){g.enter(b,null,m||f).then(function(){!c.isDefined(t)||t&&!a.$eval(t)||h()});z()});l=d.scope=b;l.$emit("$viewContentLoaded");
l.$eval(w)}else z()}var l,m,k,t=b.autoscroll,w=b.onload||"";a.$on("$routeChangeSuccess",x);x()}}}function A(c,h,g){return{restrict:"ECA",priority:-400,link:function(a,f){var b=g.current,d=b.locals;f.html(d.$template);var y=c(f.contents());b.controller&&(d.$scope=a,d=h(b.controller,d),b.controllerAs&&(a[b.controllerAs]=d),f.data("$ngControllerController",d),f.children().data("$ngControllerController",d));y(a)}}}p=c.module("ngRoute",["ng"]).provider("$route",function(){function r(a,f){return c.extend(Object.create(a),
f)}function h(a,c){var b=c.caseInsensitiveMatch,d={originalPath:a,regexp:a},g=d.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,c,b,d){a="?"===d?d:null;d="*"===d?d:null;g.push({name:b,optional:!!a});c=c||"";return""+(a?"":c)+"(?:"+(a?c:"")+(d&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");d.regexp=new RegExp("^"+a+"$",b?"i":"");return d}var g={};this.when=function(a,f){var b=c.copy(f);c.isUndefined(b.reloadOnSearch)&&(b.reloadOnSearch=!0);
c.isUndefined(b.caseInsensitiveMatch)&&(b.caseInsensitiveMatch=this.caseInsensitiveMatch);g[a]=c.extend(b,a&&h(a,b));if(a){var d="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";g[d]=c.extend({redirectTo:a},h(d,b))}return this};this.caseInsensitiveMatch=!1;this.otherwise=function(a){"string"===typeof a&&(a={redirectTo:a});this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function(a,f,b,d,h,p,x){function l(b){var e=s.current;
(v=(n=k())&&e&&n.$$route===e.$$route&&c.equals(n.pathParams,e.pathParams)&&!n.reloadOnSearch&&!w)||!e&&!n||a.$broadcast("$routeChangeStart",n,e).defaultPrevented&&b&&b.preventDefault()}function m(){var u=s.current,e=n;if(v)u.params=e.params,c.copy(u.params,b),a.$broadcast("$routeUpdate",u);else if(e||u)w=!1,(s.current=e)&&e.redirectTo&&(c.isString(e.redirectTo)?f.path(t(e.redirectTo,e.params)).search(e.params).replace():f.url(e.redirectTo(e.pathParams,f.path(),f.search())).replace()),d.when(e).then(function(){if(e){var a=
c.extend({},e.resolve),b,f;c.forEach(a,function(b,e){a[e]=c.isString(b)?h.get(b):h.invoke(b,null,null,e)});c.isDefined(b=e.template)?c.isFunction(b)&&(b=b(e.params)):c.isDefined(f=e.templateUrl)&&(c.isFunction(f)&&(f=f(e.params)),c.isDefined(f)&&(e.loadedTemplateUrl=x.valueOf(f),b=p(f)));c.isDefined(b)&&(a.$template=b);return d.all(a)}}).then(function(f){e==s.current&&(e&&(e.locals=f,c.copy(e.params,b)),a.$broadcast("$routeChangeSuccess",e,u))},function(b){e==s.current&&a.$broadcast("$routeChangeError",
e,u,b)})}function k(){var a,b;c.forEach(g,function(d,g){var q;if(q=!b){var h=f.path();q=d.keys;var l={};if(d.regexp)if(h=d.regexp.exec(h)){for(var k=1,m=h.length;k<m;++k){var n=q[k-1],p=h[k];n&&p&&(l[n.name]=p)}q=l}else q=null;else q=null;q=a=q}q&&(b=r(d,{params:c.extend({},f.search(),a),pathParams:a}),b.$$route=d)});return b||g[null]&&r(g[null],{params:{},pathParams:{}})}function t(a,b){var d=[];c.forEach((a||"").split(":"),function(a,c){if(0===c)d.push(a);else{var f=a.match(/(\w+)(?:[?*])?(.*)/),
g=f[1];d.push(b[g]);d.push(f[2]||"");delete b[g]}});return d.join("")}var w=!1,n,v,s={routes:g,reload:function(){w=!0;a.$evalAsync(function(){l();m()})},updateParams:function(a){if(this.current&&this.current.$$route)a=c.extend({},this.current.params,a),f.path(t(this.current.$$route.originalPath,a)),f.search(a);else throw B("norout");}};a.$on("$locationChangeStart",l);a.$on("$locationChangeSuccess",m);return s}]});var B=c.$$minErr("ngRoute");p.provider("$routeParams",function(){this.$get=function(){return{}}});
p.directive("ngView",v);p.directive("ngView",A);v.$inject=["$route","$anchorScroll","$animate"];A.$inject=["$compile","$controller","$route"]})(window,window.angular);
//# sourceMappingURL=angular-route.min.js.map

View File

@@ -1,5 +1,27 @@
angular.module('habridge', [])
.service('bridgeService', ["$http", function ($http) {
var app = angular.module('habridge', [
'ngRoute'
]);
app.config(function ($routeProvider) {
$routeProvider.when('/#', {
templateUrl: 'views/configuration.html',
controller: 'ViewingController'
}).when('/editor', {
templateUrl: 'views/editor.html',
controller: 'AddingController'
}).otherwise({
templateUrl: 'views/configuration.html',
controller: 'ViewingController'
})
});
app.factory('BridgeSettings'), function() {
return {
name : 'anonymous'
};
});
app.service('bridgeService', function ($http) {
var self = this;
this.state = {base: window.location.origin + "/api/devices", upnpbase: window.location.origin + "/upnp/settings", devices: [], error: ""};
@@ -135,15 +157,15 @@ angular.module('habridge', [])
);
};
this.editDevice = function (id, name, type, onUrl, offUrl) {
this.editDevice = function (id, name, onUrl, offUrl) {
this.device.id = id;
this.device.name = name;
this.device.onUrl = onUrl;
this.device.offUrl = offUrl;
};
}])
});
.controller('ViewingController', ["$scope", "bridgeService", function ($scope, bridgeService) {
app.controller('ViewingController', function ($scope, bridgeService) {
bridgeService.viewDevices();
bridgeService.viewBridgeSettings();
bridgeService.viewVeraDevices();
@@ -160,11 +182,11 @@ angular.module('habridge', [])
bridgeService.viewDevices();
};
$scope.editDevice = function (device) {
bridgeService.editDevice(device.id, device.name, device.type, device.onUrl, device.offUrl);
bridgeService.editDevice(device.id, device.name, device.onUrl, device.offUrl);
};
}])
});
.controller('AddingController', ["$scope", "bridgeService", function ($scope, bridgeService) {
app.controller('AddingController', function ($scope, bridgeService) {
$scope.device = {id: "", name: "", type: "switch", onUrl: "", offUrl: ""};
$scope.vera = {base: "", port: "3480", id: ""};
bridgeService.device = $scope.device;
@@ -228,8 +250,8 @@ angular.module('habridge', [])
);
}
}])
});
.controller('ErrorsController', ["$scope", "bridgeService", function ($scope, bridgeService) {
app.controller('ErrorsController', function ($scope, bridgeService) {
$scope.bridge = bridgeService.state;
}]);
});

View File

@@ -0,0 +1,101 @@
<h2>Configuration <a class="btn btn-primary pull-right" href="#/editor"><i
class="icon-plis-sign icon-white"></i> Editor</a>
</h2>
<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>{{bridge.upnpconfigaddress}}</td>
</tr>
<tr>
<td>server.port</td>
<td>{{bridge.serverport}}</td>
</tr>
<tr>
<td>upnp.devices.db</td>
<td>{{bridge.upnpdevicedb}}</td>
</tr>
<tr>
<td>upnp.response.port</td>
<td>{{bridge.upnpresponseport}}</td>
</tr>
<tr>
<td>vera.address</td>
<td>{{bridge.veraaddress}}</td>
</tr>
</table>
</div>
</div>
<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>ID</th>
<th>Name</th>
<th>Type</th>
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="device in bridge.devices">
<td>{{device.id}}</td>
<td>{{device.name}}</td>
<td>{{device.deviceType}}</td>
<td>
<button class="btn btn-info" type="submit"
ng-click="testUrl(device.onUrl)">Test ON</button>
<button class="btn btn-info" type="submit"
ng-click="testUrl(device.offUrl)">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>

View File

@@ -0,0 +1,163 @@
<h2>
Editor <a class="btn btn-primary pull-right" href="/">
Configuration</a>
</h2>
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
<div class="panel-heading">
<h2 class="panel-title">Vera Device List</h2>
</div>
<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>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Id</th>
<th>Category</th>
<th>Room</th>
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="veradevice in bridge.veradevices">
<td>{{veradevice.name}}</td>
<td>{{veradevice.id}}</td>
<td>{{veradevice.category}}</td>
<td>{{veradevice.room}}</td>
<td>
<button class="btn btn-success" type="submit"
ng-click="buildDeviceUrls(veradevice, bridge.veraaddress)">Generate
Device 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">Vera Scene List</h2>
</div>
<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>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Name</th>
<th>Id</th>
<th>Room</th>
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="verascene in bridge.verascenes">
<td>{{verascene.name}}</td>
<td>{{verascene.id}}</td>
<td>{{verascene.room}}</td>
<td>
<button class="btn btn-success" type="submit"
ng-click="buildSceneUrls(verascene, bridge.veraaddress)">Generate
Device 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">Generate a new device</h2>
</div>
<ul class="list-group">
<li class="list-group-item">
<p class="text-muted">You can generate on/off URLs by filling in
the Vera server URL, port, and device ID; or you can fill them out
manually in the lower section.</p>
<form class="form-horizontal">
<div class="form-group">
<label class="col-xs-12 col-sm-2 control-label" for="vera-base">Vera
Server URL </label>
<div class="col-xs-8 col-sm-7">
<input type="text" class="form-control" id="vera-base"
ng-model="vera.base"
placeholder="Vera URL (e.g. http://192.168.1.100)">
</div>
<button type="submit" ng-click="setVeraAddress(bridge.veraaddress)"
class="col-xs-4 col-sm-2 btn btn-success">Use
vera.address</button>
</div>
<div class="form-group">
<label class="col-xs-2 col-sm-2 control-label" for="vera-port">Vera
Request Port </label>
<div class="col-xs-10 col-sm-2">
<input type="text" class="form-control" id="vera-port"
ng-model="vera.port" placeholder="Vera Port (typically 3480)">
</div>
<label class="col-xs-2 col-sm-2 control-label" for="vera-id">Device
ID </label>
<div class="col-xs-10 col-sm-2">
<input type="text" class="form-control" id="vera-id"
ng-model="vera.id" placeholder="ID">
</div>
<button type="submit" ng-click="buildUrls()"
class="col-xs-4 col-sm-2 btn btn-success">Generate Device
URLs</button>
</div>
</form>
</li>
</ul>
</div>
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
<div class="panel-heading">
<h2 class="panel-title">Add a new device</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">
{{device.id ? 'Update' : 'Add' }} Device</button>
</div>
<div class="form-group">
<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">
<input type="text" class="form-control" id="device-on-url"
ng-model="device.onUrl" placeholder="URL to turn device on">
</div>
<button class="col-xs-4 col-sm-2 btn btn-success" type="button"
ng-click="testUrl(device.onUrl)">Test</button>
</div>
<div class="form-group">
<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">
<input type="text" class="form-control" id="device-off-url"
ng-model="device.offUrl" placeholder="URL to turn device off">
</div>
<button class="col-xs-4 col-sm-2 btn btn-success" type="button"
ng-click="testUrl(device.offUrl)">Test</button>
</div>
</form>
</li>
</ul>
</div>