From 314ae58ebd6cb3944deb3ec05e3dc45138bd74d6 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 18 Nov 2015 16:31:11 -0600 Subject: [PATCH] This closes #8, closes #9, closes #10 and closes #11. Finished device, scene and activity tracking, updated upnp handling, updated HUE API config handling and test on and off calls. --- pom.xml | 2 +- .../HABridge/dao/DeviceRepository.java | 6 ++ .../devicemanagmeent/DeviceResource.java | 5 +- .../HABridge/upnp/UpnpListener.java | 38 ++++------ .../com/bwssystems/harmony/HarmonyServer.java | 2 +- src/main/resources/public/scripts/app.js | 74 +++++++++++++++++-- .../public/views/harmonyactivity.html | 7 +- .../resources/public/views/harmonydevice.html | 35 +++++++++ .../public/views/nonconfiguration.html | 64 ---------------- .../resources/public/views/veradevice.html | 42 ++++++++++- .../resources/public/views/verascene.html | 37 +++++++++- 11 files changed, 210 insertions(+), 102 deletions(-) delete mode 100644 src/main/resources/public/views/nonconfiguration.html diff --git a/pom.xml b/pom.xml index 2d353d8..87e85e2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 1.0.9b + 1.1.0 jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java index de29383..0d4afdd 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java @@ -178,6 +178,12 @@ public class DeviceRepository { } else if (name.equals("name")) { deviceEntry.setName(reader.nextString()); 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")) { deviceEntry.setDeviceType(reader.nextString()); log.debug("Read a Device - device json type:" + deviceEntry.getDeviceType()); diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index 13a8613..e49c8ae 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -143,8 +143,9 @@ public class DeviceResource { }, new JsonTransformer()); delete (API_CONTEXT + "/:id", "application/json", (request, response) -> { - log.debug("Delete a device"); - DeviceDescriptor deleted = deviceRepository.findOne(request.params(":id")); + String anId = request.params(":id"); + log.debug("Delete a device: " + anId); + DeviceDescriptor deleted = deviceRepository.findOne(anId); if(deleted == null) response.status(HttpStatus.SC_NOT_FOUND); else diff --git a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java index 78a5520..70c1833 100644 --- a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java +++ b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java @@ -76,14 +76,7 @@ public class UpnpListener { byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length); upnpMulticastSocket.receive(packet); - String packetString = new String(packet.getData()); - 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)){ + if(isSSDPDiscovery(packet)){ sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort()); } } @@ -97,17 +90,22 @@ public class UpnpListener { } /** - * very naive ssdp discovery packet detection - * @param body - * @return + * ssdp discovery packet detection */ - protected boolean isSSDPDiscovery(String body){ - // log.debug("Check if this is a MAN ssdp-discover packet for a upnp basic device: " + body); - //Only respond to discover request for upnp basic device from echo, the others are for the wemo - if(body != null && body.contains("M-SEARCH") && body.contains("\"ssdp:discover\"")){ - if(traceupnp) + protected boolean isSSDPDiscovery(DatagramPacket packet){ + //Only respond to discover request for strict upnp form + String packetString = new String(packet.getData()); + if(packetString != null && packetString.startsWith("M-SEARCH * HTTP/1.1") && packetString.contains("\"ssdp:discover\"")){ + 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."); - 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) 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"; protected void sendUpnpResponse(DatagramSocket socket, InetAddress requester, int sourcePort) throws IOException { String discoveryResponse = null; - discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort, getRandomUUIDString()); + discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort); if(traceupnp) log.info("Traceupnp: sendUpnpResponse: " + discoveryResponse); else @@ -142,8 +140,4 @@ public class UpnpListener { DatagramPacket response = new DatagramPacket(discoveryResponse.getBytes(), discoveryResponse.length(), requester, sourcePort); socket.send(response); } - - protected String getRandomUUIDString(){ - return "88f6698f-2c83-4393-bd03-cd54a9f8595"; // https://xkcd.com/221/ - } } diff --git a/src/main/java/com/bwssystems/harmony/HarmonyServer.java b/src/main/java/com/bwssystems/harmony/HarmonyServer.java index bb5fe4f..8fd0bd4 100644 --- a/src/main/java/com/bwssystems/harmony/HarmonyServer.java +++ b/src/main/java/com/bwssystems/harmony/HarmonyServer.java @@ -54,7 +54,7 @@ public class HarmonyServer { log.debug("something is very wrong as dummyProvider is not null..."); if(mySettings.isDevMode()) modeString = " (development mode)"; - if(noopCalls) + else if(noopCalls) modeString = " (no op calls to harmony)"; log.info("setup initiated " + modeString + "...."); if(mySettings.isDevMode()) diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index a49e3b9..a6aaa47 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -191,7 +191,7 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) { } ); }; - + this.viewVeraScenes = function () { this.state.error = ""; if(!this.state.showVera) @@ -209,7 +209,7 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) { } ); }; - + this.viewHarmonyActivities = function () { this.state.error = ""; 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++) { - if(this.state.devices[i].mapId == activityId) + if(this.state.devices[i].mapId == id) return true; } + return false; }; 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) { self.state.device = device; }; @@ -410,7 +418,13 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer bridgeService.updateShowHarmony(); $scope.device = bridgeService.state.device; $scope.activitiesVisible = false; + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + $scope.buttonsVisible = false; $scope.imgActivitiesUrl = "glyphicon glyphicon-plus"; + $scope.devicesVisible = false; + $scope.imgDevicesUrl = "glyphicon glyphicon-plus"; + $scope.scenesVisible = false; + $scope.imgScenesUrl = "glyphicon glyphicon-plus"; $scope.predicate = ''; $scope.reverse = true; $scope.device_dim_control = ""; @@ -537,6 +551,7 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer } ); } + $scope.toggleActivities = function () { $scope.activitiesVisible = !$scope.activitiesVisible; if($scope.activitiesVisible) @@ -545,15 +560,43 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer $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) { var out = []; if(input == null) return out; for (var i = 0; i < input.length; i++) { - if(!bridgeService.findHarmonyActivityEntry(input[i].id)){ + if(!bridgeService.findDeviceByMapId(input[i].id)){ 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) { var out = []; if(input == null) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.findHarmonyActivityEntry(input[i].id)){ + if(bridgeService.findDeviceByMapId(input[i].id)){ 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) { $scope.bridge = bridgeService.state; }); diff --git a/src/main/resources/public/views/harmonyactivity.html b/src/main/resources/public/views/harmonyactivity.html index a4f21c0..25fcaad 100644 --- a/src/main/resources/public/views/harmonyactivity.html +++ b/src/main/resources/public/views/harmonyactivity.html @@ -30,7 +30,7 @@ Actions - + {{harmonyactivity.label}} {{harmonyactivity.id}} @@ -58,11 +58,14 @@ Id + Actions - + {{harmonyactivity.label}} {{harmonyactivity.id}} + diff --git a/src/main/resources/public/views/harmonydevice.html b/src/main/resources/public/views/harmonydevice.html index a37abd2..aa8a8e9 100644 --- a/src/main/resources/public/views/harmonydevice.html +++ b/src/main/resources/public/views/harmonydevice.html @@ -58,6 +58,41 @@ +
+

