From 4c86e42776fabdbcdd96d2191ec13cf7f0a054be Mon Sep 17 00:00:00 2001 From: Admin Date: Mon, 11 Dec 2017 16:40:59 -0600 Subject: [PATCH] Added hex color codes, added swith to utilize groups/rooms. updated exec to use new path parsing. Revert back to Spark 2.3 due to issues. --- pom.xml | 4 +-- .../bwssystems/HABridge/BridgeSecurity.java | 35 +++++++++++++++++-- .../HABridge/BridgeSettingsDescriptor.java | 10 ++++++ .../com/bwssystems/HABridge/HABridge.java | 2 +- .../devicemanagmeent/DeviceResource.java | 5 ++- .../bwssystems/HABridge/hue/ColorDecode.java | 24 +++++++++++++ .../bwssystems/HABridge/hue/HueMulator.java | 34 ++++++++++++++---- .../HABridge/plugins/exec/CommandHome.java | 6 ++-- src/main/resources/public/scripts/app.js | 4 +-- src/main/resources/public/views/system.html | 6 ++++ 10 files changed, 112 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index cf0a3da..1b22967 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 5.0.0 + 5.0.0a jar HA Bridge @@ -63,7 +63,7 @@ com.sparkjava spark-core - 2.7.1 + 2.3 slf4j-simple diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java b/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java index 0c6fb70..a91db6b 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java @@ -238,6 +238,31 @@ public class BridgeSecurity { return null; } + public String findWhitelistUserByDeviceType(String aDeviceType) { + String validUser = null; + boolean found = false; + WhitelistEntry anEntry = null; + if (aDeviceType != null) { + if (securityDescriptor.getWhitelist() != null) { + Set theUserIds = securityDescriptor.getWhitelist().keySet(); + Iterator userIterator = theUserIds.iterator(); + while (!found && userIterator.hasNext()) { + validUser = userIterator.next(); + anEntry = securityDescriptor.getWhitelist().get(validUser); + if (anEntry.getName().equals(aDeviceType)) { + found = true; + log.debug("findWhitelistUserByDeviceType: found a user <" + validUser + "> for device type <" + aDeviceType + ">"); + } + } + } + } + + if(!found) + validUser = null; + + return validUser; + } + private void newWhitelistUser(String aUser, String userDescription) { if (securityDescriptor.getWhitelist() == null) { securityDescriptor.setWhitelist(new HashMap<>()); @@ -250,8 +275,14 @@ public class BridgeSecurity { } public String createWhitelistUser(String userDescription) { - String aUser = getNewUserID(); - newWhitelistUser(aUser, userDescription); + String aUser = null; + String theEntry = findWhitelistUserByDeviceType(userDescription); + if(theEntry == null) { + aUser = getNewUserID(); + newWhitelistUser(aUser, userDescription); + } else { + aUser = theEntry; + } return aUser; } diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java index 6bb1108..7da1551 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java @@ -15,6 +15,9 @@ public class BridgeSettingsDescriptor { @SerializedName("useupnpiface") @Expose private boolean useupnpiface; + @SerializedName("userooms") + @Expose + private boolean userooms; @SerializedName("serverport") @Expose private Integer serverport; @@ -119,6 +122,7 @@ public class BridgeSettingsDescriptor { super(); this.upnpstrict = true; this.useupnpiface = false; + this.userooms = false; this.traceupnp = false; this.nestconfigured = false; this.veraconfigured = false; @@ -152,6 +156,12 @@ public class BridgeSettingsDescriptor { public void setUseupnpiface(boolean useupnpiface) { this.useupnpiface = useupnpiface; } + public boolean isUserooms() { + return userooms; + } + public void setUserooms(boolean userooms) { + this.userooms = userooms; + } public Integer getServerPort() { return serverport; } diff --git a/src/main/java/com/bwssystems/HABridge/HABridge.java b/src/main/java/com/bwssystems/HABridge/HABridge.java index 55b48cf..72cd939 100644 --- a/src/main/java/com/bwssystems/HABridge/HABridge.java +++ b/src/main/java/com/bwssystems/HABridge/HABridge.java @@ -62,7 +62,7 @@ public class HABridge { // sparkjava config directive to set port for the web server to listen on port(bridgeSettings.getBridgeSettingsDescriptor().getServerPort()); staticFileLocation("/public"); - initExceptionHandler((e) -> HABridge.theExceptionHandler(e, bridgeSettings.getBridgeSettingsDescriptor().getServerPort())); +// initExceptionHandler((e) -> HABridge.theExceptionHandler(e, bridgeSettings.getBridgeSettingsDescriptor().getServerPort())); if(!bridgeSettings.getBridgeControl().isReinit()) init(); bridgeSettings.getBridgeControl().setReinit(false); diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index 849ec21..99a3743 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -48,7 +48,10 @@ public class DeviceResource { public DeviceResource(BridgeSettings theSettings, HomeManager aHomeManager) { bridgeSettings = theSettings; this.deviceRepository = new DeviceRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpDeviceDb()); - this.groupRepository = new GroupRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpGroupDb()); + if(bridgeSettings.getBridgeSettingsDescriptor().isUserooms()) + this.groupRepository = new GroupRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpGroupDb()); + else + this.groupRepository = null; homeManager = aHomeManager; aGsonHandler = new GsonBuilder().create(); setupEndpoints(); diff --git a/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java index 34506f4..b9f26a2 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java +++ b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java @@ -16,6 +16,10 @@ public class ColorDecode { private static final String COLOR_R = "${color.r}"; private static final String COLOR_G = "${color.g}"; private static final String COLOR_B = "${color.b}"; + private static final String COLOR_RX = "${color.rx}"; + private static final String COLOR_GX = "${color.gx}"; + private static final String COLOR_BX = "${color.bx}"; + private static final String COLOR_RGBX = "${color.rgbx}"; private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}"); public static List convertCIEtoRGB(List xy, int brightness) { @@ -175,6 +179,26 @@ public class ColorDecode { notDone = true; } + if (request.contains(COLOR_RX)) { + request = request.replace(COLOR_RX, String.format("%02X", rgb.get(0))); + notDone = true; + } + + if (request.contains(COLOR_GX)) { + request = request.replace(COLOR_GX, String.format("%02X", rgb.get(1))); + notDone = true; + } + + if (request.contains(COLOR_BX)) { + request = request.replace(COLOR_BX, String.format("%02X", rgb.get(2))); + notDone = true; + } + + if (request.contains(COLOR_RGBX)) { + request = request.replace(COLOR_RGBX, String.format("%02X%02X%02X", rgb.get(0), rgb.get(1), rgb.get(2))); + notDone = true; + } + Matcher m = COLOR_MILIGHT.matcher(request); while (m.find()) { int group = Integer.parseInt(m.group(1)); diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 23cc4fa..c0e07a0 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -127,7 +127,12 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return addGroup(request.params(":userid"), request.ip(), request.body()); + if(bridgeSettings.isUserooms()) { + return addGroup(request.params(":userid"), request.ip(), request.body()); + } else { + log.debug("group add requested from (No Use Rooms) " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + return "[{\"success\":{\"id\":\"1\"}}]"; + } }); // http://ip_address:port/api/:userid/groups/ // delete a group @@ -135,7 +140,12 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return deleteGroup(request.params(":userid"), request.params(":groupid"), request.ip()); + if(bridgeSettings.isUserooms()) { + return deleteGroup(request.params(":userid"), request.params(":groupid"), request.ip()); + } else { + log.debug("delete to groups API from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + return "[{\"error\":{\"address\": \"/groups/0/action/scene\", \"type\":7, \"description\": \"invalid value, dummy for parameter, scene\"}}]"; + } }); // http://ip_address:port/api/:userid/groups/ // modify a single group @@ -143,7 +153,12 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return modifyGroup(request.params(":userid"), request.params(":groupid"), request.ip(), request.body()); + if(bridgeSettings.isUserooms()) { + return modifyGroup(request.params(":userid"), request.params(":groupid"), request.ip(), request.body()); + } else { + log.debug("put to groups API from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + return "[{\"error\":{\"address\": \"/groups/0/action/scene\", \"type\":7, \"description\": \"invalid value, dummy for parameter, scene\"}}]"; + } }); // http://ip_address:port/api/:userid/groups//action // group acions @@ -151,7 +166,12 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return changeGroupState(request.params(":userid"), request.params(":groupid"), request.body(), request.ip(), false); + if(bridgeSettings.isUserooms()) { + return changeGroupState(request.params(":userid"), request.params(":groupid"), request.body(), request.ip(), false); + } else { + log.debug("put action to groups API from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + return "[{\"error\":{\"address\": \"/groups/0/action/scene\", \"type\":7, \"description\": \"invalid value, dummy for parameter, scene\"}}]"; + } }); // http://ip_address:port/api/{userId}/scenes returns json objects of // all scenes configured @@ -922,7 +942,7 @@ public class HueMulator { toContinue = true; if(toContinue) { - log.debug("hue api user create requested: " + body + " from " + ipAddress); + log.debug("user add toContinue was true, creating user."); if (body != null && !body.isEmpty()) { try { @@ -938,6 +958,8 @@ public class HueMulator { if (aDeviceType == null) aDeviceType = ""; + else + aDeviceType = aDeviceType + "#" + ipAddress; if (newUser == null) { newUser = bridgeSettingMaster.getBridgeSecurity().createWhitelistUser(aDeviceType); @@ -1084,7 +1106,7 @@ public class HueMulator { } private String changeState(String userId, String lightId, String body, String ipAddress, boolean ignoreRequester) { - if (Integer.parseInt(lightId) >= 10000) { + if (bridgeSettings.isUserooms() && Integer.parseInt(lightId) >= 10000) { return changeGroupState(userId, String.valueOf(Integer.parseInt(lightId) - 10000), body, ipAddress, true); } String responseString = null; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java b/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java index a501c7b..fcb4708 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java @@ -1,5 +1,6 @@ package com.bwssystems.HABridge.plugins.exec; +import java.io.File; import java.io.IOException; import org.slf4j.Logger; @@ -45,10 +46,7 @@ public class CommandHome implements Home { intermediate = TimeDecode.replaceTimeValue(intermediate); String execGarden = theSettings.getBridgeSecurity().getExecGarden(); if(execGarden != null && !execGarden.trim().isEmpty()) { - if(System.getProperty("os.name").toLowerCase().indexOf("win") >= 0) - intermediate = execGarden + "\\" + intermediate; - else - intermediate = execGarden + "/" + intermediate; + intermediate = new File(execGarden.trim(), intermediate).getAbsolutePath(); } String anError = doExecRequest(intermediate, lightId); diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 9ec0790..1a539ee 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -2068,7 +2068,7 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n onpayload = "http://" + fibarodevice.fibaroaddress + ":" + fibarodevice.fibaroport + "/api/callAction?deviceID=" + fibarodevice.id + "&name=turnOn"; offpayload = "http://" + fibarodevice.fibaroaddress + ":" + fibarodevice.fibaroport + "/api/callAction?deviceID=" + fibarodevice.id + "&name=turnOff"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, fibarodevice.id, fibarodevice.name, fibarodevice.fibaroname, "switch", "fibaroDevice", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, fibarodevice.id, fibarodevice.name, fibarodevice.fibaroname, "switch", "fibaroDevice", null, null); bridgeService.state.device.headers = "[{\"name\":\"Authorization\",\"value\":\"" + fibarodevice.fibaroAuth + "\"}]"; $scope.device = bridgeService.state.device; if (!buildonly) { @@ -2081,7 +2081,7 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n onpayload = "http://" + fibaroscene.fibaroaddress + ":" + fibaroscene.fibaroport + "/api/sceneControl?id=" + fibaroscene.id + "&action=start"; offpayload = "http://" + fibaroscene.fibaroaddress + ":" + fibaroscene.fibaroport + "/api/sceneControl?id=" + fibaroscene.id + "&action=stop"; - bridgeService.buildUrls(onpayload, null, offpayload, false, fibaroscene.id, fibaroscene.name, fibaroscene.fibaroname, "scene", "fibaroScene", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, false, fibaroscene.id, fibaroscene.name, fibaroscene.fibaroname, "scene", "fibaroScene", null, null); bridgeService.state.device.headers = "[{\"name\":\"Authorization\",\"value\":\"" + fibaroscene.fibaroAuth + "\"}]"; $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); diff --git a/src/main/resources/public/views/system.html b/src/main/resources/public/views/system.html index 8e08304..095814f 100644 --- a/src/main/resources/public/views/system.html +++ b/src/main/resources/public/views/system.html @@ -100,6 +100,12 @@ ng-model="bridge.settings.useupnpiface" ng-true-value=true ng-false-value=false> {{bridge.settings.useupnpiface}} + + Use Rooms for Alexa + {{bridge.settings.userooms}} + Web Server IP Address