From 208b1cad2af19d1c704d34bea97523f9907ae55b Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 9 Jun 2017 12:57:18 -0500 Subject: [PATCH] Fixed HAL control issue, added switch status, added new ${device.xxx} replacement items and interface selection for upnp --- README.md | 4 ++- pom.xml | 2 +- .../HABridge/BridgeSettingsDescriptor.java | 14 +++++++++++ .../HABridge/dao/DeviceDescriptor.java | 3 ++- .../HABridge/dao/DeviceRepository.java | 1 + .../HABridge/hue/DeviceDataDecode.java | 18 +++++++++++++ .../HABridge/plugins/hal/HalHome.java | 25 ++++++++++++++----- .../HABridge/upnp/UpnpListener.java | 7 +++++- .../resources/public/views/configuration.html | 2 ++ src/main/resources/public/views/system.html | 6 +++++ 10 files changed, 72 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1f27cdab..461dfa50 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,8 @@ The default location for the configuration file to contain the settings for the 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 `/ explicitly. #### UPNP IP Address The server defaults to the first available address on the host if this is not given. This default may NOT be the correct IP that is your public IP for your host on the network. It is best to set this parameter to not have discovery issues. Replace this value with the server ipv4 address you would like to use as the address that any upnp device will call after discovery. +#### Use UPNP Address Interface +The server tries to bind to all interfaces to respond to UPNP request. Setting this to `true` will make the binding to the interface that has the `UPNP IP Address`. The default is to be all interfaces which is set as false. #### Web Server IP Address The server defaults to all interfaces on the machine (0.0.0.0). Replace this value with the server ipv4 address you would like to use as the address that will bind to a specific ip address on an interface if you would like. This is only necessary if you want to isolate how access is handled to the web UI. #### Web Server Port @@ -408,7 +410,7 @@ You can control items that require special calculated values using ${intensity.m For the items that want to have a date time put into the message, utilize ${time.format(yyyy-MM-ddTHH:mm:ssXXX)} where "yyyy-MM-ddTHH:mm:ssXXX" can be any format from the Java SimpleDateFormat documented here: https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html -Also, device data can be inserted into your payloads by the use of "${device.name}", "${device.id}", "${device.uniqueid}", "${device.targetDevice}", "${device.mapId}", "${device.mapType}" and "${device.deviceType}". These work just like the dimming value replacements. +Also, device data can be inserted into your payloads by the use of "${device.name}", "${device.id}", "${device.uniqueid}", "${device.targetDevice}", "${device.mapId}", "${device.mapType}", "${device.deviceType}", "${device.requesterAddress}", "${device.description}" and "${device.comments}". These work just like the dimming value replacements. e.g. ``` [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&DeviceNum=10&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=${intensity.math(X/4)}","type":"httpDevice"}] diff --git a/pom.xml b/pom.xml index 43d074ce..66cc597e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.5.1a + 4.5.1b jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java index 797f7b94..3daf54cf 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java @@ -12,6 +12,9 @@ public class BridgeSettingsDescriptor { @SerializedName("upnpconfigaddress") @Expose private String upnpconfigaddress; + @SerializedName("useupnpiface") + @Expose + private boolean useupnpiface; @SerializedName("serverport") @Expose private Integer serverport; @@ -104,6 +107,7 @@ public class BridgeSettingsDescriptor { public BridgeSettingsDescriptor() { super(); this.upnpstrict = true; + this.useupnpiface = false; this.traceupnp = false; this.nestconfigured = false; this.veraconfigured = false; @@ -113,8 +117,12 @@ public BridgeSettingsDescriptor() { this.halconfigured = false; this.mqttconfigured = false; this.hassconfigured = false; + this.domoticzconfigured = false; + this.somfyconfigured = false; + this.lifxconfigured = false; this.farenheit = true; this.whitelist = null; + this.securityData = null; this.settingsChanged = false; this.myechourl = "echo.amazon.com/#cards"; this.webaddress = "0.0.0.0"; @@ -126,6 +134,12 @@ public String getUpnpConfigAddress() { public void setUpnpConfigAddress(String upnpConfigAddress) { this.upnpconfigaddress = upnpConfigAddress; } + public boolean isUseupnpiface() { + return useupnpiface; + } + public void setUseupnpiface(boolean useupnpiface) { + this.useupnpiface = useupnpiface; + } public Integer getServerPort() { return serverport; } diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java index c31b0d03..7480be7a 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java @@ -74,7 +74,8 @@ public class DeviceDescriptor{ @SerializedName("comments") @Expose private String comments; - + @SerializedName("deviceState") + @Expose private DeviceState deviceState; public String getName() { diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java index cf44ecb8..61b38edf 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java @@ -61,6 +61,7 @@ private void _loadRepository(Path aPath){ { DeviceDescriptor list[] = gson.fromJson(jsonContent, DeviceDescriptor[].class); for(int i = 0; i < list.length; i++) { + list[i].setDeviceState(null); put(list[i].getId(), list[i]); if(Integer.decode(list[i].getId()) > nextId) { nextId = Integer.decode(list[i].getId()); diff --git a/src/main/java/com/bwssystems/HABridge/hue/DeviceDataDecode.java b/src/main/java/com/bwssystems/HABridge/hue/DeviceDataDecode.java index 7997d152..b6dc5c3a 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/DeviceDataDecode.java +++ b/src/main/java/com/bwssystems/HABridge/hue/DeviceDataDecode.java @@ -14,6 +14,9 @@ public class DeviceDataDecode { private static final String DEVICE_MAPTYPE = "${device.mapType}"; private static final String DEVICE_DEVICETYPE = "${device.deviceType}"; private static final String DEVICE_TARGETDEVICE = "${device.targetDevice}"; + private static final String DEVICE_REQUESTERADDRESS = "${device.requesterAddress}"; + private static final String DEVICE_DESCRIPTION = "${device.description}"; + private static final String DEVICE_COMMENTS = "${device.comments}"; public static String replaceDeviceData(String request, DeviceDescriptor device) { if (request == null) { @@ -58,6 +61,21 @@ public static String replaceDeviceData(String request, DeviceDescriptor device) notDone = true; } + if (request.contains(DEVICE_REQUESTERADDRESS)) { + request = request.replace(DEVICE_REQUESTERADDRESS, device.getRequesterAddress()); + notDone = true; + } + + if (request.contains(DEVICE_DESCRIPTION)) { + request = request.replace(DEVICE_DESCRIPTION, device.getDescription()); + notDone = true; + } + + if (request.contains(DEVICE_COMMENTS)) { + request = request.replace(DEVICE_COMMENTS, device.getComments()); + notDone = true; + } + log.debug("Request <<" + request + ">>, not done: " + notDone); } return request; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java index ecafb892..5dac5a63 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java @@ -112,19 +112,20 @@ private Boolean addHalDevices(List theDeviceList, List the @Override public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) { + boolean halFound = false; String responseString = null; String theUrl = anItem.getItem().getAsString(); if(theUrl != null && !theUrl.isEmpty () && theUrl.contains("http")) { String intermediate = theUrl.substring(theUrl.indexOf("://") + 3); String hostPortion = intermediate.substring(0, intermediate.indexOf('/')); // String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1); - String hostAddr = null; +// String hostAddr = null; // String port = null; - if (hostPortion.contains(":")) { - hostAddr = hostPortion.substring(0, intermediate.indexOf(':')); +// if (hostPortion.contains(":")) { +// hostAddr = hostPortion.substring(0, intermediate.indexOf(':')); // port = hostPortion.substring(intermediate.indexOf(':') + 1); - } else - hostAddr = hostPortion; +// } else +// hostAddr = hostPortion; log.debug("executing HUE api request to Http " + (anItem.getHttpVerb() == null ? "GET" : anItem.getHttpVerb()) + ": " + anItem.getItem().getAsString()); @@ -137,7 +138,8 @@ public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String for (Map.Entry entry : hals.entrySet()) { - if(entry.getValue().getHalAddress().getIp().equals(hostAddr)) { + if(entry.getValue().getHalAddress().getIp().equals(hostPortion)) { + halFound = true; if(entry.getValue().getHalAddress().getSecure()!= null && entry.getValue().getHalAddress().getSecure()) anUrl = "https://" + anUrl; else @@ -146,6 +148,10 @@ public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String if(!anUrl.contains("?Token=")) anUrl = anUrl + "?Token=" + entry.getValue().getHalAddress().getPassword(); + log.debug("executing HUE api request to Http " + + (anItem.getHttpVerb() == null ? "GET" : anItem.getHttpVerb()) + ": " + + anUrl); + if (entry.getValue().deviceCommand(anUrl) == null) { log.warn("Error on calling hal to change device state: " + anUrl); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, @@ -155,6 +161,13 @@ public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String } } } + + if(!halFound) { + log.warn("No HAL found to call: " + theUrl); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "No HAL found.", "/lights/" + + lightId + "state", null, null).getTheErrors(), HueError[].class); + } return responseString; } diff --git a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java index b7e80c24..8f74a80d 100644 --- a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java +++ b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java @@ -25,6 +25,7 @@ public class UpnpListener { private String responseAddress; private boolean strict; private boolean traceupnp; + private boolean useUpnpIface; private BridgeControlDescriptor bridgeControl; private String bridgeId; private String bridgeSNUUID; @@ -74,6 +75,7 @@ public UpnpListener(BridgeSettingsDescriptor theSettings, BridgeControlDescripto responseAddress = theSettings.getUpnpConfigAddress(); strict = theSettings.isUpnpStrict(); traceupnp = theSettings.isTraceupnp(); + useUpnpIface = theSettings.isUseupnpiface(); bridgeControl = theControl; aHueConfig = HuePublicConfig.createConfig("temp", responseAddress, HueConstants.HUB_VERSION); bridgeId = aHueConfig.getBridgeid(); @@ -114,7 +116,10 @@ public boolean startListening(){ else log.debug(name + " ... has addr " + addr); if (InetAddressUtils.isIPv4Address(addr.getHostAddress())) { - IPsPerNic++; + if(!useUpnpIface) + IPsPerNic++; + else if(addr.getHostAddress().equals(responseAddress)) + IPsPerNic++; } } log.debug("Checking " + name + " to our interface set"); diff --git a/src/main/resources/public/views/configuration.html b/src/main/resources/public/views/configuration.html index def1839c..a3664e70 100644 --- a/src/main/resources/public/views/configuration.html +++ b/src/main/resources/public/views/configuration.html @@ -43,6 +43,7 @@

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

ID Name Description + Device State Type Target Inactive @@ -55,6 +56,7 @@

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

{{device.id}} {{device.name}} {{device.description}} + on={{device.deviceState.on}},bri={{device.deviceState.on}},hue={{device.deviceState.hue}},sat={{device.deviceState.sat}},effect={{device.deviceState.effect}},ct={{device.deviceState.ct}},alert={{device.deviceState.alert}},colormode={{device.deviceState.colormode}},reachable={{device.deviceState.reachable}},XYList={{device.deviceState.xy}} {{device.deviceType}} {{device.targetDevice}} {{device.inactive}} diff --git a/src/main/resources/public/views/system.html b/src/main/resources/public/views/system.html index 7a902385..7d5ef6c2 100644 --- a/src/main/resources/public/views/system.html +++ b/src/main/resources/public/views/system.html @@ -82,6 +82,12 @@

Bridge Settings

ng-model="bridge.settings.upnpconfigaddress" placeholder="192.168.1.1"> + + Use UPNP Address Interface Only + {{bridge.settings.useupnpiface}} + Web Server IP Address