Already Configured Harmony Buttons

+
+
diff --git a/src/main/resources/public/views/nonconfiguration.html b/src/main/resources/public/views/nonconfiguration.html deleted file mode 100644 index a3bb4e5..0000000 --- a/src/main/resources/public/views/nonconfiguration.html +++ /dev/null @@ -1,64 +0,0 @@ - - -
- -
-
-
-

Current devices

-
- - - - - - - - - - - - - - - -
- ID - - Name - - Type - Actions
{{device.id}}{{device.name}}{{device.deviceType}} - - - - -
-
-
-
- -

Bridge settings

-
-
\ No newline at end of file diff --git a/src/main/resources/public/views/veradevice.html b/src/main/resources/public/views/veradevice.html index 1d0a0b7..d9ed6e8 100644 --- a/src/main/resources/public/views/veradevice.html +++ b/src/main/resources/public/views/veradevice.html @@ -45,7 +45,7 @@ Actions - + {{veradevice.name}} {{veradevice.id}} {{veradevice.category}} @@ -59,6 +59,46 @@ +
+

Already Configured Vera Devices

+
+
    +
  • + + + + + + + + + + + + + + + + + +
    + Name + + + Id + + + Category + + + Room + + Actions
    {{veradevice.name}}{{veradevice.id}}{{veradevice.category}}{{veradevice.room}} + +
    +
  • +
diff --git a/src/main/resources/public/views/verascene.html b/src/main/resources/public/views/verascene.html index 7f58856..c9d8ce4 100644 --- a/src/main/resources/public/views/verascene.html +++ b/src/main/resources/public/views/verascene.html @@ -34,7 +34,7 @@ Actions - + {{verascene.name}} {{verascene.id}} {{verascene.room}} @@ -47,6 +47,41 @@ +
+

Already Configured Vera Scenes

+
+
    +
  • + + + + + + + + + + + + + + + +
    + Name + + + Id + + + Room + + Actions
    {{verascene.name}}{{verascene.id}}{{verascene.room}} + +
    +
  • +