From 8ff7bc01206c3dc10c374ecd72a932d986f117e6 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 28 Sep 2016 16:18:53 -0500 Subject: [PATCH] Updated upnp response for M-SEARCH again. Updated devices to have numbering more in line with how the hue bridge is done. Added special generation of hue device unique id as the philips api spec shows. Added a renumber function to convert id's. --- pom.xml | 2 +- .../HABridge/api/hue/DeviceResponse.java | 2 +- .../HABridge/dao/DeviceDescriptor.java | 11 +++++ .../HABridge/dao/DeviceRepository.java | 47 +++++++++++++++++-- .../devicemanagmeent/DeviceResource.java | 16 +++++++ .../HABridge/upnp/UpnpListener.java | 18 +++++-- src/main/resources/public/scripts/app.js | 15 ++++++ .../resources/public/views/configuration.html | 5 ++ .../resources/public/views/editdevice.html | 8 ++++ 9 files changed, 115 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 8f2546c..17c4999 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 3.1.0b + 3.1.0c jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/DeviceResponse.java b/src/main/java/com/bwssystems/HABridge/api/hue/DeviceResponse.java index e293145..8d25c60 100644 --- a/src/main/java/com/bwssystems/HABridge/api/hue/DeviceResponse.java +++ b/src/main/java/com/bwssystems/HABridge/api/hue/DeviceResponse.java @@ -84,7 +84,7 @@ public class DeviceResponse { response.setState(device.getDeviceState()); response.setName(device.getName()); - response.setUniqueid(device.getId()); + response.setUniqueid(device.getUniqueid()); response.setManufacturername("Philips"); response.setType("Dimmable light"); response.setModelid("LWB004"); diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java index 6ed7b95..480ea57 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java @@ -11,6 +11,9 @@ public class DeviceDescriptor{ @SerializedName("id") @Expose private String id; + @SerializedName("uniqueid") + @Expose + private String uniqueid; @SerializedName("name") @Expose private String name; @@ -128,6 +131,14 @@ public class DeviceDescriptor{ this.id = id; } + public String getUniqueid() { + return uniqueid; + } + + public void setUniqueid(String uniqueid) { + this.uniqueid = uniqueid; + } + public String getHeaders() { return headers; } diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java index 6dc7218..727c73e 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java @@ -2,6 +2,7 @@ package com.bwssystems.HABridge.dao; import java.io.IOException; +import java.math.BigInteger; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -9,8 +10,11 @@ import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; -import java.util.Random; + +import javax.xml.bind.DatatypeConverter; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +33,7 @@ public class DeviceRepository extends BackupHandler { private Map devices; private Path repositoryPath; private Gson gson; - final private Random random = new Random(); + private Integer maxId; private Logger log = LoggerFactory.getLogger(DeviceRepository.class); public DeviceRepository(String deviceDb) { @@ -41,6 +45,7 @@ public class DeviceRepository extends BackupHandler { repositoryPath = null; repositoryPath = Paths.get(deviceDb); setupParams(repositoryPath, ".bk", "device.db-"); + maxId = 1; _loadRepository(repositoryPath); } @@ -57,6 +62,9 @@ public class DeviceRepository extends BackupHandler { DeviceDescriptor list[] = gson.fromJson(jsonContent, DeviceDescriptor[].class); for(int i = 0; i < list.length; i++) { put(list[i].getId(), list[i]); + if(Integer.decode(list[i].getId()) > maxId) { + maxId = Integer.decode(list[i].getId()); + } } } } @@ -84,8 +92,17 @@ public class DeviceRepository extends BackupHandler { for(int i = 0; i < descriptors.length; i++) { if(descriptors[i].getId() != null && descriptors[i].getId().length() > 0) devices.remove(descriptors[i].getId()); - else - descriptors[i].setId(String.valueOf(random.nextInt(Integer.MAX_VALUE))); + else { + descriptors[i].setId(String.valueOf(maxId)); + maxId++; + } + if(descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) { + BigInteger bigInt = BigInteger.valueOf(Integer.decode(descriptors[i].getId())); + byte[] theBytes = bigInt.toByteArray(); + String hexValue = DatatypeConverter.printHexBinary(theBytes); + + descriptors[i].setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); + } put(descriptors[i].getId(), descriptors[i]); theNames = theNames + " " + descriptors[i].getName() + ", "; } @@ -94,6 +111,28 @@ public class DeviceRepository extends BackupHandler { log.debug("Save device(s): " + theNames); } + public void renumber() { + List list = new ArrayList(devices.values()); + Iterator deviceIterator = list.iterator(); + Map newdevices = new HashMap();; + maxId = 1; + log.debug("Renumber devices."); + while(deviceIterator.hasNext()) { + DeviceDescriptor theDevice = deviceIterator.next(); + theDevice.setId(String.valueOf(maxId)); + BigInteger bigInt = BigInteger.valueOf(maxId); + byte[] theBytes = bigInt.toByteArray(); + String hexValue = DatatypeConverter.printHexBinary(theBytes); + + theDevice.setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); + newdevices.put(theDevice.getId(), theDevice); + maxId++; + } + devices = newdevices; + String jsonValue = gson.toJson(findAll()); + repositoryWriter(jsonValue, repositoryPath); + } + public String delete(DeviceDescriptor aDescriptor) { if (aDescriptor != null) { devices.remove(aDescriptor.getId()); diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index cd0fdc6..e57b911 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -8,6 +8,7 @@ import static spark.Spark.delete; import java.util.Arrays; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -280,6 +281,21 @@ public class DeviceResource { return halHome.getDevices(); }, new JsonTransformer()); + // http://ip_address:port/api/devices/exec/renumber CORS request + options(API_CONTEXT + "/exec/renumber", "application/json", (request, response) -> { + response.status(HttpStatus.SC_OK); + response.header("Access-Control-Allow-Origin", request.headers("Origin")); + response.header("Access-Control-Allow-Methods", "POST"); + response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers")); + response.header("Content-Type", "text/html; charset=utf-8"); + return ""; + }); + post (API_CONTEXT + "/exec/renumber", "application/json", (request, response) -> { + log.debug("Renumber devices."); + deviceRepository.renumber(); + return null; + }, new JsonTransformer()); + get (API_CONTEXT + "/backup/available", "application/json", (request, response) -> { log.debug("Get backup filenames"); response.status(HttpStatus.SC_OK); diff --git a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java index 436371c..c0cf521 100644 --- a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java +++ b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java @@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory; import com.bwssystems.HABridge.BridgeControlDescriptor; import com.bwssystems.HABridge.BridgeSettingsDescriptor; import com.bwssystems.HABridge.Configuration; -import com.bwssystems.HABridge.api.hue.HuePublicConfig; +// import com.bwssystems.HABridge.api.hue.HuePublicConfig; import java.io.IOException; import java.net.*; @@ -24,6 +24,14 @@ public class UpnpListener { private boolean traceupnp; private BridgeControlDescriptor bridgeControl; private boolean discoveryTemplateLatest; + private String discoveryTemplate = "HTTP/1.1 200 OK\r\n" + + "CACHE-CONTROL: max-age=86400\r\n" + + "EXT:\r\n" + + "LOCATION: http://%s:%s/description.xml\r\n" + + "SERVER: FreeRTOS/7.4.2 UPnP/1.0 IpBridge/1.10.0\r\n" + + "ST: upnp:rootdevice\r\n" + + "USN: uuid:2f402f80-da50-11e1-9b23-001788102201\r\n\r\n"; +/* private String discoveryTemplate = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=86400\r\n" + @@ -33,6 +41,9 @@ public class UpnpListener { "hue-bridgeid: %s\r\n" + "ST: upnp:rootdevice\r\n" + "USN: uuid:2f402f80-da50-11e1-9b23-001788102201\r\n\r\n"; + + discoveryResponse = String.format(discoveryTemplate, Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT, responseAddress, httpServerPort, HuePublicConfig.createConfig("temp", responseAddress).getBridgeid()); +*/ private String discoveryTemplate091516 = "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=86400\r\n" + "EXT:\r\n" + @@ -40,6 +51,7 @@ public class UpnpListener { "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/1.10.0\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n" + "USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1\r\n\r\n"; +/* private String discoveryTemplateOld = "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=86400\r\n" + "EXT:\r\n" + @@ -48,7 +60,7 @@ public class UpnpListener { "01-NLS: %s\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n" + "USN: uuid:Socket-1_0-221438K0100073::urn:Belkin:device:**\r\n\r\n"; - +*/ public UpnpListener(BridgeSettingsDescriptor theSettings, BridgeControlDescriptor theControl) { super(); upnpResponsePort = theSettings.getUpnpResponsePort(); @@ -225,7 +237,7 @@ public class UpnpListener { protected void sendUpnpResponse(DatagramSocket socket, InetAddress requester, int sourcePort) throws IOException { String discoveryResponse = null; if(discoveryTemplateLatest) - discoveryResponse = String.format(discoveryTemplate, Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT, responseAddress, httpServerPort, HuePublicConfig.createConfig("temp", responseAddress).getBridgeid()); + discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort); else discoveryResponse = String.format(discoveryTemplate091516, responseAddress, httpServerPort); if(traceupnp) { diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index b6c2cf1..face627 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -115,12 +115,24 @@ app.service('bridgeService', function ($http, $window, ngToast) { ); }; + this.renumberDevices = function () { + return $http.post(this.state.base + "/exec/renumber").then( + function (response) { + self.viewDevices(); + }, + function (error) { + self.displayError("Cannot renumber devices from habridge: ", error); + } + ); + }; + this.clearDevice = function () { if(self.state.device == null) self.state.device = []; self.state.device.id = ""; self.state.device.mapType = null; self.state.device.mapId = null; + self.state.device.uniqueid = null; self.state.device.name = ""; self.state.device.onUrl = ""; self.state.device.dimUrl = ""; @@ -785,6 +797,9 @@ app.controller('ViewingController', function ($scope, $location, $http, $window, bridgeService.editDevice(device); $location.path('/editdevice'); }; + $scope.renumberDevices = function() { + bridgeService.renumberDevices(); + }; $scope.backupDeviceDb = function (optionalbackupname) { bridgeService.backupDeviceDb(optionalbackupname); }; diff --git a/src/main/resources/public/views/configuration.html b/src/main/resources/public/views/configuration.html index 5a7c61d..9541661 100644 --- a/src/main/resources/public/views/configuration.html +++ b/src/main/resources/public/views/configuration.html @@ -25,6 +25,11 @@

Current devices ({{bridge.devices.length}})

+
+

+ +

+
diff --git a/src/main/resources/public/views/editdevice.html b/src/main/resources/public/views/editdevice.html index d11e6ca..09339bc 100644 --- a/src/main/resources/public/views/editdevice.html +++ b/src/main/resources/public/views/editdevice.html @@ -107,6 +107,14 @@ Clear Device +
+ + +
+ +
+