mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-16 18:24:36 +00:00
Updated logging for upnp listener and description service. Added method
in huemulator for "/*" which was present in the armzilla version for the Harmony Hub. Updated the readme.
This commit is contained in:
@@ -20,7 +20,7 @@ The server defaults to the first available address on the host. Replace the -Dup
|
|||||||
The server defaults to running on port 8080. If you're already running a server (like openHAB) on 8080, -Dserver.port=`<port>` on the command line.
|
The server defaults to running on port 8080. If you're already running a server (like openHAB) on 8080, -Dserver.port=`<port>` on the command line.
|
||||||
### -Dupnp.device.db=`<filepath>`
|
### -Dupnp.device.db=`<filepath>`
|
||||||
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=`<directory>/<filename> or <filename>` if it is the same directory.
|
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=`<directory>/<filename> or <filename>` if it is the same directory.
|
||||||
### -Dupnp.resonse.port=`<port>`
|
### -Dupnp.response.port=`<port>`
|
||||||
The upnp response port that will be used. The default is 50000.
|
The upnp response port that will be used. The default is 50000.
|
||||||
### -Dupnp.strict=`<true|false>`
|
### -Dupnp.strict=`<true|false>`
|
||||||
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=`<true|false>` 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=false.
|
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=`<true|false>` 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=false.
|
||||||
|
|||||||
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>0.4.3</version>
|
<version>0.4.4</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>HA Bridge</name>
|
<name>HA Bridge</name>
|
||||||
|
|||||||
@@ -100,6 +100,31 @@ public class HueMulator {
|
|||||||
return "[{\"success\":{\"username\":\"" + newUser + "\"}}]";
|
return "[{\"success\":{\"username\":\"" + newUser + "\"}}]";
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
// http://ip_address:port/api/* with body of user request returns json object for a success of user add - This method is for Harmony Hub
|
||||||
|
post(HUE_CONTEXT + "/*", "application/json", (request, response) -> {
|
||||||
|
UserCreateRequest aNewUser = null;
|
||||||
|
String newUser = null;
|
||||||
|
String aDeviceType = null;
|
||||||
|
|
||||||
|
log.info("HH trace: hue api user create requested: " + request.body() + " from " + request.ip());
|
||||||
|
|
||||||
|
if(request.body() != null && !request.body().isEmpty()) {
|
||||||
|
aNewUser = new Gson().fromJson(request.body(), UserCreateRequest.class);
|
||||||
|
newUser = aNewUser.getUsername();
|
||||||
|
aDeviceType = aNewUser.getDevicetype();
|
||||||
|
}
|
||||||
|
if(newUser == null)
|
||||||
|
newUser = "lightssystem";
|
||||||
|
|
||||||
|
if(aDeviceType == null)
|
||||||
|
aDeviceType = "<not given>";
|
||||||
|
log.debug("HH trace: hue api user create requested for device type: " + aDeviceType + " and username: " + newUser);
|
||||||
|
|
||||||
|
response.type("application/json; charset=utf-8");
|
||||||
|
response.status(HttpStatus.SC_OK);
|
||||||
|
return "[{\"success\":{\"username\":\"" + newUser + "\"}}]";
|
||||||
|
} );
|
||||||
|
|
||||||
// http://ip_address:port/api/{userId} returns json objects for the full state
|
// http://ip_address:port/api/{userId} returns json objects for the full state
|
||||||
get(HUE_CONTEXT + "/:userid", "application/json", (request, response) -> {
|
get(HUE_CONTEXT + "/:userid", "application/json", (request, response) -> {
|
||||||
String userId = request.params(":userid");
|
String userId = request.params(":userid");
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class UpnpListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void startListening(){
|
public void startListening(){
|
||||||
log.info("UPNP Discovery Listener started....");
|
log.info("UPNP Discovery Listener starting....");
|
||||||
|
|
||||||
try (DatagramSocket responseSocket = new DatagramSocket(upnpResponsePort);
|
try (DatagramSocket responseSocket = new DatagramSocket(upnpResponsePort);
|
||||||
MulticastSocket upnpMulticastSocket = new MulticastSocket(UPNP_DISCOVERY_PORT);) {
|
MulticastSocket upnpMulticastSocket = new MulticastSocket(UPNP_DISCOVERY_PORT);) {
|
||||||
@@ -55,7 +55,10 @@ public class UpnpListener {
|
|||||||
|
|
||||||
while (addrs.hasMoreElements()) {
|
while (addrs.hasMoreElements()) {
|
||||||
InetAddress addr = addrs.nextElement();
|
InetAddress addr = addrs.nextElement();
|
||||||
log.debug(name + " ... has addr " + addr);
|
if(traceupnp)
|
||||||
|
log.info("Traceupnp: " + name + " ... has addr " + addr);
|
||||||
|
else
|
||||||
|
log.debug(name + " ... has addr " + addr);
|
||||||
if (InetAddressUtils.isIPv4Address(addr.getHostAddress())) {
|
if (InetAddressUtils.isIPv4Address(addr.getHostAddress())) {
|
||||||
IPsPerNic++;
|
IPsPerNic++;
|
||||||
}
|
}
|
||||||
@@ -63,10 +66,15 @@ public class UpnpListener {
|
|||||||
log.debug("Checking " + name + " to our interface set");
|
log.debug("Checking " + name + " to our interface set");
|
||||||
if (IPsPerNic > 0) {
|
if (IPsPerNic > 0) {
|
||||||
upnpMulticastSocket.joinGroup(socketAddress, xface);
|
upnpMulticastSocket.joinGroup(socketAddress, xface);
|
||||||
log.debug("Adding " + name + " to our interface set");
|
if(traceupnp)
|
||||||
|
log.info("Traceupnp: Adding " + name + " to our interface set");
|
||||||
|
else
|
||||||
|
log.debug("Adding " + name + " to our interface set");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("UPNP Discovery Listener running and ready....");
|
||||||
|
|
||||||
while(true){ //trigger shutdown here
|
while(true){ //trigger shutdown here
|
||||||
byte[] buf = new byte[1024];
|
byte[] buf = new byte[1024];
|
||||||
DatagramPacket packet = new DatagramPacket(buf, buf.length);
|
DatagramPacket packet = new DatagramPacket(buf, buf.length);
|
||||||
@@ -74,9 +82,9 @@ public class UpnpListener {
|
|||||||
String packetString = new String(packet.getData());
|
String packetString = new String(packet.getData());
|
||||||
if(packetString != null && packetString.contains("M-SEARCH")) {
|
if(packetString != null && packetString.contains("M-SEARCH")) {
|
||||||
if(traceupnp)
|
if(traceupnp)
|
||||||
log.info("Trace SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + " body : " + packetString);
|
log.info("Traceupnp: SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + packetString);
|
||||||
else
|
else
|
||||||
log.debug("Got SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + " body : " + packetString);
|
log.debug("Got SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + packetString);
|
||||||
}
|
}
|
||||||
if(isSSDPDiscovery(packetString)){
|
if(isSSDPDiscovery(packetString)){
|
||||||
sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort());
|
sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort());
|
||||||
@@ -84,7 +92,7 @@ public class UpnpListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("UpnpListener encountered an error. Shutting down", e);
|
log.error("UpnpListener encountered an error opening sockets. Shutting down", e);
|
||||||
|
|
||||||
}
|
}
|
||||||
log.info("UPNP Discovery Listener Stopped");
|
log.info("UPNP Discovery Listener Stopped");
|
||||||
@@ -100,11 +108,23 @@ public class UpnpListener {
|
|||||||
// log.debug("Check if this is a MAN ssdp-discover packet for a upnp basic device: " + 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
|
//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(body != null && body.contains("M-SEARCH") && body.contains("\"ssdp:discover\"")){
|
||||||
if(strict && body.startsWith("M-SEARCH * HTTP/1.1") && body.contains("MAN: \"ssdp:discover\"") && body.contains("ST: urn:schemas-upnp-org:device:basic:1"))
|
if(traceupnp)
|
||||||
|
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")))
|
||||||
|
{
|
||||||
|
if(traceupnp)
|
||||||
|
log.info("Traceupnp: isSSDPDiscovery found message to be valid under strict rules - strict: " + strict + ", vTwo.Compatibility: " + vTwoCompatibility);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
else if (!strict || vTwoCompatibility)
|
else if (!strict || vTwoCompatibility)
|
||||||
|
{
|
||||||
|
if(traceupnp)
|
||||||
|
log.info("Traceupnp: isSSDPDiscovery found message to be valid under loose rules - strict: " + strict + ", vTwo.Compatibility: " + vTwoCompatibility);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(traceupnp)
|
||||||
|
log.info("Traceupnp: isSSDPDiscovery found message to not be valid - strict: " + strict + ", vTwo.Compatibility: " + vTwoCompatibility);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +149,10 @@ public class UpnpListener {
|
|||||||
discoveryResponse = String.format(discoveryTemplateVTwo, responseAddress, httpServerPort, getRandomUUIDString());
|
discoveryResponse = String.format(discoveryTemplateVTwo, responseAddress, httpServerPort, getRandomUUIDString());
|
||||||
else
|
else
|
||||||
discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort, getRandomUUIDString());
|
discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort, getRandomUUIDString());
|
||||||
log.debug("sndUpnpResponse: " + discoveryResponse);
|
if(traceupnp)
|
||||||
|
log.info("Traceupnp: sendUpnpResponse: " + discoveryResponse);
|
||||||
|
else
|
||||||
|
log.debug("sendUpnpResponse: " + discoveryResponse);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ public class UpnpSettingsResource {
|
|||||||
|
|
||||||
private Logger log = LoggerFactory.getLogger(UpnpSettingsResource.class);
|
private Logger log = LoggerFactory.getLogger(UpnpSettingsResource.class);
|
||||||
|
|
||||||
|
private BridgeSettings theSettings;
|
||||||
|
|
||||||
private String hueTemplate = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<root xmlns=\"urn:schemas-upnp-org:device-1-0\">\n"
|
private String hueTemplate = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<root xmlns=\"urn:schemas-upnp-org:device-1-0\">\n"
|
||||||
+ "<specVersion>\n" + "<major>1</major>\n" + "<minor>0</minor>\n" + "</specVersion>\n"
|
+ "<specVersion>\n" + "<major>1</major>\n" + "<minor>0</minor>\n" + "</specVersion>\n"
|
||||||
+ "<URLBase>http://%s:%s/</URLBase>\n" + // hostname string
|
+ "<URLBase>http://%s:%s/</URLBase>\n" + // hostname string
|
||||||
@@ -87,21 +89,28 @@ public class UpnpSettingsResource {
|
|||||||
|
|
||||||
public UpnpSettingsResource(BridgeSettings theSettings) {
|
public UpnpSettingsResource(BridgeSettings theSettings) {
|
||||||
super();
|
super();
|
||||||
setupListener(theSettings);
|
this.theSettings = theSettings;
|
||||||
|
setupListener(this.theSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupListener (BridgeSettings theSettings) {
|
private void setupListener (BridgeSettings theSettings) {
|
||||||
log.info("Hue description service started....");
|
log.info("Hue description service started....");
|
||||||
// http://ip_adress:port/description.xml which returns the xml configuration for the hue emulator
|
// http://ip_adress:port/description.xml which returns the xml configuration for the hue emulator
|
||||||
get("/description.xml", "application/xml; charset=utf-8", (request, response) -> {
|
get("/description.xml", "application/xml; charset=utf-8", (request, response) -> {
|
||||||
log.debug("upnp device settings requested: " + request.params(":id") + " from " + request.ip());
|
if(theSettings.isTraceupnp())
|
||||||
|
log.info("Traceupnp: upnp device settings requested: " + request.params(":id") + " from " + request.ip() + ":" + request.port());
|
||||||
|
else
|
||||||
|
log.debug("upnp device settings requested: " + request.params(":id") + " from " + request.ip() + ":" + request.port());
|
||||||
String portNumber = Integer.toString(request.port());
|
String portNumber = Integer.toString(request.port());
|
||||||
String filledTemplate = null;
|
String filledTemplate = null;
|
||||||
if(theSettings.isVtwocompatibility())
|
if(theSettings.isVtwocompatibility())
|
||||||
filledTemplate = String.format(hueTemplateVTwo, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress());
|
filledTemplate = String.format(hueTemplateVTwo, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress());
|
||||||
else
|
else
|
||||||
filledTemplate = String.format(hueTemplate, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress());
|
filledTemplate = String.format(hueTemplate, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress());
|
||||||
log.debug("upnp device settings response: " + filledTemplate);
|
if(theSettings.isTraceupnp())
|
||||||
|
log.info("Traceupnp: upnp device settings response: " + filledTemplate);
|
||||||
|
else
|
||||||
|
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("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
|
||||||
// response.header("Pragma", "no-cache");
|
// response.header("Pragma", "no-cache");
|
||||||
// response.header("Expires", "Mon, 1 Aug 2011 09:00:00 GMT");
|
// response.header("Expires", "Mon, 1 Aug 2011 09:00:00 GMT");
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||||
<li><a href="http://www.bwssystems.com" target="_blank">Developed by BWS Systems</a></li>
|
<li><a href="http://www.bwssystems.com" target="_blank">Developed by BWS Systems</a></li>
|
||||||
<li><a href="http://www.amazon.com/echo" target="_blank">Amazon Echo</a></li>
|
<li><a href="http://www.amazon.com/echo" target="_blank">Amazon Echo</a></li>
|
||||||
<li><a href="#">HA Bridge Version 0.4.3</a></li>
|
<li><a href="#">HA Bridge Version 0.4.4</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Reference in New Issue
Block a user