diff --git a/README.md b/README.md index b8fa4b6..6226ab1 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,40 @@ # ha-bridge -Emulates philips hue api to other home automation gateways. The Amazon echo now supports wemo and philips hue. -Build ------ - -To customize and build it yourself, build a new jar with maven: +Emulates philips hue api to other home automation gateways. The Amazon echo now supports wemo and philips hue. +## Build +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. - -Run ----- - -Then locate the jar and start the server with: +Otherwise go to http://www.bwssystems.com/apps.html to download the latest jar file. +## Run +Then locate the jar and start the server with: ``` java -jar -Dvera.address=192.168.X.Y ha-bridge-0.X.Y.jar -``` +``' +## Available Arguments +### -Dvera.address= 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. - +### -Dupnp.config.address= The server defaults to the first available address on the host. Replace the -Dupnp.config.address= value with the server ipv4 address you would like to use. - +### -Dserver.port= The server defaults to running on port 8080. If you're already running a server (like openHAB) on 8080, -Dserver.port= on the command line. - +### -Dupnp.devices.db= 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=/ or if it is the same directory. - -The default upnp response port will be 50000 otherwise it can be set with -Dupnp.response.port=. - -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= 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. - -Then configure by going to the url for the host you are running on or localhost: +### -Dupnp.resonse.port= +The upnp response port that will be used. The default is 50000. +### -Dupnp.strict= +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= 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= +Turn on tracing for upnp discovery messages. The default is false. +### -Dvtwo.compatibility= +Turns on compatibility for upnp detection and response as it was in the original version of amazon-echo-ha-bridge. The default is true. +## Web Config +Configure by going to the url for the host you are running on or localhost with port you have assigned: ``` -http://192.168.1.240:8080 +http://: ``` - -Command line configure ----- -Register a device via REST by by using a tool and the url, for example: +## Command line configure +Register a device via REST by by using a tool and the url, for example: ``` POST http://host:8080/api/devices { @@ -46,9 +44,8 @@ POST http://host:8080/api/devices "offUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41" } ``` -Dimming ----- -Dimming is also supported by using the expessions ${intensity.percent} or ${intensity.byte} for 0-100 and 0-255 respectively. +## Dimming +Dimming is also supported by using the expessions ${intensity.percent} or ${intensity.byte} for 0-100 and 0-255 respectively. e.g. ``` { @@ -60,14 +57,13 @@ e.g. ``` See the echo's documentation for the dimming phrase. -POST/PUT support ------ +## POST/PUT support added optional fields * contentType (currently un-validated) * httpVerb (POST/PUT/GET only supported) * contentBody your post/put body here -This will allow control of any other application that may need mroe then GET. +This will allow control of any other application that may need more then GET. e.g: ``` { @@ -80,7 +76,7 @@ e.g: "contentBody" : "{\"fooBar\":\"baz\"}" } ``` -Anything that takes an action as a result of an HTTP request will probably work - like putting Vera in and out of night mode: +Anything that takes an action as a result of an HTTP request will probably work - like putting Vera in and out of night mode: ``` { "name": "night mode", @@ -89,10 +85,9 @@ Anything that takes an action as a result of an HTTP request will probably work "onUrl": "http://192.168.1.201:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=SetHouseMode&Mode=3" } ``` -Ask Alexa ----- -After this Tell Alexa: "Alexa, discover my devices" +## Ask Alexa +After this Tell Alexa: "Alexa, discover my devices" -Then you can say "Alexa, Turn on the office light" or whatever name you have given your configured devices. +Then you can say "Alexa, Turn on the office light" or whatever name you have given your configured devices. -To view or remove devices that Alexa knows about, you can use the mobile app Menu / Settings / Connected Home +To view or remove devices that Alexa knows about, you can use the mobile app Menu / Settings / Connected Home \ No newline at end of file diff --git a/pom.xml b/pom.xml index a0f6388..63c34e5 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 0.4.0 + 0.4.1 jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index 3e04ca5..1e0757b 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -7,6 +7,8 @@ public class BridgeSettings { private String upnpdevicedb; private String veraaddress; private boolean upnpStrict; + private boolean traceupnp; + private boolean vtwocompatibility; public String getUpnpConfigAddress() { return upnpconfigaddress; @@ -45,4 +47,18 @@ public class BridgeSettings { public void setUpnpStrict(boolean upnpStrict) { this.upnpStrict = upnpStrict; } + public boolean isTraceupnp() { + return traceupnp; + } + public void setTraceupnp(boolean traceupnp) { + this.traceupnp = traceupnp; + } + + public boolean isVtwocompatibility() { + return vtwocompatibility; + } + public void setVtwocompatibility(boolean vtwocompatibility) { + this.vtwocompatibility = vtwocompatibility; + } + } diff --git a/src/main/java/com/bwssystems/HABridge/HABridge.java b/src/main/java/com/bwssystems/HABridge/HABridge.java index ba8a438..adb494d 100644 --- a/src/main/java/com/bwssystems/HABridge/HABridge.java +++ b/src/main/java/com/bwssystems/HABridge/HABridge.java @@ -55,6 +55,8 @@ public class HABridge { bridgeSettings.setUpnpResponsePort(System.getProperty("upnp.response.port", "50000")); bridgeSettings.setVeraAddress(System.getProperty("vera.address", "192.168.1.100")); bridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "true"))); + bridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("trace.upnp", "false"))); + bridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("vtwo.compatibility", "true"))); // sparkjava config directive to set ip address for the web server to listen on // ipAddress("0.0.0.0"); // not used diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index 43e06c8..7b144c5 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -61,7 +61,7 @@ public class DeviceResource { deviceRepository.save(device); log.debug("Created a Device: " + request.body()); - response.status(HttpStatus.SC_OK); + response.status(HttpStatus.SC_CREATED); } return device; }, new JsonTransformer()); diff --git a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java index aa6a7e9..7c47da2 100644 --- a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java +++ b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java @@ -24,6 +24,10 @@ public class UpnpListener { private String responseAddress; private boolean strict; + + private boolean traceupnp; + + private boolean vTwoCompatibility; public UpnpListener(BridgeSettings theSettings) { super(); @@ -31,6 +35,8 @@ public class UpnpListener { httpServerPort = Integer.valueOf(theSettings.getServerPort()); responseAddress = theSettings.getUpnpConfigAddress(); strict = theSettings.isUpnpStrict(); + traceupnp = theSettings.isTraceupnp(); + vTwoCompatibility = theSettings.isVtwocompatibility(); } public void startListening(){ @@ -66,8 +72,12 @@ public class UpnpListener { DatagramPacket packet = new DatagramPacket(buf, buf.length); upnpMulticastSocket.receive(packet); String packetString = new String(packet.getData()); - if(packetString != null && packetString.startsWith("M-SEARCH * HTTP/1.1")) - log.debug("Got SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + " body : " + packetString); + if(packetString != null && packetString.startsWith("M-SEARCH * HTTP/1.1")) { + if(traceupnp) + log.info("Trace 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()); } @@ -92,7 +102,7 @@ public class UpnpListener { if(body != null && body.startsWith("M-SEARCH * HTTP/1.1") && body.contains("MAN: \"ssdp:discover\"")){ if(strict && body.contains("ST: urn:schemas-upnp-org:device:basic:1")) return true; - else if (!strict) + else if (!strict || vTwoCompatibility) return true; } return false; @@ -105,8 +115,20 @@ public class UpnpListener { "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/0.1\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"; + String discoveryTemplateVTwo = "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" + + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + + "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"; protected void sendUpnpResponse(DatagramSocket socket, InetAddress requester, int sourcePort) throws IOException { - String discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort, getRandomUUIDString()); + String discoveryResponse = null; + if(vTwoCompatibility) + discoveryResponse = String.format(discoveryTemplateVTwo, responseAddress, httpServerPort, getRandomUUIDString()); + else + discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort, getRandomUUIDString()); log.debug("sndUpnpResponse: " + discoveryResponse); DatagramPacket response = new DatagramPacket(discoveryResponse.getBytes(), discoveryResponse.length(), requester, sourcePort); socket.send(response); diff --git a/src/main/java/com/bwssystems/HABridge/upnp/UpnpSettingsResource.java b/src/main/java/com/bwssystems/HABridge/upnp/UpnpSettingsResource.java index a692a2f..e90400c 100644 --- a/src/main/java/com/bwssystems/HABridge/upnp/UpnpSettingsResource.java +++ b/src/main/java/com/bwssystems/HABridge/upnp/UpnpSettingsResource.java @@ -38,6 +38,53 @@ public class UpnpSettingsResource { + "24\n" + "hue_logo_3.png\n" + "\n" + "\n" + "\n" + "\n"; + private String hueTemplateVTwo = "\n" + + "\n" + + "\n" + + "1\n" + + "0\n" + + "\n" + + "http://%s:%s/\n" + //hostname string + "\n" + + "urn:schemas-upnp-org:device:Basic:1\n" + + "Amazon-Echo-HA-Bridge (%s)\n" + + "Royal Philips Electronics\n" + + "http://www.bwssystems.com\n" + + "Hue Emulator for Amazon Echo bridge\n" + + "Philips hue bridge 2012\n" + + "929000226503\n" + + "http://www.bwssystems.com/apps.html\n" + + "01189998819991197253\n" + + "uuid:88f6698f-2c83-4393-bd03-cd54a9f8595\n" + + "\n" + + "\n" + + "(null)\n" + + "(null)\n" + + "(null)\n" + + "(null)\n" + + "(null)\n" + + "\n" + + "\n" + + "index.html\n" + + "\n" + + "\n" + + "image/png\n" + + "48\n" + + "48\n" + + "24\n" + + "hue_logo_0.png\n" + + "\n" + + "\n" + + "image/png\n" + + "120\n" + + "120\n" + + "24\n" + + "hue_logo_3.png\n" + + "\n" + + "\n" + + "\n" + + "\n"; + public UpnpSettingsResource(BridgeSettings theSettings) { super(); setupListener(theSettings); @@ -49,7 +96,11 @@ public class UpnpSettingsResource { get("/description.xml", "application/xml; charset=utf-8", (request, response) -> { log.debug("upnp device settings requested: " + request.params(":id") + " from " + request.ip()); String portNumber = Integer.toString(request.port()); - String filledTemplate = String.format(hueTemplate, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress()); + String filledTemplate = null; + if(theSettings.isVtwocompatibility()) + filledTemplate = String.format(hueTemplateVTwo, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress()); + else + filledTemplate = String.format(hueTemplate, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress()); log.debug("upnp device settings response: " + filledTemplate); // response.header("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); // response.header("Pragma", "no-cache"); diff --git a/src/main/resources/public/index.html b/src/main/resources/public/index.html index 52b74a6..60dfe3f 100644 --- a/src/main/resources/public/index.html +++ b/src/main/resources/public/index.html @@ -36,7 +36,7 @@ diff --git a/src/main/resources/public/views/editor.html b/src/main/resources/public/views/editor.html index 4e7f992..9597e6b 100644 --- a/src/main/resources/public/views/editor.html +++ b/src/main/resources/public/views/editor.html @@ -103,6 +103,40 @@ ng-click="testUrl(device.offUrl)">Test +
+
+ + +
+ +
+
+
+
+
+ + +
+ +
+
+
+
+
+ + +
+ +
+
+
+