mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-18 16:17:30 +00:00
Finished device, scene and activity tracking, updated upnp handling, updated HUE API config handling and test on and off calls.
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.bwssystems.HABridge</groupId>
|
<groupId>com.bwssystems.HABridge</groupId>
|
||||||
<artifactId>ha-bridge</artifactId>
|
<artifactId>ha-bridge</artifactId>
|
||||||
<version>1.0.9b</version>
|
<version>1.1.0</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>HA Bridge</name>
|
<name>HA Bridge</name>
|
||||||
|
|||||||
@@ -178,6 +178,12 @@ public class DeviceRepository {
|
|||||||
} else if (name.equals("name")) {
|
} else if (name.equals("name")) {
|
||||||
deviceEntry.setName(reader.nextString());
|
deviceEntry.setName(reader.nextString());
|
||||||
log.debug("Read a Device - device json name: " + deviceEntry.getName());
|
log.debug("Read a Device - device json name: " + deviceEntry.getName());
|
||||||
|
} else if (name.equals("mapType")) {
|
||||||
|
deviceEntry.setMapType(reader.nextString());
|
||||||
|
log.debug("Read a Device - device json name: " + deviceEntry.getMapType());
|
||||||
|
} else if (name.equals("mapId")) {
|
||||||
|
deviceEntry.setMapId(reader.nextString());
|
||||||
|
log.debug("Read a Device - device json name: " + deviceEntry.getMapId());
|
||||||
} else if (name.equals("deviceType")) {
|
} else if (name.equals("deviceType")) {
|
||||||
deviceEntry.setDeviceType(reader.nextString());
|
deviceEntry.setDeviceType(reader.nextString());
|
||||||
log.debug("Read a Device - device json type:" + deviceEntry.getDeviceType());
|
log.debug("Read a Device - device json type:" + deviceEntry.getDeviceType());
|
||||||
|
|||||||
@@ -143,8 +143,9 @@ public class DeviceResource {
|
|||||||
}, new JsonTransformer());
|
}, new JsonTransformer());
|
||||||
|
|
||||||
delete (API_CONTEXT + "/:id", "application/json", (request, response) -> {
|
delete (API_CONTEXT + "/:id", "application/json", (request, response) -> {
|
||||||
log.debug("Delete a device");
|
String anId = request.params(":id");
|
||||||
DeviceDescriptor deleted = deviceRepository.findOne(request.params(":id"));
|
log.debug("Delete a device: " + anId);
|
||||||
|
DeviceDescriptor deleted = deviceRepository.findOne(anId);
|
||||||
if(deleted == null)
|
if(deleted == null)
|
||||||
response.status(HttpStatus.SC_NOT_FOUND);
|
response.status(HttpStatus.SC_NOT_FOUND);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -76,14 +76,7 @@ public class UpnpListener {
|
|||||||
byte[] buf = new byte[1024];
|
byte[] buf = new byte[1024];
|
||||||
DatagramPacket packet = new DatagramPacket(buf, buf.length);
|
DatagramPacket packet = new DatagramPacket(buf, buf.length);
|
||||||
upnpMulticastSocket.receive(packet);
|
upnpMulticastSocket.receive(packet);
|
||||||
String packetString = new String(packet.getData());
|
if(isSSDPDiscovery(packet)){
|
||||||
if(packetString != null && packetString.contains("M-SEARCH")) {
|
|
||||||
if(traceupnp)
|
|
||||||
log.info("Traceupnp: SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + packetString);
|
|
||||||
else
|
|
||||||
log.debug("Got SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + packetString);
|
|
||||||
}
|
|
||||||
if(isSSDPDiscovery(packetString)){
|
|
||||||
sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort());
|
sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,17 +90,22 @@ public class UpnpListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* very naive ssdp discovery packet detection
|
* ssdp discovery packet detection
|
||||||
* @param body
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
protected boolean isSSDPDiscovery(String body){
|
protected boolean isSSDPDiscovery(DatagramPacket packet){
|
||||||
// log.debug("Check if this is a MAN ssdp-discover packet for a upnp basic device: " + body);
|
//Only respond to discover request for strict upnp form
|
||||||
//Only respond to discover request for upnp basic device from echo, the others are for the wemo
|
String packetString = new String(packet.getData());
|
||||||
if(body != null && body.contains("M-SEARCH") && body.contains("\"ssdp:discover\"")){
|
if(packetString != null && packetString.startsWith("M-SEARCH * HTTP/1.1") && packetString.contains("\"ssdp:discover\"")){
|
||||||
if(traceupnp)
|
if(traceupnp) {
|
||||||
|
log.info("Traceupnp: SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + packetString);
|
||||||
log.info("Traceupnp: isSSDPDiscovery found message to be an M-SEARCH message.");
|
log.info("Traceupnp: isSSDPDiscovery found message to be an M-SEARCH message.");
|
||||||
if(strict && body.startsWith("M-SEARCH * HTTP/1.1") && body.contains("MAN: \"ssdp:discover\"") && (body.contains("ST: urn:schemas-upnp-org:device:basic:1") || body.contains("ST: upnp:rootdevice") || body.contains("ST: ssdp:all")))
|
}
|
||||||
|
else {
|
||||||
|
log.debug("Got SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + packetString);
|
||||||
|
log.debug("Found message to be an M-SEARCH message.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strict && (packetString.contains("ST: urn:schemas-upnp-org:device:basic:1") || packetString.contains("ST: upnp:rootdevice") || packetString.contains("ST: ssdp:all")))
|
||||||
{
|
{
|
||||||
if(traceupnp)
|
if(traceupnp)
|
||||||
log.info("Traceupnp: isSSDPDiscovery found message to be valid under strict rules - strict: " + strict);
|
log.info("Traceupnp: isSSDPDiscovery found message to be valid under strict rules - strict: " + strict);
|
||||||
@@ -134,7 +132,7 @@ public class UpnpListener {
|
|||||||
"USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1\r\n\r\n";
|
"USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1\r\n\r\n";
|
||||||
protected void sendUpnpResponse(DatagramSocket socket, InetAddress requester, int sourcePort) throws IOException {
|
protected void sendUpnpResponse(DatagramSocket socket, InetAddress requester, int sourcePort) throws IOException {
|
||||||
String discoveryResponse = null;
|
String discoveryResponse = null;
|
||||||
discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort, getRandomUUIDString());
|
discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort);
|
||||||
if(traceupnp)
|
if(traceupnp)
|
||||||
log.info("Traceupnp: sendUpnpResponse: " + discoveryResponse);
|
log.info("Traceupnp: sendUpnpResponse: " + discoveryResponse);
|
||||||
else
|
else
|
||||||
@@ -142,8 +140,4 @@ public class UpnpListener {
|
|||||||
DatagramPacket response = new DatagramPacket(discoveryResponse.getBytes(), discoveryResponse.length(), requester, sourcePort);
|
DatagramPacket response = new DatagramPacket(discoveryResponse.getBytes(), discoveryResponse.length(), requester, sourcePort);
|
||||||
socket.send(response);
|
socket.send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getRandomUUIDString(){
|
|
||||||
return "88f6698f-2c83-4393-bd03-cd54a9f8595"; // https://xkcd.com/221/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class HarmonyServer {
|
|||||||
log.debug("something is very wrong as dummyProvider is not null...");
|
log.debug("something is very wrong as dummyProvider is not null...");
|
||||||
if(mySettings.isDevMode())
|
if(mySettings.isDevMode())
|
||||||
modeString = " (development mode)";
|
modeString = " (development mode)";
|
||||||
if(noopCalls)
|
else if(noopCalls)
|
||||||
modeString = " (no op calls to harmony)";
|
modeString = " (no op calls to harmony)";
|
||||||
log.info("setup initiated " + modeString + "....");
|
log.info("setup initiated " + modeString + "....");
|
||||||
if(mySettings.isDevMode())
|
if(mySettings.isDevMode())
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.viewVeraScenes = function () {
|
this.viewVeraScenes = function () {
|
||||||
this.state.error = "";
|
this.state.error = "";
|
||||||
if(!this.state.showVera)
|
if(!this.state.showVera)
|
||||||
@@ -209,7 +209,7 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.viewHarmonyActivities = function () {
|
this.viewHarmonyActivities = function () {
|
||||||
this.state.error = "";
|
this.state.error = "";
|
||||||
if(!this.state.showHarmony)
|
if(!this.state.showHarmony)
|
||||||
@@ -246,11 +246,12 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.findHarmonyActivityEntry = function(activityId) {
|
this.findDeviceByMapId = function(id) {
|
||||||
for(var i = 0; i < this.state.devices.length; i++) {
|
for(var i = 0; i < this.state.devices.length; i++) {
|
||||||
if(this.state.devices[i].mapId == activityId)
|
if(this.state.devices[i].mapId == id)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.addDevice = function (device) {
|
this.addDevice = function (device) {
|
||||||
@@ -327,6 +328,13 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.deleteDeviceByMapId = function (id) {
|
||||||
|
for(var i = 0; i < this.state.devices.length; i++) {
|
||||||
|
if(this.state.devices[i].mapId == id)
|
||||||
|
return self.deleteDevice(this.state.devices[i].id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.editDevice = function (device) {
|
this.editDevice = function (device) {
|
||||||
self.state.device = device;
|
self.state.device = device;
|
||||||
};
|
};
|
||||||
@@ -410,7 +418,13 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
|
|||||||
bridgeService.updateShowHarmony();
|
bridgeService.updateShowHarmony();
|
||||||
$scope.device = bridgeService.state.device;
|
$scope.device = bridgeService.state.device;
|
||||||
$scope.activitiesVisible = false;
|
$scope.activitiesVisible = false;
|
||||||
|
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||||
|
$scope.buttonsVisible = false;
|
||||||
$scope.imgActivitiesUrl = "glyphicon glyphicon-plus";
|
$scope.imgActivitiesUrl = "glyphicon glyphicon-plus";
|
||||||
|
$scope.devicesVisible = false;
|
||||||
|
$scope.imgDevicesUrl = "glyphicon glyphicon-plus";
|
||||||
|
$scope.scenesVisible = false;
|
||||||
|
$scope.imgScenesUrl = "glyphicon glyphicon-plus";
|
||||||
$scope.predicate = '';
|
$scope.predicate = '';
|
||||||
$scope.reverse = true;
|
$scope.reverse = true;
|
||||||
$scope.device_dim_control = "";
|
$scope.device_dim_control = "";
|
||||||
@@ -537,6 +551,7 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.toggleActivities = function () {
|
$scope.toggleActivities = function () {
|
||||||
$scope.activitiesVisible = !$scope.activitiesVisible;
|
$scope.activitiesVisible = !$scope.activitiesVisible;
|
||||||
if($scope.activitiesVisible)
|
if($scope.activitiesVisible)
|
||||||
@@ -545,15 +560,43 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
|
|||||||
$scope.imgActivitiesUrl = "glyphicon glyphicon-plus";
|
$scope.imgActivitiesUrl = "glyphicon glyphicon-plus";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.toggleButtons = function () {
|
||||||
|
$scope.buttonsVisible = !$scope.buttonsVisible;
|
||||||
|
if($scope.buttonsVisible)
|
||||||
|
$scope.imgButtonsUrl = "glyphicon glyphicon-minus";
|
||||||
|
else
|
||||||
|
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.toggleDevices = function () {
|
||||||
|
$scope.devicesVisible = !$scope.devicesVisible;
|
||||||
|
if($scope.devicesVisible)
|
||||||
|
$scope.imgDevicesUrl = "glyphicon glyphicon-minus";
|
||||||
|
else
|
||||||
|
$scope.imgDevicesUrl = "glyphicon glyphicon-plus";
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.toggleScenes = function () {
|
||||||
|
$scope.scenesVisible = !$scope.scenesVisible;
|
||||||
|
if($scope.scenesVisible)
|
||||||
|
$scope.imgScenesUrl = "glyphicon glyphicon-minus";
|
||||||
|
else
|
||||||
|
$scope.imgScenesUrl = "glyphicon glyphicon-plus";
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.deleteDeviceByMapId = function (id) {
|
||||||
|
bridgeService.deleteDeviceByMapId(id);
|
||||||
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.filter('availableActivity', function(bridgeService) {
|
app.filter('availableId', function(bridgeService) {
|
||||||
return function(input) {
|
return function(input) {
|
||||||
var out = [];
|
var out = [];
|
||||||
if(input == null)
|
if(input == null)
|
||||||
return out;
|
return out;
|
||||||
for (var i = 0; i < input.length; i++) {
|
for (var i = 0; i < input.length; i++) {
|
||||||
if(!bridgeService.findHarmonyActivityEntry(input[i].id)){
|
if(!bridgeService.findDeviceByMapId(input[i].id)){
|
||||||
out.push(input[i]);
|
out.push(input[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -561,13 +604,13 @@ app.filter('availableActivity', function(bridgeService) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.filter('unavailableActivity', function(bridgeService) {
|
app.filter('unavailableId', function(bridgeService) {
|
||||||
return function(input) {
|
return function(input) {
|
||||||
var out = [];
|
var out = [];
|
||||||
if(input == null)
|
if(input == null)
|
||||||
return out;
|
return out;
|
||||||
for (var i = 0; i < input.length; i++) {
|
for (var i = 0; i < input.length; i++) {
|
||||||
if(bridgeService.findHarmonyActivityEntry(input[i].id)){
|
if(bridgeService.findDeviceByMapId(input[i].id)){
|
||||||
out.push(input[i]);
|
out.push(input[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -575,6 +618,21 @@ app.filter('unavailableActivity', function(bridgeService) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.filter('configuredButtons', function() {
|
||||||
|
return function(input) {
|
||||||
|
var out = [];
|
||||||
|
if(input == null)
|
||||||
|
return out;
|
||||||
|
for (var i = 0; i < input.length; i++) {
|
||||||
|
if(input[i].mapType == "harmonyButton"){
|
||||||
|
out.push(input[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
app.controller('ErrorsController', function ($scope, bridgeService) {
|
app.controller('ErrorsController', function ($scope, bridgeService) {
|
||||||
$scope.bridge = bridgeService.state;
|
$scope.bridge = bridgeService.state;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tr ng-repeat="harmonyactivity in bridge.harmonyactivities | availableActivity | orderBy:predicate:reverse">
|
<tr ng-repeat="harmonyactivity in bridge.harmonyactivities | availableId | orderBy:predicate:reverse">
|
||||||
<td>{{harmonyactivity.label}}</td>
|
<td>{{harmonyactivity.label}}</td>
|
||||||
<td>{{harmonyactivity.id}}</td>
|
<td>{{harmonyactivity.id}}</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -58,11 +58,14 @@
|
|||||||
<a href="" ng-click="order('id')">Id</a>
|
<a href="" ng-click="order('id')">Id</a>
|
||||||
<span class="sortorder" ng-show="predicate === 'id'" ng-class="{reverse:reverse}"></span>
|
<span class="sortorder" ng-show="predicate === 'id'" ng-class="{reverse:reverse}"></span>
|
||||||
</th>
|
</th>
|
||||||
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tr ng-repeat="harmonyactivity in bridge.harmonyactivities | unavailableActivity | orderBy:predicate:reverse">
|
<tr ng-repeat="harmonyactivity in bridge.harmonyactivities | unavailableId | orderBy:predicate:reverse">
|
||||||
<td>{{harmonyactivity.label}}</td>
|
<td>{{harmonyactivity.label}}</td>
|
||||||
<td>{{harmonyactivity.id}}</td>
|
<td>{{harmonyactivity.id}}</td>
|
||||||
|
<td><button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(harmonyactivity.id)">Delete</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -58,6 +58,41 @@
|
|||||||
</table>
|
</table>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">Already Configured Harmony Buttons <a ng-click="toggleButtons()"><span class={{imgButtonsUrl}} aria-hidden="true"></span></a></h2>
|
||||||
|
</div>
|
||||||
|
<ul ng-if="buttonsVisible" class="list-group">
|
||||||
|
<li class="list-group-item">
|
||||||
|
<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')">Device Id</a>
|
||||||
|
<span class="sortorder" ng-show="predicate === 'id'" ng-class="{reverse:reverse}"></span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a href="" ng-click="order('mapId')">Harmony Device-Button On-Button Off</a>
|
||||||
|
<span class="sortorder" ng-show="predicate === 'id'" ng-class="{reverse:reverse}"></span>
|
||||||
|
</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="device in bridge.devices | configuredButtons | orderBy:predicate:reverse">
|
||||||
|
<td>{{device.name}}</td>
|
||||||
|
<td>{{device.id}}</td>
|
||||||
|
<td>{{device.mapId}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(device.mapId)">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
<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 ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</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">×</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>
|
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tr ng-repeat="veradevice in bridge.veradevices | orderBy:predicate:reverse">
|
<tr ng-repeat="veradevice in bridge.veradevices | availableId | orderBy:predicate:reverse">
|
||||||
<td>{{veradevice.name}}</td>
|
<td>{{veradevice.name}}</td>
|
||||||
<td>{{veradevice.id}}</td>
|
<td>{{veradevice.id}}</td>
|
||||||
<td>{{veradevice.category}}</td>
|
<td>{{veradevice.category}}</td>
|
||||||
@@ -59,6 +59,46 @@
|
|||||||
</table>
|
</table>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">Already Configured Vera Devices <a ng-click="toggleDevices()"><span class={{imgDevicesUrl}} aria-hidden="true"></a></h2>
|
||||||
|
</div>
|
||||||
|
<ul ng-if="devicesVisible" class="list-group">
|
||||||
|
<li class="list-group-item">
|
||||||
|
<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>
|
||||||
|
<a href="" ng-click="order('category')">Category</a>
|
||||||
|
<span class="sortorder" ng-show="predicate === 'category'" ng-class="{reverse:reverse}"></span>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<a href="" ng-click="order('room')">Room</a>
|
||||||
|
<span class="sortorder" ng-show="predicate === 'room'" ng-class="{reverse:reverse}"></span>
|
||||||
|
</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="veradevice in bridge.veradevices | unavailableId | orderBy:predicate:reverse">
|
||||||
|
<td>{{veradevice.name}}</td>
|
||||||
|
<td>{{veradevice.id}}</td>
|
||||||
|
<td>{{veradevice.category}}</td>
|
||||||
|
<td>{{veradevice.room}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(harmonyactivity.id)">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tr ng-repeat="verascene in bridge.verascenes | orderBy:predicate:reverse">
|
<tr ng-repeat="verascene in bridge.verascenes | availableId | orderBy:predicate:reverse">
|
||||||
<td>{{verascene.name}}</td>
|
<td>{{verascene.name}}</td>
|
||||||
<td>{{verascene.id}}</td>
|
<td>{{verascene.id}}</td>
|
||||||
<td>{{verascene.room}}</td>
|
<td>{{verascene.room}}</td>
|
||||||
@@ -47,6 +47,41 @@
|
|||||||
</table>
|
</table>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">Already Configured Vera Scenes <a ng-click="toggleScenes()"><span class={{imgScenesUrl}} aria-hidden="true"></a></h2>
|
||||||
|
</div>
|
||||||
|
<ul ng-if="scenesVisible" class="list-group">
|
||||||
|
<li class="list-group-item">
|
||||||
|
<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>
|
||||||
|
<a href="" ng-click="order('room')">Room</a>
|
||||||
|
<span class="sortorder" ng-show="predicate === 'room'" ng-class="{reverse:reverse}"></span>
|
||||||
|
</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="verascene in bridge.verascenes | unavailableId | orderBy:predicate:reverse">
|
||||||
|
<td>{{verascene.name}}</td>
|
||||||
|
<td>{{verascene.id}}</td>
|
||||||
|
<td>{{verascene.room}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(harmonyactivity.id)">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
|||||||
Reference in New Issue
Block a user