From 55ed9ba4c2d499d5a1de98ff55ce6a61e9c22277 Mon Sep 17 00:00:00 2001 From: Ben Chadwick Date: Mon, 10 Dec 2018 11:03:53 -0500 Subject: [PATCH 01/52] initial HSL replacement code --- README.md | 2 ++ .../com/bwssystems/HABridge/hue/ColorDecode.java | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b6b491a..3c5596e 100644 --- a/README.md +++ b/README.md @@ -489,6 +489,8 @@ For the items that want to have a date time put into the message, utilize ${time Color has been added as a replacement control and the available values are ${color.r}, ${color.g}, ${color.b} which are representations of each color as 0 - 255. There are hex equivalents as well as ${color.rx}, ${color.gx}, ${color.bx} and ${color.rgbx} as 2 place hex representations except for rgbx which is a six place hex representation. +Color can also be replaced with ${color.hsl} which will output a string in the Hue/Saturation/Brightness comma-delineated format, useful for many devices under OpenHAB. The format will be a 0-360 hue value, a 0-100 saturation value, and a 0-100 brightness value, separated by commas. (Such devices usually accept either a full HSB value in that format, or a single ${intensity.percent} value for the dimming value, send as raw text in a POST request.) + Special handling for milights is included and is handled by ${color.milight:x}. The usage for that is as follows: udp://ip:port/0x${color.milight:x} where x is a number between 0 and 4 (0 all groups, 1-4 specific group). The group is necessary in case the color turns out to be white. The correct group on must of course be sent before that udp packet. Note that milight can only use 255 colors and white is handled completely separate for the rgbw strips, so setting temperature via ct with milight does something but not really the desired result diff --git a/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java index 86421de..2ff2f7a 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java +++ b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.awt.Color; import org.slf4j.Logger; @@ -20,6 +21,7 @@ public class ColorDecode { 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 String COLOR_HSL = "${color.hsl}"; private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}"); public static List convertCIEtoRGB(List xy, int brightness) { @@ -197,8 +199,18 @@ public class ColorDecode { 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; - } - + } + + if (request.contains(COLOR_HSL)) { + float[] hsb = new float[3]; + Color.RGBtoHSB(rgb.get(0),rgb.get(1),rgb.get(2),hsb); + float hue = hsb[0] * (float) 360.0; + float sat = hsb[1] * (float) 100.0; + float bright = hsb[2] * (float) 100.0; + request = request.replace(COLOR_HSL, String.format("%f,%f,%f", hue, sat, bright)); + notDone = true; + } + Matcher m = COLOR_MILIGHT.matcher(request); while (m.find()) { int group = Integer.parseInt(m.group(1)); From 56481f3f727db96635cb9d8c5c2caeeb07ac6e93 Mon Sep 17 00:00:00 2001 From: Ben Chadwick Date: Mon, 10 Dec 2018 11:08:53 -0500 Subject: [PATCH 02/52] indentation and typo correction --- README.md | 2 +- src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3c5596e..6de1d38 100644 --- a/README.md +++ b/README.md @@ -489,7 +489,7 @@ For the items that want to have a date time put into the message, utilize ${time Color has been added as a replacement control and the available values are ${color.r}, ${color.g}, ${color.b} which are representations of each color as 0 - 255. There are hex equivalents as well as ${color.rx}, ${color.gx}, ${color.bx} and ${color.rgbx} as 2 place hex representations except for rgbx which is a six place hex representation. -Color can also be replaced with ${color.hsl} which will output a string in the Hue/Saturation/Brightness comma-delineated format, useful for many devices under OpenHAB. The format will be a 0-360 hue value, a 0-100 saturation value, and a 0-100 brightness value, separated by commas. (Such devices usually accept either a full HSB value in that format, or a single ${intensity.percent} value for the dimming value, send as raw text in a POST request.) +Color can also be replaced with ${color.hsl} which will output a string in the Hue/Saturation/Brightness comma-delineated format, useful for many devices under OpenHAB. The format will be a 0-360 hue value, a 0-100 saturation value, and a 0-100 brightness value, separated by commas. (Such devices usually accept either a full HSB value in that format, or a single ${intensity.percent} value for the dimming value, sent as raw text in a POST request.) Special handling for milights is included and is handled by ${color.milight:x}. The usage for that is as follows: udp://ip:port/0x${color.milight:x} where x is a number between 0 and 4 (0 all groups, 1-4 specific group). The group is necessary in case the color turns out to be white. The correct group on must of course be sent before that udp packet. Note that milight can only use 255 colors and white is handled completely separate for the rgbw strips, so setting temperature via ct with milight does something but not really the desired result diff --git a/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java index 2ff2f7a..ad9a3af 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java +++ b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java @@ -209,7 +209,7 @@ public class ColorDecode { float bright = hsb[2] * (float) 100.0; request = request.replace(COLOR_HSL, String.format("%f,%f,%f", hue, sat, bright)); notDone = true; - } + } Matcher m = COLOR_MILIGHT.matcher(request); while (m.find()) { From 9a438abf79377ad2a910477f2792c69efd00234e Mon Sep 17 00:00:00 2001 From: gaudryc Date: Thu, 3 Jan 2019 18:20:42 +0100 Subject: [PATCH 03/52] Add /system/logout request to remove current authenticated user and invalidate his session. --- .../bwssystems/HABridge/SystemControl.java | 19 +++++++++++++ src/main/resources/public/scripts/app.js | 27 ++++++++++++------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/SystemControl.java b/src/main/java/com/bwssystems/HABridge/SystemControl.java index 0e609a6..ce2eb8f 100644 --- a/src/main/java/com/bwssystems/HABridge/SystemControl.java +++ b/src/main/java/com/bwssystems/HABridge/SystemControl.java @@ -243,6 +243,24 @@ public class SystemControl { return result; }, new JsonTransformer()); + // http://ip_address:port/system/logout CORS request + options(SYSTEM_CONTEXT + "/logout", (request, response) -> { + response.status(HttpStatus.SC_OK); + response.header("Access-Control-Allow-Origin", request.headers("Origin")); + response.header("Access-Control-Allow-Methods", "GET, POST, PUT"); + response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers")); + response.header("Content-Type", "text/html; charset=utf-8"); + return ""; + }); + // http://ip_address:port/system/logout invalidates user session + put(SYSTEM_CONTEXT + "/logout", (request, response) -> { + log.debug("logout...."); + bridgeSettings.getBridgeSecurity().removeAuthenticatedUser(request); + response.status(HttpStatus.SC_OK); + response.type("application/json"); + return ""; + }); + // http://ip_address:port/system/presslinkbutton CORS request options(SYSTEM_CONTEXT + "/presslinkbutton", (request, response) -> { response.status(HttpStatus.SC_OK); @@ -558,4 +576,5 @@ public class SystemControl { pingListener(); return "{\"control\":\"stopping\"}"; } + } \ No newline at end of file diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 910c5be..fc343a9 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -4813,15 +4813,24 @@ app.factory('Auth', function($resource, $rootScope, $sessionStorage, $http, $bas bridgeService.displayWarn("Login Error: ", error); }); }; - - - auth.logout = function() { - delete $sessionStorage.user; - delete $rootScope.user; - delete bridgeService.state.loggedInUser; - }; - - + + + auth.logout = function() { + delete $sessionStorage.user; + delete $rootScope.user; + delete bridgeService.state.loggedInUser; + // Logout on server side to destroy current session (fire and forget it) + $http.put(bridgeService.state.systemsbase + "/logout").then( + function (response) { + // nothing more to do + }, + function (error) { + bridgeService.displayWarn("Logout Error: ", error); + } + ); + }; + + auth.checkPermissionForView = function(view) { if (!view.requiresAuthentication) { return true; From ce220d999a5c06c4f9993d12a07f600b40ce7766 Mon Sep 17 00:00:00 2001 From: gaudryc Date: Thu, 3 Jan 2019 18:23:12 +0100 Subject: [PATCH 04/52] Invalidate authenticated user session. --- src/main/java/com/bwssystems/HABridge/BridgeSecurity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java b/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java index 6e883e5..4d0d623 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java @@ -355,7 +355,7 @@ public class BridgeSecurity { public void removeAuthenticatedUser(Request request) { request.session().removeAttribute(USER_SESSION_ID); - + request.session().invalidate(); } public User getAuthenticatedUser(Request request) { From 7490cf72a35e4fff1d22564770b1ebe50c16cb77 Mon Sep 17 00:00:00 2001 From: gaudryc Date: Thu, 3 Jan 2019 18:36:56 +0100 Subject: [PATCH 05/52] Add shutdown hook before starting web server to be able to stop HA-Bridge from the command line (using SIGTERM signal). --- .../com/bwssystems/HABridge/HABridge.java | 11 ++++- .../com/bwssystems/HABridge/ShutdownHook.java | 48 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/bwssystems/HABridge/ShutdownHook.java diff --git a/src/main/java/com/bwssystems/HABridge/HABridge.java b/src/main/java/com/bwssystems/HABridge/HABridge.java index 368cc2f..2e93760 100644 --- a/src/main/java/com/bwssystems/HABridge/HABridge.java +++ b/src/main/java/com/bwssystems/HABridge/HABridge.java @@ -44,7 +44,8 @@ public class HABridge { Version theVersion; @SuppressWarnings("unused") HttpClientPool thePool; - + ShutdownHook shutdownHook = null; + log.info("HA Bridge startup sequence..."); theVersion = new Version(); // Singleton initialization @@ -68,6 +69,14 @@ public class HABridge { // setup system control api first theSystem = new SystemControl(bridgeSettings, theVersion); theSystem.setupServer(); + + // Add shutdown hook to be able to properly stop server + if (shutdownHook != null) { + Runtime.getRuntime().removeShutdownHook(shutdownHook); + } + shutdownHook = new ShutdownHook(bridgeSettings, theSystem); + Runtime.getRuntime().addShutdownHook(shutdownHook); + // setup the UDP Datagram socket to be used by the HueMulator and the upnpListener udpSender = UDPDatagramSender.createUDPDatagramSender(bridgeSettings.getBridgeSettingsDescriptor().getUpnpResponsePort()); if(udpSender == null) { diff --git a/src/main/java/com/bwssystems/HABridge/ShutdownHook.java b/src/main/java/com/bwssystems/HABridge/ShutdownHook.java new file mode 100644 index 0000000..8310471 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/ShutdownHook.java @@ -0,0 +1,48 @@ +package com.bwssystems.HABridge; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class implements the shutdown hook used to properly stop server from the + * command line (sending SIGTERM), or while shutting down the host machine. + * + * @author gaudryc + */ +public class ShutdownHook extends Thread { + + private final BridgeSettings bridgeSettings; + private final SystemControl theSystem; + + /** + * Constructor + * + * @param bridgeSettings + * bridge settings + * @param theSystem + */ + public ShutdownHook(final BridgeSettings bridgeSettings, final SystemControl theSystem) { + this.bridgeSettings = bridgeSettings; + this.theSystem = theSystem; + } + + @Override + public void run() { + Logger log = LoggerFactory.getLogger(ShutdownHook.class); + log.info("Shutdown requested..."); + if (bridgeSettings != null) { + if (!bridgeSettings.getBridgeControl().isStop() && (theSystem != null)) { + log.info("Forcing system stop..."); + theSystem.stop(); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + log.error("Sleep error: " + e.getMessage()); + } + } else { + log.info("Already stopped"); + } + } + } + +} From 12823704f3b86a68d54c6726afc55f6b0a018dcd Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 16:21:07 +0100 Subject: [PATCH 06/52] Bug: Call to method of static java.text.DateFormat in com.bwssystems.HABridge.BridgeSettings.getCurrentDate(). As the JavaDoc states, DateFormats are inherently unsafe for multithreaded use. The detector has found a call to an instance of DateFormat that has been obtained via a static field. This looks suspicious. --- .../com/bwssystems/HABridge/BridgeSettings.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index eef0d7e..5544b7f 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -12,8 +12,8 @@ import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.nio.file.attribute.PosixFilePermission; import java.security.GeneralSecurityException; -import java.text.SimpleDateFormat; -import java.util.Date; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; @@ -31,7 +31,7 @@ public class BridgeSettings extends BackupHandler { private BridgeSettingsDescriptor theBridgeSettings; private BridgeControlDescriptor bridgeControl; private BridgeSecurity bridgeSecurity; - private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); + private static final DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss"); public BridgeSettings() { super(); @@ -58,10 +58,10 @@ public class BridgeSettings extends BackupHandler { public BridgeSecurity getBridgeSecurity() { return bridgeSecurity; } - public static String getCurrentDate() { - return dateFormat.format(new Date()); - } - + public String getCurrentDate() { + return LocalDateTime.now().format(dateTimeFormat); + } + public void buildSettings() { String addressString = null; String theVeraAddress = null; From f8349f12bc562e1f56182958d9fef812dc473f7a Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 18:39:37 +0100 Subject: [PATCH 07/52] Bug: Call to method of static java.text.DateFormat in com.bwssystems.HABridge.api.hue.WhitelistEntry.getCurrentDate() As the JavaDoc states, DateFormats are inherently unsafe for multithreaded use. The detector has found a call to an instance of DateFormat that has been obtained via a static field. This looks suspicious. --- .../bwssystems/HABridge/api/hue/WhitelistEntry.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/WhitelistEntry.java b/src/main/java/com/bwssystems/HABridge/api/hue/WhitelistEntry.java index ffd6801..48e1b8c 100644 --- a/src/main/java/com/bwssystems/HABridge/api/hue/WhitelistEntry.java +++ b/src/main/java/com/bwssystems/HABridge/api/hue/WhitelistEntry.java @@ -1,14 +1,14 @@ package com.bwssystems.HABridge.api.hue; -import java.text.SimpleDateFormat; -import java.util.Date; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; public class WhitelistEntry { private String lastUseDate; private String createDate; private String name; - private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + private static final DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); public static WhitelistEntry createEntry(String devicetype) { WhitelistEntry anEntry = new WhitelistEntry(); @@ -18,9 +18,9 @@ public class WhitelistEntry return anEntry; } - public static String getCurrentDate() { - return dateFormat.format(new Date()); - } + public static String getCurrentDate() { + return LocalDateTime.now().format(dateTimeFormat); + } public String getLastUseDate() { return lastUseDate; From d9916b766214af534a15b616df5d887514e91ed7 Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 19:18:27 +0100 Subject: [PATCH 08/52] Bug: Useless control flow to next line in com.bwssystems.HABridge.plugins.http.HttpTestHandler.updateTheData(String, String) This method contains a useless control flow statement in which control flow follows to the same or following line regardless of whether or not the branch is taken. Often, this is caused by inadvertently using an empty statement as the body of an if statement, e.g.: --- .../com/bwssystems/HABridge/plugins/http/HttpTestHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HttpTestHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HttpTestHandler.java index 10d7ceb..c54d3b0 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HttpTestHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HttpTestHandler.java @@ -32,7 +32,7 @@ public class HttpTestHandler extends HTTPHandler { } else { for(NameValue aTest:this.theData) { - if(aTest.getName().equals(compareValue)); + if(aTest.getName().equals(compareValue)) aTest.setValue(testData); } } From 92ab02145eae3047d5c414fdf8a8410b3048adbb Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 19:52:55 +0100 Subject: [PATCH 09/52] Bug: Non-transient non-serializable instance fields in serializable class com.bwssystems.logservices.LoggingForm --- src/main/java/com/bwssystems/logservices/LoggerInfo.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/bwssystems/logservices/LoggerInfo.java b/src/main/java/com/bwssystems/logservices/LoggerInfo.java index 8542546..4e2926c 100644 --- a/src/main/java/com/bwssystems/logservices/LoggerInfo.java +++ b/src/main/java/com/bwssystems/logservices/LoggerInfo.java @@ -1,5 +1,7 @@ package com.bwssystems.logservices; +import java.io.Serializable; + import com.bwssystems.logservices.LoggingUtil.LogLevels; /** @@ -7,7 +9,10 @@ import com.bwssystems.logservices.LoggingUtil.LogLevels; * * */ -public class LoggerInfo { +public class LoggerInfo implements Serializable { + + /** serialVersionUID. */ + private static final long serialVersionUID = 1085935297588739585L; private String loggerName; private LogLevels logLevel; From df04d542db8c99b14ec2efcc29bbffd28f640d82 Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 20:03:24 +0100 Subject: [PATCH 10/52] Bug: The method com.bwssystems.HABridge.plugins.hue.HueInfo.changeState(HueDeviceIdentifier, String, String) ignores the return value of String.contains(CharSequence) --- .../java/com/bwssystems/HABridge/plugins/hue/HueInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hue/HueInfo.java b/src/main/java/com/bwssystems/HABridge/plugins/hue/HueInfo.java index 590e5a2..7c858d2 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hue/HueInfo.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hue/HueInfo.java @@ -161,8 +161,8 @@ public class HueInfo { + "\",\"description\": \"Error on calling HUE to change device state\", \"parameter\": \"/lights/" + lightId + "state\"}}]"; } else if (responseString.contains("[{\"error\":")) { - if(responseString.contains("unauthorized user")) { - } +// if(responseString.contains("unauthorized user")) { +// } log.warn("Error occurred when calling Hue Passthru: " + responseString); } } else { From 07fa11b9ff443166627b23903294e0c7773885ee Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 20:07:10 +0100 Subject: [PATCH 11/52] Bug: com.bwssystems.HABridge.plugins.domoticz.DomoticzHome.addDomoticzDevices(List, List, String) has Boolean return type and returns explicit null --- .../com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java index a68aabc..1806b3c 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java @@ -73,7 +73,7 @@ public class DomoticzHome implements Home { private Boolean addDomoticzDevices(List theDeviceList, List theSourceList, String theKey) { if(!validDomoticz) - return null; + return false; Iterator devices = theSourceList.iterator(); while(devices.hasNext()) { DomoticzDevice theDevice = devices.next(); From f90f39e5f1222916387e0f39f3411daf15c1e79f Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 20:08:38 +0100 Subject: [PATCH 12/52] Bug: com.bwssystems.HABridge.plugins.hal.HalHome.addHalDevices(List, List, String) has Boolean return type and returns explicit null --- src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a18de76..3357e12 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java @@ -104,7 +104,7 @@ public class HalHome implements Home { private Boolean addHalDevices(List theDeviceList, List theSourceList, String theKey) { if(!validHal) - return null; + return false; Iterator devices = theSourceList.iterator(); while(devices.hasNext()) { HalDevice theDevice = devices.next(); From 9cbc2907682348db0c9d102c57a992a4c1f5fafa Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 20:09:49 +0100 Subject: [PATCH 13/52] Bug: com.bwssystems.HABridge.plugins.hass.HassHome.addHassDevices(List, List, String) has Boolean return type and returns explicit null --- .../java/com/bwssystems/HABridge/plugins/hass/HassHome.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java b/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java index 6de7f8d..e7208e7 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java @@ -98,7 +98,7 @@ public class HassHome implements Home { private Boolean addHassDevices(List theDeviceList, List theSourceList, String theKey) { if(!validHass) - return null; + return false; Iterator devices = theSourceList.iterator(); while(devices.hasNext()) { State theDevice = devices.next(); From 1311d4a68df75cc10502dcc14bf26638d40126f4 Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 21:43:39 +0100 Subject: [PATCH 14/52] Bug: Possible null pointer dereference in method com.bwssystems.HABridge.plugins.broadlink.BroadlinkHome.deviceHandler(CallItem, MultiCommandUtil, String, int, Integer, Integer, ColorData, DeviceDescriptor, String) on exception path --- .../HABridge/plugins/broadlink/BroadlinkHome.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java index 8ef6fc3..0499e91 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java @@ -143,9 +143,12 @@ public class BroadlinkHome implements Home { if(broadlinkMap == null) broadlinkMap = new HashMap(); - String newId = theDevice.getHost() + "-" + String.format("%04x", theDevice.getDeviceType()); - if(broadlinkMap.get(newId) == null) - broadlinkMap.put(newId, theDevice); + if (theDevice != null) { + String newId = theDevice.getHost() + "-" + String.format("%04x", theDevice.getDeviceType()); + if (broadlinkMap.get(newId) == null) { + broadlinkMap.put(newId, theDevice); + } + } } } if (theDevice == null) { From 14c36148567d524cc3b97ff21bfbee85408386e4 Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 21:54:23 +0100 Subject: [PATCH 15/52] Bug: Possible null pointer dereference in com.bwssystems.HABridge.hue.HueMulator.callUrl(String, DeviceDescriptor, String, String, String, String, boolean, Integer, Integer, ColorData) --- src/main/java/com/bwssystems/HABridge/hue/HueMulator.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 4034578..f8b9ab9 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -1471,10 +1471,11 @@ public class HueMulator { else log.warn("Call Items type is null <<<" + callItems[i] + ">>>"); } - - if(callItems.length == 0) + + if ((callItems == null) || (callItems.length == 0)) { log.warn("No call items were available: <<<" + url + ">>>"); - + } + return responseString; } } From e1b5aede662659288068b44798700072d03d7c14 Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 21:58:01 +0100 Subject: [PATCH 16/52] Bug: Possible null pointer dereference in com.bwssystems.HABridge.hue.HueMulator.formatSuccessHueResponse(StateChangeBody, String, String, DeviceState, Integer, Integer, ColorData, boolean) --- src/main/java/com/bwssystems/HABridge/hue/HueMulator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index f8b9ab9..4e3cf50 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -597,10 +597,10 @@ public class HueMulator { notFirstChange = true; } - if(deviceState.isOn() && deviceState.getBri() <= 0) + if((deviceState != null) && deviceState.isOn() && deviceState.getBri() <= 0) deviceState.setBri(254); - if(!deviceState.isOn() && (targetBri != null || targetBriInc != null)) + if((deviceState != null) && !deviceState.isOn() && (targetBri != null || targetBriInc != null)) deviceState.setOn(true); responseString = responseString + "]"; From 3971c8144907482f1e835b599e57392d49e983e8 Mon Sep 17 00:00:00 2001 From: gaudryc Date: Sun, 6 Jan 2019 22:01:39 +0100 Subject: [PATCH 17/52] Bug: Comparison of String objects using == or != in com.bwssystems.HABridge.plugins.http.HTTPHandler.doHttpRequest(String, String, String, String, NameValue[]) --- .../java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java index a35a33b..b41bf51 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java @@ -115,7 +115,7 @@ public class HTTPHandler { theContent = ""; log.debug("Successfull response - The http response is <<<" + theContent + ">>>"); retryCount = 2; - } else if (callType != null && callType == DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex] && response.getStatusLine().getStatusCode() == 302) { + } else if (DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex].equals(callType) && response.getStatusLine().getStatusCode() == 302) { if(theContent == null) theContent = ""; log.debug("Successfull response - The http response is <<<" + theContent + ">>>"); From 45e2b63f981caa2303b00e32ef8027e08fdf2619 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Tue, 21 May 2019 16:44:38 -0500 Subject: [PATCH 18/52] Updating color handling --- README.md | 17 +- pom.xml | 255 +++++++------ .../HABridge/dao/DeviceRepository.java | 6 +- .../bwssystems/HABridge/hue/ColorDecode.java | 347 +++++++++++------- .../bwssystems/HABridge/hue/HueMulator.java | 8 +- 5 files changed, 370 insertions(+), 263 deletions(-) diff --git a/README.md b/README.md index 5eee244..e9301de 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,6 @@ This bridge was built to help put the Internet of Things together. ## Build To customize and build it yourself, build a new jar with maven: -ATTENTION: This requires JDK 1.8 to build - ``` mvn install ``` @@ -58,30 +56,23 @@ Otherwise, downloads are available at https://github.com/bwssytems/ha-bridge/rel ## Run Then locate the jar and start the server with: -ATTENTION: This requires JDK 1.8 to run - ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below. ``` -java -jar ha-bridge-5.2.2.jar -``` - -ATTENTION: If running Java9, you will need to add the xml bind module -``` -java -jar --add-modules java.xml.bind ha-bridge-5.2.2.jar +java -jar ha-bridge-5.3.0.jar ``` ## Manual installation of ha-bridge and setup of systemd service Next gen Linux systems (this includes the Raspberry Pi), use systemd to run and manage services. Here is a link on how to use systemd: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units -Create the directory and make sure that ha-bridge-5.2.2.jar is in your /home/pi/ha-bridge directory. +Create the directory and make sure that ha-bridge-5.3.0.jar is in your /home/pi/ha-bridge directory. ``` pi@raspberrypi:~ $ mkdir ha-bridge pi@raspberrypi:~ $ cd ha-bridge -pi@raspberrypi:~/ha-bridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v5.2.2/ha-bridge-5.2.2.jar +pi@raspberrypi:~/ha-bridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v5.3.0/ha-bridge-5.3.0.jar ``` Create the ha-bridge.service unit file: @@ -100,7 +91,7 @@ After=network.target Type=simple WorkingDirectory=/home/pi/ha-bridge -ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/ha-bridge/data/habridge.config /home/pi/ha-bridge/ha-bridge-5.2.2.jar +ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/ha-bridge/data/habridge.config /home/pi/ha-bridge/ha-bridge-5.3.0.jar [Install] WantedBy=multi-user.target diff --git a/pom.xml b/pom.xml index 50e8f8f..f63ebbf 100644 --- a/pom.xml +++ b/pom.xml @@ -1,105 +1,102 @@ - + 4.0.0 com.bwssystems.HABridge ha-bridge - 5.2.2 + 5.2.next_a jar HA Bridge Emulates a Philips Hue bridge to allow the Amazon Echo to hook up to other HA systems, i.e. Vera or Harmony Hub or Nest, using lightweight frameworks - 1.8 - 1.8 - 1.8 - UTF-8 + UTF-8 - jitpack.io - https://jitpack.io + jitpack.io + https://jitpack.io + + + Eclipse Paho Repo + https://repo.eclipse.org/content/repositories/paho-releases/ - - Eclipse Paho Repo - https://repo.eclipse.org/content/repositories/paho-releases/ - - com.github.bwssytems - harmony-java-client - master-SNAPSHOT - - - org.slf4j - slf4j-simple - - - org.slf4j - log4j-over-slf4j - - + com.github.bwssytems + harmony-java-client + master-SNAPSHOT + + + org.slf4j + slf4j-simple + + + org.slf4j + log4j-over-slf4j + + - - com.github.bwssytems - nest-controller - 1.0.14 - - - org.slf4j - slf4j-simple - - - org.slf4j - log4j-over-slf4j - - - - com.sparkjava - spark-core - 2.7.2 - - - slf4j-simple - org.slf4j - - + com.github.bwssytems + nest-controller + 1.0.14 + + + org.slf4j + slf4j-simple + + + org.slf4j + log4j-over-slf4j + + + + + com.sparkjava + spark-core + 2.7.2 + + + slf4j-simple + org.slf4j + + org.apache.httpcomponents httpclient 4.5.1 - - org.apache.httpcomponents - httpcore - 4.4.4 - - - org.slf4j - slf4j-api - 1.7.24 - + + org.apache.httpcomponents + httpcore + 4.4.4 + + + org.slf4j + slf4j-api + 1.7.24 + ch.qos.logback logback-classic 1.2.1 - - com.google.code.gson - gson - 2.6.2 - - net.java.dev.eval - eval - 0.5 + com.google.code.gson + gson + 2.6.2 + + + net.java.dev.eval + eval + 0.5 com.google.inject @@ -107,68 +104,95 @@ 4.1.0 - org.igniterealtime.smack - smack-core - 4.2.0 - - - org.eclipse.paho - org.eclipse.paho.client.mqttv3 - 1.2.0 - - - junit - junit - 4.12 - test + org.igniterealtime.smack + smack-core + 4.2.0 - com.github.bwssytems - lifx-sdk-java - 2.1.6 + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + 1.2.0 - com.github.mob41 - broadlink-java-api - master-SNAPSHOT + junit + junit + 4.12 + test - org.apache.commons - commons-lang3 - 3.5 + com.github.bwssytems + lifx-sdk-java + 2.1.6 + + + com.github.mob41 + broadlink-java-api + master-SNAPSHOT + + + org.apache.commons + commons-lang3 + 3.5 - - - src/main/resources - - version.properties - - true - - - src/main/resources - - version.properties - - false - - + + + src/main/resources + + version.properties + + true + + + src/main/resources + + version.properties + + false + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M2 + + + enforce-maven + + enforce + + + + + 3.6 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 11 + + - org.apache.maven.plugins - maven-surefire-plugin - 2.22.1 - - true - + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M3 + + true + org.apache.maven.plugins maven-shade-plugin - 2.4.3 + 3.2.1 package @@ -230,8 +254,7 @@ - + com.bwssystems.HABridge.HABridge diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java index b8b5651..aafc0df 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java @@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory; import com.bwssystems.HABridge.DeviceMapTypes; import com.bwssystems.HABridge.api.CallItem; import com.bwssystems.HABridge.api.hue.DeviceResponse; +import com.bwssystems.HABridge.api.hue.DeviceState; import com.bwssystems.HABridge.dao.DeviceDescriptor; import com.bwssystems.HABridge.plugins.hue.HueHome; import com.bwssystems.HABridge.util.BackupHandler; @@ -67,7 +68,10 @@ public class DeviceRepository extends BackupHandler { { DeviceDescriptor list[] = gson.fromJson(jsonContent, DeviceDescriptor[].class); for(int i = 0; i < list.length; i++) { - list[i].setDeviceState(null); + if(list[i].getColorUrl() == null || list[i].getColorUrl().isEmpty()) + list[i].setDeviceState(DeviceState.createDeviceState(false)); + else + list[i].setDeviceState(DeviceState.createDeviceState(true)); 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/ColorDecode.java b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java index ad9a3af..89b97f9 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java +++ b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java @@ -4,8 +4,7 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.awt.Color; - +import java.awt.Color; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,91 +23,174 @@ public class ColorDecode { private static final String COLOR_HSL = "${color.hsl}"; private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}"); + public static List convertHSLtoRGB(int hue, int sat, int brightness) { + List rgb; + float decimalBrightness = (float) 0.0; + float var_1 = (float) 0.0; + float var_2 = (float) 0.0; + float h = (float) 0.0; + float h2 = (float) 0.0; + float s = (float) 0.0; + double r = 0.0; + double g = 0.0; + double b = 0.0; + + if(brightness > 0) + decimalBrightness = (float) (brightness / 255.0); + + if(hue > 0) { + h = (float)(hue / 65535.0); + h2 = h + (float)0.5; + if(h2 > 1) { + h2 = h2 * (float) -1.0; + } + } + if(sat > 0) { + s = (float)(sat / 254.0); + } + + if (s == 0) + { + r = decimalBrightness * 255; + g = decimalBrightness * 255; + b = decimalBrightness * 255; + } + else + { + if (decimalBrightness < 0.5) + { + var_2 = decimalBrightness * (1 + s); + } + else + { + var_2 = (decimalBrightness + s) - (s * decimalBrightness); + }; + + var_1 = 2 * decimalBrightness - var_2; + r = 255 * hue_2_rgb(var_1,var_2,h2 + (1 / 3)); + g = 255 * hue_2_rgb(var_1,var_2,h2); + b = 255 * hue_2_rgb(var_1,var_2,h2 - (1 / 3)); + }; + + rgb = new ArrayList(); + rgb.add((int) Math.round(r * 255)); + rgb.add((int) Math.round(g * 255)); + rgb.add((int) Math.round(b * 255)); + + return rgb; + } + + public static float hue_2_rgb(float v1, float v2, float vh) { + if (vh < 0) + { + vh += 1; + }; + + if (vh > 1) + { + vh -= 1; + }; + + if ((6 * vh) < 1) + { + return (v1 + (v2 - v1) * 6 * vh); + }; + + if ((2 * vh) < 1) + { + return (v2); + }; + + if ((3 * vh) < 2) + { + return (v1 + (v2 - v1) * ((2 / 3 - vh) * 6)); + }; + + return (v1); + } + public static List convertCIEtoRGB(List xy, int brightness) { List rgb; double x = xy.get(0); // the given x value double y = xy.get(1); // the given y value double z = 1.0 - x - y; - double Y = (double)brightness/(double)254.00; // The given brightness value + double Y = (double) brightness / (double) 254.00; // The given brightness value double X = (Y / y) * x; double Z = (Y / y) * z; - double r = X * 1.656492 - Y * 0.354851 - Z * 0.255038; + double r = X * 1.656492 - Y * 0.354851 - Z * 0.255038; double g = -X * 0.707196 + Y * 1.655397 + Z * 0.036152; - double b = X * 0.051713 - Y * 0.121364 + Z * 1.011530; + double b = X * 0.051713 - Y * 0.121364 + Z * 1.011530; if (r > b && r > g && r > 1.0) { g = g / r; b = b / r; r = 1.0; - } - else if (g > b && g > r && g > 1.0) { + } else if (g > b && g > r && g > 1.0) { r = r / g; b = b / g; g = 1.0; - } - else if (b > r && b > g && b > 1.0) { + } else if (b > r && b > g && b > 1.0) { r = r / b; g = g / b; b = 1.0; } - r = r <= 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math.pow(r, (1.0 / 2.4)) - 0.055; g = g <= 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math.pow(g, (1.0 / 2.4)) - 0.055; b = b <= 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math.pow(b, (1.0 / 2.4)) - 0.055; - - if (r > b && r > g) { - // red is biggest - if (r > 1.0) { - g = g / r; - b = b / r; - r = 1.0; - } - } - else if (g > b && g > r) { - // green is biggest - if (g > 1.0) { - r = r / g; - b = b / g; - g = 1.0; - } - } - else if (b > r && b > g) { - // blue is biggest - if (b > 1.0) { - r = r / b; - g = g / b; - b = 1.0; - } - } - if(r < 0.0) - r = 0; - if(g < 0.0) - g = 0; - if(b < 0.0) - b = 0; - rgb = new ArrayList(); - rgb.add((int)Math.round(r * 255)); - rgb.add((int)Math.round(g * 255)); - rgb.add((int)Math.round(b * 255)); - log.debug("Color change with XY: " + x + " " + y + " Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2)); + if (r > b && r > g) { + // red is biggest + if (r > 1.0) { + g = g / r; + b = b / r; + r = 1.0; + } + } else if (g > b && g > r) { + // green is biggest + if (g > 1.0) { + r = r / g; + b = b / g; + g = 1.0; + } + } else if (b > r && b > g) { + // blue is biggest + if (b > 1.0) { + r = r / b; + g = g / b; + b = 1.0; + } + } + if (r < 0.0) + r = 0; + if (g < 0.0) + g = 0; + if (b < 0.0) + b = 0; + + rgb = new ArrayList(); + rgb.add((int) Math.round(r * 255)); + rgb.add((int) Math.round(g * 255)); + rgb.add((int) Math.round(b * 255)); + log.debug("Color change with XY: " + x + " " + y + " Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + + " " + rgb.get(2)); return rgb; } - // took that approximation from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ + // took that approximation from + // http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ public static List convertCTtoRGB(Integer ct) { - double temperature = 1000000.0 / (double)ct; + double temperature = 1000000.0 / (double) ct; temperature /= 100; - double r,g,b; + double r, g, b; if (temperature <= 66) { r = 255; g = temperature; - g = 99.4708025861 * Math.log(g) - 161.1195681661; + g = 99.4708025861 * Math.log(g) - 161.1195681661; } else { r = temperature - 60; r = 329.698727446 * (Math.pow(r, -0.1332047592)); @@ -126,25 +208,26 @@ public class ColorDecode { b = 138.5177312231 * Math.log(b) - 305.0447927307; } } - r = assureBounds(r); - g = assureBounds(g); - b = assureBounds(b); - List rgb = new ArrayList(); - rgb.add((int)Math.round(r)); - rgb.add((int)Math.round(g)); - rgb.add((int)Math.round(b)); - log.debug("Color change with CT: " + ct + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2)); - return rgb; + r = assureBounds(r); + g = assureBounds(g); + b = assureBounds(b); + List rgb = new ArrayList(); + rgb.add((int) Math.round(r)); + rgb.add((int) Math.round(g)); + rgb.add((int) Math.round(b)); + log.debug("Color change with CT: " + ct + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + + rgb.get(2)); + return rgb; } private static double assureBounds(double value) { if (value < 0.0) { - value = 0; - } - if (value > 255.0) { - value = 255; - } - return value; + value = 0; + } + if (value > 255.0) { + value = 255; + } + return value; } @SuppressWarnings("unchecked") @@ -159,25 +242,28 @@ public class ColorDecode { ColorData.ColorMode colorMode = colorData.getColorMode(); List rgb = null; if (colorMode == ColorData.ColorMode.XY) { - rgb = convertCIEtoRGB((List)colorData.getData(), setIntensity); + rgb = convertCIEtoRGB((List) colorData.getData(), setIntensity); } else if (colorMode == ColorData.ColorMode.CT) { - rgb = convertCTtoRGB((Integer)colorData.getData()); + rgb = convertCTtoRGB((Integer) colorData.getData()); } - - while(notDone) { + + while (notDone) { notDone = false; if (request.contains(COLOR_R)) { - request = request.replace(COLOR_R, isHex ? String.format("%02X", rgb.get(0)) : String.valueOf(rgb.get(0))); + request = request.replace(COLOR_R, + isHex ? String.format("%02X", rgb.get(0)) : String.valueOf(rgb.get(0))); notDone = true; } if (request.contains(COLOR_G)) { - request = request.replace(COLOR_G, isHex ? String.format("%02X", rgb.get(1)) : String.valueOf(rgb.get(1))); + request = request.replace(COLOR_G, + isHex ? String.format("%02X", rgb.get(1)) : String.valueOf(rgb.get(1))); notDone = true; } if (request.contains(COLOR_B)) { - request = request.replace(COLOR_B, isHex ? String.format("%02X", rgb.get(2)) : String.valueOf(rgb.get(2))); + request = request.replace(COLOR_B, + isHex ? String.format("%02X", rgb.get(2)) : String.valueOf(rgb.get(2))); notDone = true; } @@ -197,75 +283,78 @@ public class ColorDecode { } if (request.contains(COLOR_RGBX)) { - request = request.replace(COLOR_RGBX, String.format("%02X%02X%02X", rgb.get(0), rgb.get(1), rgb.get(2))); + request = request.replace(COLOR_RGBX, + String.format("%02X%02X%02X", rgb.get(0), rgb.get(1), rgb.get(2))); notDone = true; - } - - if (request.contains(COLOR_HSL)) { - float[] hsb = new float[3]; - Color.RGBtoHSB(rgb.get(0),rgb.get(1),rgb.get(2),hsb); - float hue = hsb[0] * (float) 360.0; - float sat = hsb[1] * (float) 100.0; - float bright = hsb[2] * (float) 100.0; - request = request.replace(COLOR_HSL, String.format("%f,%f,%f", hue, sat, bright)); + } + + if (request.contains(COLOR_HSL)) { + float[] hsb = new float[3]; + Color.RGBtoHSB(rgb.get(0), rgb.get(1), rgb.get(2), hsb); + float hue = hsb[0] * (float) 360.0; + float sat = hsb[1] * (float) 100.0; + float bright = hsb[2] * (float) 100.0; + request = request.replace(COLOR_HSL, String.format("%f,%f,%f", hue, sat, bright)); notDone = true; - } - + } + Matcher m = COLOR_MILIGHT.matcher(request); while (m.find()) { - int group = Integer.parseInt(m.group(1)); - request = m.replaceFirst(getMilightV5FromRgb(rgb, group)); - m.reset(request); + int group = Integer.parseInt(m.group(1)); + request = m.replaceFirst(getMilightV5FromRgb(rgb, group)); + m.reset(request); } - + log.debug("Request <<" + request + ">>, not done: " + notDone); } return request; } private static String getMilightV5FromRgb(List rgb, int group) { - double r = (double)rgb.get(0); - double g = (double)rgb.get(1); - double b = (double)rgb.get(2); - if (r > 245 && g > 245 && b > 245) { // it's white - String retVal = ""; - if (group == 0) { - retVal += "C2"; - } else if (group == 1) { - retVal += "C5"; - } else if (group == 2) { - retVal += "C7"; - } else if (group == 3) { - retVal += "C9"; - } else if (group == 4) { - retVal += "CB"; - } - log.debug("Convert RGB to Milight. Result: WHITE. RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2)); - return retVal + "0055"; - } else { // normal color - r /= (double)0xFF; - g /= (double)0xFF; - b /= (double)0xFF; - double max = Math.max(Math.max(r, g), b), min = Math.min(Math.min(r, g), b); - double h = 0; - double d = max - min; + double r = (double) rgb.get(0); + double g = (double) rgb.get(1); + double b = (double) rgb.get(2); + if (r > 245 && g > 245 && b > 245) { // it's white + String retVal = ""; + if (group == 0) { + retVal += "C2"; + } else if (group == 1) { + retVal += "C5"; + } else if (group == 2) { + retVal += "C7"; + } else if (group == 3) { + retVal += "C9"; + } else if (group == 4) { + retVal += "CB"; + } + log.debug("Convert RGB to Milight. Result: WHITE. RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + + rgb.get(2)); + return retVal + "0055"; + } else { // normal color + r /= (double) 0xFF; + g /= (double) 0xFF; + b /= (double) 0xFF; + double max = Math.max(Math.max(r, g), b), min = Math.min(Math.min(r, g), b); + double h = 0; + double d = max - min; - if (max == min) { - h = 0; - } else { - if (max == r) { - h = ((g - b) / d + (g < b ? 6 : 0)); - } else if (max == g) { - h = ((b - r) / d + 2); - } else if (max == b){ - h = ((r - g) / d + 4); - } - h = Math.round(h * 60); - } - int milight = (int)((256 + 176 - Math.floor(h / 360.0 * 255.0)) % 256); - log.debug("Convert RGB to Milight. Result: " + milight + " RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2)); - return "40" + String.format("%02X", milight) + "55"; - } + if (max == min) { + h = 0; + } else { + if (max == r) { + h = ((g - b) / d + (g < b ? 6 : 0)); + } else if (max == g) { + h = ((b - r) / d + 2); + } else if (max == b) { + h = ((r - g) / d + 4); + } + h = Math.round(h * 60); + } + int milight = (int) ((256 + 176 - Math.floor(h / 360.0 * 255.0)) % 256); + log.debug("Convert RGB to Milight. Result: " + milight + " RGB Values: " + rgb.get(0) + " " + rgb.get(1) + + " " + rgb.get(2)); + return "40" + String.format("%02X", milight) + "55"; + } } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 75c5302..80174b1 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -600,8 +600,8 @@ public class HueMulator { if((deviceState != null) && deviceState.isOn() && deviceState.getBri() <= 0) deviceState.setBri(254); - if((deviceState != null) && !deviceState.isOn() && (targetBri != null || targetBriInc != null)) - deviceState.setOn(true); +// if((deviceState != null) && !deviceState.isOn() && (targetBri != null || targetBriInc != null)) +// deviceState.setOn(true); responseString = responseString + "]"; @@ -1186,11 +1186,11 @@ public class HueMulator { isOnRequest = true; } - if(!device.isOnFirstDim() && device.isOnWhenDimPresent() && isDimRequest) { + if(!device.isOnFirstDim() && device.isOnWhenDimPresent() && isDimRequest && !isOnRequest) { isOnRequest = true; theStateChanges.setOn(true); } else if(!device.isOnFirstDim() && !device.isOnWhenDimPresent() && isDimRequest) { - isOnRequest = false; + // isOnRequest = false; } if(device.isOnFirstDim() && isDimRequest && !device.getDeviceState().isOn()) { From 79d5b5da286768a5874b83b1ee2e58aaa994aa19 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Wed, 22 May 2019 15:30:50 -0500 Subject: [PATCH 19/52] Fixed color handling, starter Mozilla IOT integration --- .../bwssystems/HABridge/BridgeSettings.java | 1 + .../HABridge/BridgeSettingsDescriptor.java | 282 +++++-- .../bwssystems/HABridge/hue/ColorData.java | 6 + .../bwssystems/HABridge/hue/ColorDecode.java | 65 +- .../bwssystems/HABridge/hue/HueMulator.java | 727 +++++++++++------- .../bwssystems/HABridge/hue/HueSatBri.java | 38 + src/main/resources/public/views/system.html | 74 ++ 7 files changed, 828 insertions(+), 365 deletions(-) create mode 100644 src/main/java/com/bwssystems/HABridge/hue/HueSatBri.java diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index 1b03df7..40396c5 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -216,6 +216,7 @@ public class BridgeSettings extends BackupHandler { theBridgeSettings.setHomeWizardConfigured(theBridgeSettings.isValidHomeWizard()); theBridgeSettings.setOpenhabconfigured(theBridgeSettings.isValidOpenhab()); theBridgeSettings.setFhemconfigured(theBridgeSettings.isValidFhem()); + theBridgeSettings.setMoziotconfigured(theBridgeSettings.isValidMozIot()); // Lifx is either configured or not, so it does not need an update. if(serverPortOverride != null) theBridgeSettings.setServerPort(serverPortOverride); diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java index 57f6ac9..a72edb7 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java @@ -90,6 +90,9 @@ public class BridgeSettingsDescriptor { @SerializedName("openhabaddress") @Expose private IpList openhabaddress; + @SerializedName("moziotgateway") + @Expose + private IpList moziotgateway; @SerializedName("hubversion") @Expose private String hubversion; @@ -114,10 +117,13 @@ public class BridgeSettingsDescriptor { @SerializedName("broadlinkconfigured") @Expose private boolean broadlinkconfigured; -// @SerializedName("activeloggers") -// @Expose -// private List activeloggers; - + @SerializedName("tracestate") + @Expose + private boolean tracestate; + // @SerializedName("activeloggers") + // @Expose + // private List activeloggers; + private boolean settingsChanged; private boolean veraconfigured; private boolean fibaroconfigured; @@ -132,11 +138,12 @@ public class BridgeSettingsDescriptor { private boolean homewizardconfigured; private boolean openhabconfigured; private boolean fhemconfigured; - + private boolean moziotconfigured; + // Deprecated settings private String haltoken; private boolean upnpstrict; - + public BridgeSettingsDescriptor() { super(); this.upnpstrict = true; @@ -156,6 +163,7 @@ public class BridgeSettingsDescriptor { this.homewizardconfigured = false; this.lifxconfigured = false; this.openhabconfigured = false; + this.moziotconfigured = false; this.farenheit = true; this.securityData = null; this.settingsChanged = false; @@ -163,456 +171,612 @@ public class BridgeSettingsDescriptor { this.webaddress = "0.0.0.0"; this.hubversion = HueConstants.HUB_VERSION; this.hubmac = null; -// this.activeloggers = null; + // this.activeloggers = null; this.upnpsenddelay = Configuration.UPNP_SEND_DELAY; this.broadlinkconfigured = false; + this.tracestate = false; } + public String getUpnpConfigAddress() { return upnpconfigaddress; } + public void setUpnpConfigAddress(String upnpConfigAddress) { this.upnpconfigaddress = upnpConfigAddress; } + public boolean isUseupnpiface() { return useupnpiface; } + public void setUseupnpiface(boolean useupnpiface) { this.useupnpiface = useupnpiface; } + public boolean isUserooms() { return userooms; } + public void setUserooms(boolean userooms) { this.userooms = userooms; } - public Integer getServerPort() { + + public Integer getServerPort() { return serverport; } + public void setServerPort(Integer serverPort) { this.serverport = serverPort; } + public void setServerPort(String serverPort) { this.serverport = Integer.valueOf(serverPort); } + public Integer getUpnpResponsePort() { return upnpresponseport; } + public void setUpnpResponsePort(Integer upnpResponsePort) { this.upnpresponseport = upnpResponsePort; } + public void setUpnpResponsePort(String upnpResponsePort) { this.upnpresponseport = Integer.valueOf(upnpResponsePort); } + public String getUpnpDeviceDb() { return upnpdevicedb; } + public void setUpnpDeviceDb(String upnpDeviceDb) { this.upnpdevicedb = upnpDeviceDb; } + public String getUpnpGroupDb() { return upnpgroupdb; } + public void setUpnpGroupDb(String upnpGroupDb) { this.upnpgroupdb = upnpGroupDb; } + public IpList getVeraAddress() { return veraaddress; } + public IpList getFibaroAddress() { return fibaroaddress; } + public IpList getSomfyAddress() { return somfyaddress; } + public IpList getHomeWizardAddress() { return homewizardaddress; - } + } + public void setVeraAddress(IpList veraAddress) { this.veraaddress = veraAddress; } + public void setFibaroAddress(IpList fibaroAddress) { this.fibaroaddress = fibaroAddress; } + public void setSomfyAddress(IpList somfyAddress) { this.somfyaddress = somfyAddress; } + public void setHomeWizardAddress(IpList homewizardaddress) { this.homewizardaddress = homewizardaddress; } + public IpList getHarmonyAddress() { return harmonyaddress; } + public void setHarmonyAddress(IpList harmonyaddress) { this.harmonyaddress = harmonyaddress; } + public boolean isUpnpStrict() { return upnpstrict; } + public void setUpnpStrict(boolean upnpStrict) { this.upnpstrict = upnpStrict; } + public boolean isTraceupnp() { return traceupnp; } + public void setTraceupnp(boolean traceupnp) { this.traceupnp = traceupnp; } + public String getNestuser() { return nestuser; } + public void setNestuser(String nestuser) { this.nestuser = nestuser; } + public String getNestpwd() { return nestpwd; } + public void setNestpwd(String nestpwd) { this.nestpwd = nestpwd; } + public boolean isVeraconfigured() { return veraconfigured; } + public boolean isFibaroconfigured() { return fibaroconfigured; } + public boolean isSomfyconfigured() { return somfyconfigured; } + public boolean isHomeWizardConfigured() { return homewizardconfigured; - } + } + public void setVeraconfigured(boolean veraconfigured) { this.veraconfigured = veraconfigured; } + public void setFibaroconfigured(boolean fibaroconfigured) { this.fibaroconfigured = fibaroconfigured; } + public void setSomfyconfigured(boolean somfyconfigured) { this.somfyconfigured = somfyconfigured; } + public void setHomeWizardConfigured(boolean homewizardconfigured) { this.homewizardconfigured = homewizardconfigured; } + public boolean isHarmonyconfigured() { return harmonyconfigured; } + public void setHarmonyconfigured(boolean harmonyconfigured) { this.harmonyconfigured = harmonyconfigured; } + public boolean isNestConfigured() { return nestconfigured; } + public void setNestConfigured(boolean isNestConfigured) { this.nestconfigured = isNestConfigured; } + public Integer getButtonsleep() { return buttonsleep; } + public void setButtonsleep(Integer buttonsleep) { this.buttonsleep = buttonsleep; } + public String getConfigfile() { return configfile; } + public void setConfigfile(String configfile) { this.configfile = configfile; } + public Integer getNumberoflogmessages() { return numberoflogmessages; } + public void setNumberoflogmessages(Integer numberoflogmessages) { this.numberoflogmessages = numberoflogmessages; } + public boolean isFarenheit() { return farenheit; } + public void setFarenheit(boolean farenheit) { this.farenheit = farenheit; } + public IpList getHueaddress() { return hueaddress; } + public void setHueaddress(IpList hueaddress) { this.hueaddress = hueaddress; } + public boolean isHueconfigured() { return hueconfigured; } + public void setHueconfigured(boolean hueconfigured) { this.hueconfigured = hueconfigured; } + public IpList getHaladdress() { return haladdress; } + public void setHaladdress(IpList haladdress) { this.haladdress = haladdress; } + public String getHaltoken() { return haltoken; } + public void setHaltoken(String haltoken) { this.haltoken = haltoken; } + public boolean isHalconfigured() { return halconfigured; } + public void setHalconfigured(boolean halconfigured) { this.halconfigured = halconfigured; } + public Map getWhitelist() { return whitelist; } + protected void removeWhitelist() { whitelist = null; } + public boolean isSettingsChanged() { return settingsChanged; } + public void setSettingsChanged(boolean settingsChanged) { this.settingsChanged = settingsChanged; } + public String getMyechourl() { return myechourl; } + public void setMyechourl(String myechourl) { this.myechourl = myechourl; } + public String getWebaddress() { return webaddress; } + public void setWebaddress(String webaddress) { this.webaddress = webaddress; } + public IpList getMqttaddress() { return mqttaddress; } + public void setMqttaddress(IpList mqttaddress) { this.mqttaddress = mqttaddress; } + public boolean isMqttconfigured() { return mqttconfigured; } + public void setMqttconfigured(boolean mqttconfigured) { this.mqttconfigured = mqttconfigured; } + public IpList getHassaddress() { return hassaddress; } + public void setHassaddress(IpList hassaddress) { this.hassaddress = hassaddress; } + public boolean isHassconfigured() { return hassconfigured; } + public void setHassconfigured(boolean hassconfigured) { this.hassconfigured = hassconfigured; } + public IpList getOpenhabaddress() { return openhabaddress; } + public void setOpenhabaddress(IpList openhabaddress) { this.openhabaddress = openhabaddress; } + public boolean isOpenhabconfigured() { return openhabconfigured; } + public void setOpenhabconfigured(boolean openhabconfigured) { this.openhabconfigured = openhabconfigured; } + public String getHubversion() { return hubversion; } + public void setHubversion(String hubversion) { this.hubversion = hubversion; } + public String getHubmac() { return hubmac; } + public void setHubmac(String hubmac) { this.hubmac = hubmac; } + public IpList getDomoticzaddress() { return domoticzaddress; } + public void setDomoticzaddress(IpList domoticzaddress) { this.domoticzaddress = domoticzaddress; } + public boolean isDomoticzconfigured() { return domoticzconfigured; } + public void setDomoticzconfigured(boolean domoticzconfigured) { this.domoticzconfigured = domoticzconfigured; } + public boolean isLifxconfigured() { return lifxconfigured; } + public void setLifxconfigured(boolean lifxconfigured) { this.lifxconfigured = lifxconfigured; } + public String getSecurityData() { return securityData; } + public void setSecurityData(String securityData) { this.securityData = securityData; } + public Integer getUpnpsenddelay() { return upnpsenddelay; } + public void setUpnpsenddelay(Integer upnpsenddelay) { this.upnpsenddelay = upnpsenddelay; } + public IpList getFhemaddress() { return fhemaddress; } + public void setFhemaddress(IpList fhemaddress) { this.fhemaddress = fhemaddress; } + public boolean isFhemconfigured() { return fhemconfigured; } + public void setFhemconfigured(boolean fhemconfigured) { this.fhemconfigured = fhemconfigured; } -// public List getActiveloggers() { -// return activeloggers; -// } -// public void setActiveloggers(List activeloggers) { -// this.activeloggers = activeloggers; -// } + + // public List getActiveloggers() { + // return activeloggers; + // } + // public void setActiveloggers(List activeloggers) { + // this.activeloggers = activeloggers; + // } public boolean isBroadlinkconfigured() { return broadlinkconfigured; } + public void setBroadlinkconfigured(boolean broadlinkconfigured) { this.broadlinkconfigured = broadlinkconfigured; } + public Boolean isValidVera() { - if(this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0) + if (this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0) return false; List devicesList = this.getVeraAddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; return true; } + public Boolean isValidFibaro() { - if(this.getFibaroAddress() == null || this.getFibaroAddress().getDevices().size() <= 0) + if (this.getFibaroAddress() == null || this.getFibaroAddress().getDevices().size() <= 0) return false; List devicesList = this.getFibaroAddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; return true; } + public Boolean isValidHarmony() { - if(this.getHarmonyAddress() == null || this.getHarmonyAddress().getDevices().size() <= 0) - return false; + if (this.getHarmonyAddress() == null || this.getHarmonyAddress().getDevices().size() <= 0) + return false; List devicesList = this.getHarmonyAddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; return true; } + public Boolean isValidNest() { - if(this.getNestpwd() == null || this.getNestpwd().equals("")) + if (this.getNestpwd() == null || this.getNestpwd().equals("")) return false; - if(this.getNestuser() == null || this.getNestuser().equals("")) + if (this.getNestuser() == null || this.getNestuser().equals("")) return false; return true; } + public Boolean isValidHue() { - if(this.getHueaddress() == null || this.getHueaddress().getDevices().size() <= 0) + if (this.getHueaddress() == null || this.getHueaddress().getDevices().size() <= 0) return false; List devicesList = this.getHueaddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; return true; } + public Boolean isValidHal() { - if(this.getHaladdress() == null || this.getHaladdress().getDevices().size() <= 0) - return false; - List devicesList = this.getHaladdress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (this.getHaladdress() == null || this.getHaladdress().getDevices().size() <= 0) return false; - if(devicesList.get(0).getPassword() == null || devicesList.get(0).getPassword().trim().isEmpty()) { - if(this.getHaltoken() == null || this.getHaltoken().equals("")) + List devicesList = this.getHaladdress().getDevices(); + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + return false; + if (devicesList.get(0).getPassword() == null || devicesList.get(0).getPassword().trim().isEmpty()) { + if (this.getHaltoken() == null || this.getHaltoken().equals("")) return false; } return true; } + public Boolean isValidMQTT() { - if(this.getMqttaddress() == null || this.getMqttaddress().getDevices().size() <= 0) - return false; + if (this.getMqttaddress() == null || this.getMqttaddress().getDevices().size() <= 0) + return false; List devicesList = this.getMqttaddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; return true; } + public Boolean isValidHass() { - if(this.getHassaddress() == null || this.getHassaddress().getDevices().size() <= 0) - return false; + if (this.getHassaddress() == null || this.getHassaddress().getDevices().size() <= 0) + return false; List devicesList = this.getHassaddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; return true; } + public Boolean isValidDomoticz() { - if(this.getDomoticzaddress() == null || this.getDomoticzaddress().getDevices().size() <= 0) - return false; + if (this.getDomoticzaddress() == null || this.getDomoticzaddress().getDevices().size() <= 0) + return false; List devicesList = this.getDomoticzaddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; return true; } + public Boolean isValidSomfy() { - if(this.getSomfyAddress() == null || this.getSomfyAddress().getDevices().size() <= 0) + if (this.getSomfyAddress() == null || this.getSomfyAddress().getDevices().size() <= 0) return false; List devicesList = this.getSomfyAddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; return true; } + public Boolean isValidLifx() { return this.isLifxconfigured(); } + public void updateHue(NamedIP aHue) { int indexHue = -1; - for( int i = 0; i < hueaddress.getDevices().size(); i++) { - if(hueaddress.getDevices().get(i).getName().equals(aHue.getName())) + for (int i = 0; i < hueaddress.getDevices().size(); i++) { + if (hueaddress.getDevices().get(i).getName().equals(aHue.getName())) indexHue = i; } - if(indexHue >= 0) { + if (indexHue >= 0) { hueaddress.getDevices().set(indexHue, aHue); this.setSettingsChanged(true); } } + public Boolean isValidHomeWizard() { - if(this.getHomeWizardAddress() == null || this.getHomeWizardAddress().getDevices().size() <= 0) + if (this.getHomeWizardAddress() == null || this.getHomeWizardAddress().getDevices().size() <= 0) return false; - + List devicesList = this.getHomeWizardAddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; - + return true; } + public Boolean isValidOpenhab() { - if(this.getOpenhabaddress() == null || this.getOpenhabaddress().getDevices().size() <= 0) + if (this.getOpenhabaddress() == null || this.getOpenhabaddress().getDevices().size() <= 0) return false; - + List devicesList = this.getOpenhabaddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; - + return true; } + public Boolean isValidFhem() { - if(this.getFhemaddress() == null || this.getFhemaddress().getDevices().size() <= 0) + if (this.getFhemaddress() == null || this.getFhemaddress().getDevices().size() <= 0) return false; - + List devicesList = this.getFhemaddress().getDevices(); - if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; - + return true; } + public Boolean isValidBroadlink() { return this.isBroadlinkconfigured(); } + + public boolean isTracestate() { + return tracestate; + } + + public void setTracestate(boolean tracestate) { + this.tracestate = tracestate; + } + + public IpList getMoziotgateway() { + return moziotgateway; + } + + public void setMoziotgateway(IpList moziotgateway) { + this.moziotgateway = moziotgateway; + } + + public Boolean isValidMozIot() { + if (this.getMoziotgateway() == null || this.getMoziotgateway().getDevices().size() <= 0) + return false; + + List devicesList = this.getMoziotgateway().getDevices(); + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + return false; + + return true; + } + + public boolean isMoziotconfigured() { + return moziotconfigured; + } + + public void setMoziotconfigured(boolean moziotconfigured) { + this.moziotconfigured = moziotconfigured; + } } diff --git a/src/main/java/com/bwssystems/HABridge/hue/ColorData.java b/src/main/java/com/bwssystems/HABridge/hue/ColorData.java index 6fd417c..700fa5b 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/ColorData.java +++ b/src/main/java/com/bwssystems/HABridge/hue/ColorData.java @@ -19,4 +19,10 @@ public class ColorData { return mode; } + public String toString() { + String formatString; + + formatString = "Color Data mode: " + mode + ", data: " + data; + return formatString; + } } \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java index 89b97f9..4fee010 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java +++ b/src/main/java/com/bwssystems/HABridge/hue/ColorDecode.java @@ -23,7 +23,7 @@ public class ColorDecode { private static final String COLOR_HSL = "${color.hsl}"; private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}"); - public static List convertHSLtoRGB(int hue, int sat, int brightness) { + public static List convertHSLtoRGB(HueSatBri hsl) { List rgb; float decimalBrightness = (float) 0.0; float var_1 = (float) 0.0; @@ -35,25 +35,25 @@ public class ColorDecode { double g = 0.0; double b = 0.0; - if(brightness > 0) - decimalBrightness = (float) (brightness / 255.0); + if(hsl.getBri() > 0) + decimalBrightness = (float) (hsl.getBri() / 255.0); - if(hue > 0) { - h = (float)(hue / 65535.0); + if(hsl.getHue() > 0) { + h = ((float)hsl.getHue() / (float)65535.0); h2 = h + (float)0.5; - if(h2 > 1) { - h2 = h2 * (float) -1.0; + if(h2 > 1.0) { + h2 = h2 - (float)1.0; } } - if(sat > 0) { - s = (float)(sat / 254.0); + if(hsl.getSat() > 0) { + s = (float)(hsl.getSat() / 254.0); } if (s == 0) { - r = decimalBrightness * 255; - g = decimalBrightness * 255; - b = decimalBrightness * 255; + r = decimalBrightness * (float)255; + g = decimalBrightness * (float)255; + b = decimalBrightness * (float)255; } else { @@ -66,44 +66,51 @@ public class ColorDecode { var_2 = (decimalBrightness + s) - (s * decimalBrightness); }; - var_1 = 2 * decimalBrightness - var_2; - r = 255 * hue_2_rgb(var_1,var_2,h2 + (1 / 3)); - g = 255 * hue_2_rgb(var_1,var_2,h2); - b = 255 * hue_2_rgb(var_1,var_2,h2 - (1 / 3)); + var_1 = 2 * decimalBrightness - var_2; + float onethird = (float)0.33333; + float h2Plus = (h2 + onethird); + float h2Minus = (h2 - onethird); + log.debug("calculate HSL vars - var1: " + var_1 + ", var_2: " + var_2 + ", h2: " + h2 + ", h2 + 1/3: " + h2Plus + ", h2 - 1/3: " + h2Minus); + r = 255 * hue_2_rgb(var_1, var_2, h2Plus); + g = 255 * hue_2_rgb(var_1, var_2, h2); + b = 255 * hue_2_rgb(var_1, var_2, h2Minus); }; rgb = new ArrayList(); - rgb.add((int) Math.round(r * 255)); - rgb.add((int) Math.round(g * 255)); - rgb.add((int) Math.round(b * 255)); + rgb.add((int) Math.round(r)); + rgb.add((int) Math.round(g)); + rgb.add((int) Math.round(b)); + log.debug("Color change with HSL: " + hsl + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + + rgb.get(2)); return rgb; } public static float hue_2_rgb(float v1, float v2, float vh) { - if (vh < 0) + log.debug("hue_2_rgb vh: " + vh); + if (vh < 0.0) { - vh += 1; + vh = vh + (float)1; }; - if (vh > 1) + if (vh > 1.0) { - vh -= 1; + vh = vh - (float)1; }; - if ((6 * vh) < 1) + if (((float)6.0 * vh) < 1.0) { - return (v1 + (v2 - v1) * 6 * vh); + return (v1 + (v2 - v1) * (float)6.0 * vh); }; - if ((2 * vh) < 1) + if (((float)2.0 * vh) < 1.0) { return (v2); }; - if ((3 * vh) < 2) + if ((3.0 * vh) < 2.0) { - return (v1 + (v2 - v1) * ((2 / 3 - vh) * 6)); + return (v1 + (v2 - v1) * (((float)2.0 / (float)3.0 - vh) * (float)6.0)); }; return (v1); @@ -245,6 +252,8 @@ public class ColorDecode { rgb = convertCIEtoRGB((List) colorData.getData(), setIntensity); } else if (colorMode == ColorData.ColorMode.CT) { rgb = convertCTtoRGB((Integer) colorData.getData()); + } else if (colorMode == ColorData.ColorMode.HS) { + rgb = convertHSLtoRGB((HueSatBri) colorData.getData()); } while (notDone) { diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 80174b1..4b7de93 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -44,7 +44,8 @@ import java.util.Map; import java.util.Arrays; /** - * Based on Armzilla's HueMulator - a Philips Hue emulator using sparkjava rest server + * Based on Armzilla's HueMulator - a Philips Hue emulator using sparkjava rest + * server */ public class HueMulator { @@ -60,14 +61,15 @@ public class HueMulator { private Gson aGsonHandler; private DeviceMapTypes validMapTypes; - public HueMulator(BridgeSettings bridgeMaster, DeviceRepository aDeviceRepository, GroupRepository aGroupRepository, HomeManager aHomeManager) { + public HueMulator(BridgeSettings bridgeMaster, DeviceRepository aDeviceRepository, GroupRepository aGroupRepository, + HomeManager aHomeManager) { repository = aDeviceRepository; groupRepository = aGroupRepository; validMapTypes = new DeviceMapTypes(); bridgeSettingMaster = bridgeMaster; bridgeSettings = bridgeSettingMaster.getBridgeSettingsDescriptor(); - - homeManager= aHomeManager; + + homeManager = aHomeManager; myHueHome = (HueHome) homeManager.findHome(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex]); aGsonHandler = new GsonBuilder().create(); } @@ -77,21 +79,22 @@ public class HueMulator { log.info("Hue emulator service started...."); before(HUE_CONTEXT + "/*", (request, response) -> { // This currently causes an error with Spark replies -// String path = request.pathInfo(); -// if (path.endsWith("/")) { // it should work with or without a trailing slash -// response.redirect(path.substring(0, path.length() - 1)); -// } - log.debug("HueMulator " + request.requestMethod() + " called on api/* with request <<<" + request.pathInfo() + ">>>, and body <<<" + request.body() + ">>>"); - if(bridgeSettingMaster.getBridgeSecurity().isSecure()) { + // String path = request.pathInfo(); + // if (path.endsWith("/")) { // it should work with or without a trailing slash + // response.redirect(path.substring(0, path.length() - 1)); + // } + log.debug("HueMulator " + request.requestMethod() + " called on api/* with request <<<" + request.pathInfo() + + ">>>, and body <<<" + request.body() + ">>>"); + if (bridgeSettingMaster.getBridgeSecurity().isSecure()) { String pathInfo = request.pathInfo(); - if(pathInfo != null && pathInfo.contains(HUE_CONTEXT + "/devices")) { + if (pathInfo != null && pathInfo.contains(HUE_CONTEXT + "/devices")) { User authUser = bridgeSettingMaster.getBridgeSecurity().getAuthenticatedUser(request); - if(authUser == null) { + if (authUser == null) { halt(401, "{\"message\":\"User not authenticated\"}"); } } else if (bridgeSettingMaster.getBridgeSecurity().isSecureHueApi()) { User authUser = bridgeSettingMaster.getBridgeSecurity().getAuthenticatedUser(request); - if(authUser == null) { + if (authUser == null) { halt(401, "{\"message\":\"User not authenticated\"}"); } } @@ -103,16 +106,16 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return groupsListHandler(request.params(":userid"), request.ip()); - } , new JsonTransformer()); + return groupsListHandler(request.params(":userid"), request.ip()); + }, new JsonTransformer()); // http://ip_address:port/api/{userId}/groups/{groupId} returns json // object for specified group. get(HUE_CONTEXT + "/:userid/groups/:groupid", "application/json", (request, response) -> { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return groupsIdHandler(request.params(":groupid"), request.params(":userid"), request.ip()); - } , new JsonTransformer()); + return groupsIdHandler(request.params(":groupid"), request.params(":userid"), request.ip()); + }, new JsonTransformer()); // http://ip_address:port/:userid/groups CORS request options(HUE_CONTEXT + "/:userid/groups", "application/json", (request, response) -> { response.status(HttpStatus.SC_OK); @@ -152,15 +155,16 @@ 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); - }); + return changeGroupState(request.params(":userid"), request.params(":groupid"), request.body(), request.ip(), + false); + }); // http://ip_address:port/api/{userId}/scenes returns json objects of // all scenes configured get(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return basicListHandler("scenes", request.params(":userid"), request.ip()); + return basicListHandler("scenes", request.params(":userid"), request.ip()); }); // http://ip_address:port/:userid/scenes CORS request options(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> { @@ -177,7 +181,8 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - log.debug("scene add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + log.debug("scene add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + + request.body()); return "[{\"success\":{\"id\":\"1\"}}]"; }); // http://ip_address:port/api/{userId}/schedules returns json objects of @@ -186,7 +191,7 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return basicListHandler("schedules", request.params(":userid"), request.ip()); + return basicListHandler("schedules", request.params(":userid"), request.ip()); }); // http://ip_address:port/:userid/schedules CORS request options(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> { @@ -203,7 +208,8 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - log.debug("schedules add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + log.debug("schedules add requested from " + request.ip() + " user " + request.params(":userid") + + " with body " + request.body()); return "[{\"success\":{\"id\":\"1\"}}]"; }); // http://ip_address:port/api/{userId}/sensors returns json objects of @@ -212,7 +218,7 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return basicListHandler("sensors", request.params(":userid"), request.ip()); + return basicListHandler("sensors", request.params(":userid"), request.ip()); }); // http://ip_address:port/:userid/sensors CORS request options(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> { @@ -229,7 +235,8 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - log.debug("sensors add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + log.debug("sensors add requested from " + request.ip() + " user " + request.params(":userid") + + " with body " + request.body()); return "[{\"success\":{\"id\":\"1\"}}]"; }); // http://ip_address:port/api/{userId}/rules returns json objects of all @@ -238,7 +245,7 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return basicListHandler("rules", request.params(":userid"), request.ip()); + return basicListHandler("rules", request.params(":userid"), request.ip()); }); // http://ip_address:port/:userid/rules CORS request options(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> { @@ -255,7 +262,8 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - log.debug("rules add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + log.debug("rules add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + + request.body()); return "[{\"success\":{\"id\":\"1\"}}]"; }); // http://ip_address:port/api/{userId}/resourcelinks returns json @@ -264,7 +272,7 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return basicListHandler("resourcelinks", request.params(":userid"), request.ip()); + return basicListHandler("resourcelinks", request.params(":userid"), request.ip()); }); // http://ip_address:port/:userid/resourcelinks CORS request options(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> { @@ -281,7 +289,8 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - log.debug("resourcelinks add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + log.debug("resourcelinks add requested from " + request.ip() + " user " + request.params(":userid") + + " with body " + request.body()); return "[{\"success\":{\"id\":\"1\"}}]"; }); // http://ip_address:port/api/{userId}/lights returns json objects of @@ -291,7 +300,7 @@ public class HueMulator { response.type("application/json"); response.status(HttpStatus.SC_OK); return lightsListHandler(request.params(":userid"), request.ip()); - } , new JsonTransformer()); + }, new JsonTransformer()); // http://ip_address:port/api/{userId}/lights/ returns json objects of // all lights configured @@ -300,7 +309,7 @@ public class HueMulator { response.type("application/json"); response.status(HttpStatus.SC_OK); return lightsListHandler(request.params(":userid"), request.ip()); - } , new JsonTransformer()); + }, new JsonTransformer()); // http://ip_address:port/api CORS request options(HUE_CONTEXT, "application/json", (request, response) -> { @@ -345,7 +354,7 @@ public class HueMulator { response.type("application/json"); response.status(HttpStatus.SC_OK); return getConfig(null, request.ip()); - } , new JsonTransformer()); + }, new JsonTransformer()); // http://ip_address:port/api/{userId}/config returns json objects for // the config @@ -354,7 +363,7 @@ public class HueMulator { response.type("application/json"); response.status(HttpStatus.SC_OK); return getConfig(request.params(":userid"), request.ip()); - } , new JsonTransformer()); + }, new JsonTransformer()); // http://ip_address:port/:userid/config CORS request options(HUE_CONTEXT + "/:userid/config", "application/json", (request, response) -> { response.status(HttpStatus.SC_OK); @@ -370,9 +379,10 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - log.debug("Config change requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + log.debug("Config change requested from " + request.ip() + " user " + request.params(":userid") + + " with body " + request.body()); HueConfig aConfig = aGsonHandler.fromJson(request.body(), HueConfig.class); - if(aConfig.getPortalservices() != null) { + if (aConfig.getPortalservices() != null) { return "[{\"success\":{\"/config/portalservices\":true}}]"; } return "[{\"success\":{\"/config/name\":\"My bridge\"}}]"; @@ -385,7 +395,7 @@ public class HueMulator { response.type("application/json"); response.status(HttpStatus.SC_OK); return getFullState(request.params(":userid"), request.ip()); - } , new JsonTransformer()); + }, new JsonTransformer()); // http://ip_address:port/api/{userId}/ returns json objects for the full // state @@ -394,7 +404,7 @@ public class HueMulator { response.type("application/json"); response.status(HttpStatus.SC_OK); return getFullState(request.params(":userid"), request.ip()); - } , new JsonTransformer()); + }, new JsonTransformer()); // http://ip_address:port/api/{userId}/lights/{lightId} returns json // object for a given light @@ -403,7 +413,7 @@ public class HueMulator { response.type("application/json"); response.status(HttpStatus.SC_OK); return getLight(request.params(":userid"), request.params(":id"), request.ip()); - } , new JsonTransformer()); + }, new JsonTransformer()); // http://ip_address:port/api/:userid/lights/:id/bridgeupdatestate CORS // request @@ -444,7 +454,7 @@ public class HueMulator { return changeState(request.params(":userid"), request.params(":id"), request.body(), request.ip(), false); }); } - + @SuppressWarnings("unchecked") private String formatSuccessHueResponse(StateChangeBody stateChanges, String body, String lightId, DeviceState deviceState, Integer targetBri, Integer targetBriInc, ColorData colorData, boolean offState) { @@ -460,9 +470,9 @@ public class HueMulator { } if (deviceState != null) { deviceState.setOn(stateChanges.isOn()); - if(!deviceState.isOn() && deviceState.getBri() == 254) + if (!deviceState.isOn() && deviceState.getBri() == 254) deviceState.setBri(0); - if(!deviceState.isOn() && offState) + if (!deviceState.isOn() && offState) deviceState.setBri(0); } notFirstChange = true; @@ -471,8 +481,8 @@ public class HueMulator { if (body.contains("\"bri\"")) { if (notFirstChange) responseString = responseString + ","; - responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/bri\":" + stateChanges.getBri() - + "}}"; + responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/bri\":" + + stateChanges.getBri() + "}}"; if (deviceState != null) deviceState.setBri(stateChanges.getBri()); notFirstChange = true; @@ -494,16 +504,16 @@ public class HueMulator { if (body.contains("\"xy\"")) { if (notFirstChange) responseString = responseString + ","; - responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/xy\":" + stateChanges.getXy() - + "}}"; + responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/xy\":" + + stateChanges.getXy() + "}}"; if (deviceState != null) deviceState.setXy(stateChanges.getXy()); notFirstChange = true; } else if (body.contains("\"ct\"")) { if (notFirstChange) responseString = responseString + ","; - responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/ct\":" + stateChanges.getCt() - + "}}"; + responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/ct\":" + + stateChanges.getCt() + "}}"; if (deviceState != null) deviceState.setCt(stateChanges.getCt()); notFirstChange = true; @@ -511,8 +521,8 @@ public class HueMulator { if (body.contains("\"hue\"")) { if (notFirstChange) responseString = responseString + ","; - responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/hue\":" + stateChanges.getHue() - + "}}"; + responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/hue\":" + + stateChanges.getHue() + "}}"; if (deviceState != null) deviceState.setHue(stateChanges.getHue()); notFirstChange = true; @@ -521,12 +531,12 @@ public class HueMulator { if (body.contains("\"sat\"")) { if (notFirstChange) responseString = responseString + ","; - responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/sat\":" + stateChanges.getSat() - + "}}"; + responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/sat\":" + + stateChanges.getSat() + "}}"; if (deviceState != null) deviceState.setSat(stateChanges.getSat()); notFirstChange = true; - } + } } if (body.contains("\"xy_inc\"")) { @@ -564,7 +574,7 @@ public class HueMulator { if (deviceState != null) deviceState.setSat(deviceState.getSat() + stateChanges.getSat_inc()); notFirstChange = true; - } + } } if (body.contains("\"effect\"")) { @@ -597,11 +607,12 @@ public class HueMulator { notFirstChange = true; } - if((deviceState != null) && deviceState.isOn() && deviceState.getBri() <= 0) + if ((deviceState != null) && deviceState.isOn() && deviceState.getBri() <= 0) deviceState.setBri(254); - -// if((deviceState != null) && !deviceState.isOn() && (targetBri != null || targetBriInc != null)) -// deviceState.setOn(true); + + // if((deviceState != null) && !deviceState.isOn() && (targetBri != null || + // targetBriInc != null)) + // deviceState.setOn(true); responseString = responseString + "]"; @@ -628,9 +639,10 @@ public class HueMulator { private String basicListHandler(String type, String userId, String requestIp) { log.debug("hue " + type + " list requested by user: " + userId + " from address: " + requestIp); - HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors != null) { - if(bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) + if (bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) bridgeSettingMaster.updateConfigFile(); return aGsonHandler.toJson(theErrors); @@ -642,9 +654,10 @@ public class HueMulator { private Object addGroup(String userId, String ip, String body) { HueError[] theErrors = null; log.debug("group add requested from " + ip + " user " + userId + " with body " + body); - theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors == null) { - if(bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) + if (bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) bridgeSettingMaster.updateConfigFile(); GroupResponse theGroup = null; @@ -655,13 +668,14 @@ public class HueMulator { } if (theGroup == null) { log.warn("Could not parse add group body. No group created."); - return aGsonHandler.toJson(HueErrorResponse.createResponse("5", "/groups/lights", - "invalid/missing parameters in body", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("5", "/groups/lights", "invalid/missing parameters in body", null, null, null) + .getTheErrors(), HueError[].class); } - + List groups = groupRepository.findAll(); GroupDescriptor newGroup = new GroupDescriptor(); - + String type = theGroup.getType(); String groupClass = theGroup.getClass_name(); @@ -675,14 +689,16 @@ public class HueMulator { if (!type.equals("Room")) { if (theGroup.getLights() == null || theGroup.getLights().length == 0) { return aGsonHandler.toJson(HueErrorResponse.createResponse("5", "/groups/lights", - "invalid/missing parameters in body", null, null, null).getTheErrors(), HueError[].class); + "invalid/missing parameters in body", null, null, null).getTheErrors(), HueError[].class); } } else { // check room class if it's a room if (groupClass == null || groupClass.trim().equals("")) { groupClass = GroupClassTypes.OTHER; } else if (!new GroupClassTypes().validateType(groupClass)) { - return aGsonHandler.toJson(HueErrorResponse.createResponse("7", "/groups/class", - "invalid value, " + groupClass + ", for parameter, class", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("7", "/groups/class", + "invalid value, " + groupClass + ", for parameter, class", null, null, null) + .getTheErrors(), HueError[].class); } } String name = theGroup.getName(); @@ -696,7 +712,7 @@ public class HueMulator { newGroup.setLights(theGroup.getLights()); groups.add(newGroup); groupRepository.save(groups.toArray(new GroupDescriptor[0])); - + return "[{\"success\":{\"id\":\"" + newId + "\"}}]"; } @@ -706,15 +722,19 @@ public class HueMulator { private Object deleteGroup(String userId, String groupId, String ip) { HueError[] theErrors = null; log.debug("group delete requested from " + ip + " user " + userId); - theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors == null) { - if(bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) + if (bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) bridgeSettingMaster.updateConfigFile(); GroupDescriptor group = groupRepository.findOne(groupId); if (group == null || group.isInactive()) { - return aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/groups/" + groupId, - "resource, /groups/" + groupId + ", not available", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler + .toJson(HueErrorResponse + .createResponse("3", "/groups/" + groupId, + "resource, /groups/" + groupId + ", not available", null, null, null) + .getTheErrors(), HueError[].class); } else { groupRepository.delete(group); return "[{\"success\":\"/groups/" + groupId + " deleted\"}}]"; @@ -726,15 +746,19 @@ public class HueMulator { private Object modifyGroup(String userId, String groupId, String ip, String body) { HueError[] theErrors = null; log.debug("group modify requested from " + ip + " user " + userId + " with body " + body); - theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors == null) { - if(bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) + if (bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) bridgeSettingMaster.updateConfigFile(); GroupDescriptor group = groupRepository.findOne(groupId); if (group == null || group.isInactive()) { - return aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/groups/" + groupId, - "resource, /groups/" + groupId + ", not available", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler + .toJson(HueErrorResponse + .createResponse("3", "/groups/" + groupId, + "resource, /groups/" + groupId + ", not available", null, null, null) + .getTheErrors(), HueError[].class); } else { String successString = "["; GroupResponse theGroup = null; @@ -757,37 +781,48 @@ public class HueMulator { } if (!group.getGroupType().equals("Room")) { if (!(groupClass == null || groupClass.trim().equals(""))) { - return aGsonHandler.toJson(HueErrorResponse.createResponse("6", "/groups/" + groupId + "/class", - "parameter, /groups/" + groupId + "/class, not available", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("6", "/groups/" + groupId + "/class", + "parameter, /groups/" + groupId + "/class, not available", null, null, null) + .getTheErrors(), HueError[].class); } if (theGroup.getLights() != null) { if (theGroup.getLights().length == 0) { - return aGsonHandler.toJson(HueErrorResponse.createResponse("7", "/groups/" + groupId + "/lights", - "invalid value, " + Arrays.toString(theGroup.getLights()) + ", for parameter, /groups" + groupId + "/lights", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler + .toJson(HueErrorResponse.createResponse("7", "/groups/" + groupId + "/lights", + "invalid value, " + Arrays.toString(theGroup.getLights()) + + ", for parameter, /groups" + groupId + "/lights", + null, null, null).getTheErrors(), HueError[].class); } else { group.setLights(theGroup.getLights()); - successString += "{\"success\":{\"/groups/" + groupId + "/lights\":\"" + Arrays.toString(theGroup.getLights()) + "\"}},"; + successString += "{\"success\":{\"/groups/" + groupId + "/lights\":\"" + + Arrays.toString(theGroup.getLights()) + "\"}},"; } } } else { // check room class if it's a room if (!(groupClass == null || groupClass.trim().equals(""))) { if (!new GroupClassTypes().validateType(groupClass)) { - return aGsonHandler.toJson(HueErrorResponse.createResponse("7", "/groups/class", - "invalid value, " + groupClass + ", for parameter, class", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("7", "/groups/class", + "invalid value, " + groupClass + ", for parameter, class", null, null, null) + .getTheErrors(), HueError[].class); } else { group.setGroupClass(groupClass); - successString += "{\"success\":{\"/groups/" + groupId + "/class\":\"" + groupClass + "\"}},"; + successString += "{\"success\":{\"/groups/" + groupId + "/class\":\"" + groupClass + + "\"}},"; } } if (theGroup.getLights() != null) { group.setLights(theGroup.getLights()); - successString += "{\"success\":{\"/groups/" + groupId + "/lights\":\"" + Arrays.toString(theGroup.getLights()) + "\"}},"; + successString += "{\"success\":{\"/groups/" + groupId + "/lights\":\"" + + Arrays.toString(theGroup.getLights()) + "\"}},"; } } - + groupRepository.save(); - return (successString.length() == 1) ? "[]" : successString.substring(0, successString.length()-1) + "]"; + return (successString.length() == 1) ? "[]" + : successString.substring(0, successString.length() - 1) + "]"; } } return theErrors; @@ -799,17 +834,19 @@ public class HueMulator { if (bridgeSettings.isTraceupnp()) log.info("Traceupnp: hue group list requested: " + userId + " from " + requestIp); log.debug("hue group list requested: " + userId + " from " + requestIp); - theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors == null) { - if(bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) + if (bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) bridgeSettingMaster.updateConfigFile(); - List groupList = groupRepository.findAllByRequester(requestIp); + List groupList = groupRepository.findAllByRequester(requestIp); groupResponseMap = new HashMap(); for (GroupDescriptor group : groupList) { GroupResponse groupResponse = null; - if(!group.isInactive()) { - Map lights = repository.findAllByGroupWithState(group.getLights(), requestIp, myHueHome, aGsonHandler); + if (!group.isInactive()) { + Map lights = repository.findAllByGroupWithState(group.getLights(), + requestIp, myHueHome, aGsonHandler); groupResponse = GroupResponse.createResponse(group, lights); groupResponseMap.put(group.getId(), groupResponse); } @@ -822,30 +859,34 @@ public class HueMulator { return groupResponseMap; } - private Object groupsIdHandler(String groupId, String userId, String requestIp) { log.debug("hue group id: <" + groupId + "> requested: " + userId + " from " + requestIp); HueError[] theErrors = null; - theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors == null) { - if(bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) + if (bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) bridgeSettingMaster.updateConfigFile(); if (groupId.equalsIgnoreCase("0")) { @SuppressWarnings("unchecked") - GroupResponse theResponse = GroupResponse.createDefaultGroupResponse((Map)lightsListHandler(userId, requestIp)); + GroupResponse theResponse = GroupResponse + .createDefaultGroupResponse((Map) lightsListHandler(userId, requestIp)); return theResponse; } else { GroupDescriptor group = groupRepository.findOne(groupId); if (group == null || group.isInactive()) { - return aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/groups/" + groupId, - "resource, /groups/" + groupId + ", not available", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("3", "/groups/" + groupId, + "resource, /groups/" + groupId + ", not available", null, null, null) + .getTheErrors(), HueError[].class); } else { - Map lights = repository.findAllByGroupWithState(group.getLights(), requestIp, myHueHome, aGsonHandler); + Map lights = repository.findAllByGroupWithState(group.getLights(), + requestIp, myHueHome, aGsonHandler); GroupResponse theResponse = GroupResponse.createResponse(group, lights); - return theResponse; + return theResponse; } - + } } @@ -858,52 +899,56 @@ public class HueMulator { if (bridgeSettings.isTraceupnp()) log.info("Traceupnp: hue lights list requested by user: " + userId + " from address: " + requestIp); log.debug("hue lights list requested: " + userId + " from " + requestIp); - theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors == null) { - if(bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) + if (bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) bridgeSettingMaster.updateConfigFile(); - List deviceList = repository.findAllByRequester(requestIp); + List deviceList = repository.findAllByRequester(requestIp); deviceResponseMap = new HashMap(); for (DeviceDescriptor device : deviceList) { DeviceResponse deviceResponse = null; - if(!device.isInactive()) { + if (!device.isInactive()) { if (device.containsType(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { CallItem[] callItems = null; try { - if(device.getOnUrl() != null) + if (device.getOnUrl() != null) callItems = aGsonHandler.fromJson(device.getOnUrl(), CallItem[].class); - } catch(JsonSyntaxException e) { - log.warn("Could not decode Json for url items to get Hue state for device: " + device.getName()); + } catch (JsonSyntaxException e) { + log.warn("Could not decode Json for url items to get Hue state for device: " + + device.getName()); callItems = null; } - + for (int i = 0; callItems != null && i < callItems.length; i++) { - if((callItems[i].getType() != null && callItems[i].getType().equals(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) || - (callItems[i].getItem().getAsString().contains("hueName"))) { + if ((callItems[i].getType() != null && callItems[i].getType() + .equals(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) + || (callItems[i].getItem().getAsString().contains("hueName"))) { deviceResponse = myHueHome.getHueDeviceInfo(callItems[i], device); i = callItems.length; } } } - + if (deviceResponse == null) deviceResponse = DeviceResponse.createResponse(device); deviceResponseMap.put(device.getId(), deviceResponse); } } - // handle groups which shall be exposed as fake lights to selected devices like amazon echos + // handle groups which shall be exposed as fake lights to selected devices like + // amazon echos List groups = groupRepository.findVirtualLights(requestIp); for (GroupDescriptor group : groups) { - deviceResponseMap.put(String.valueOf(Integer.parseInt(group.getId()) + 10000), - DeviceResponse.createResponseForVirtualLight(group)); + deviceResponseMap.put(String.valueOf(Integer.parseInt(group.getId()) + 10000), + DeviceResponse.createResponseForVirtualLight(group)); } } - + if (theErrors != null) return theErrors; - + return deviceResponseMap; } @@ -917,58 +962,62 @@ public class HueMulator { log.info("Traceupnp: hue api user create requested: " + body + " from address: " + ipAddress); else log.debug("hue api user create requested: " + body + " from address: " + ipAddress); - - if(bridgeSettingMaster.getBridgeSecurity().isUseLinkButton() && bridgeSettingMaster.getBridgeControl().isLinkButton()) + + if (bridgeSettingMaster.getBridgeSecurity().isUseLinkButton() + && bridgeSettingMaster.getBridgeControl().isLinkButton()) toContinue = true; - else if(!bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()) + else if (!bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()) toContinue = true; - - if(toContinue) { + + if (toContinue) { log.debug("user add toContinue was true, creating user."); - + if (body != null && !body.isEmpty()) { try { aNewUser = aGsonHandler.fromJson(body, UserCreateRequest.class); } catch (Exception e) { log.warn("Could not add user. Request garbled: " + body); - return aGsonHandler.toJson(HueErrorResponse.createResponse("2", "/", - "Could not add user.", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("2", "/", "Could not add user.", null, null, null).getTheErrors(), + HueError[].class); } newUser = aNewUser.getUsername(); aDeviceType = aNewUser.getDevicetype(); } - + if (aDeviceType == null) aDeviceType = ""; else aDeviceType = aDeviceType + "#" + ipAddress; - + if (newUser == null) { newUser = bridgeSettingMaster.getBridgeSecurity().createWhitelistUser(aDeviceType); - } - else { + } else { bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(newUser, aDeviceType, false); } - - if(bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) + + if (bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) bridgeSettingMaster.updateConfigFile(); - + if (bridgeSettings.isTraceupnp() && !aDeviceType.equals("test_ha_bridge")) log.info("Traceupnp: hue api user create requested for device type: " + aDeviceType + " and username: " + newUser + (followingSlash ? " /api/ called" : "")); - log.debug("hue api user create requested for device type: " + aDeviceType + " and username: " + newUser + (followingSlash ? " /api/ called" : "")); + log.debug("hue api user create requested for device type: " + aDeviceType + " and username: " + newUser + + (followingSlash ? " /api/ called" : "")); return "[{\"success\":{\"username\":\"" + newUser + "\"}}]"; - } - else + } else log.debug("user add toContinue was false, returning not authorized"); - return aGsonHandler.toJson(HueErrorResponse.createResponse("101", "/api/", "link button not pressed", null, null, null).getTheErrors()); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("101", "/api/", "link button not pressed", null, null, null).getTheErrors()); } - + private Object getConfig(String userId, String ipAddress) { if (bridgeSettings.isTraceupnp()) - log.info("Traceupnp: hue api/:userid/config config requested from user: " + userId + " from address: " + ipAddress); + log.info("Traceupnp: hue api/:userid/config config requested from user: " + userId + " from address: " + + ipAddress); log.debug("hue api config requested: " + userId + " from " + ipAddress); - if (bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()) != null) { + if (bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()) != null) { log.debug("hue api config requested, User invalid, returning public config"); HuePublicConfig apiResponse = HuePublicConfig.createConfig("HA-Bridge", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getHubversion(), bridgeSettings.getHubmac()); @@ -976,31 +1025,35 @@ public class HueMulator { } HueApiResponse apiResponse = new HueApiResponse("HA-Bridge", bridgeSettings.getUpnpConfigAddress(), - bridgeSettingMaster.getBridgeSecurity().getWhitelist(), bridgeSettings.getHubversion(), bridgeSettingMaster.getBridgeControl().isLinkButton(), bridgeSettings.getHubmac()); + bridgeSettingMaster.getBridgeSecurity().getWhitelist(), bridgeSettings.getHubversion(), + bridgeSettingMaster.getBridgeControl().isLinkButton(), bridgeSettings.getHubmac()); log.debug("api response config <<<" + aGsonHandler.toJson(apiResponse.getConfig()) + ">>>"); return apiResponse.getConfig(); } - + @SuppressWarnings("unchecked") private Object getFullState(String userId, String ipAddress) { log.debug("hue api full state requested: " + userId + " from " + ipAddress); - HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors != null) { log.debug("full state error occurred <<<" + aGsonHandler.toJson(theErrors) + ">>>"); return theErrors; } HueApiResponse apiResponse = new HueApiResponse("HA-Bridge", bridgeSettings.getUpnpConfigAddress(), - bridgeSettingMaster.getBridgeSecurity().getWhitelist(), bridgeSettings.getHubversion(), bridgeSettingMaster.getBridgeControl().isLinkButton(), bridgeSettings.getHubmac()); + bridgeSettingMaster.getBridgeSecurity().getWhitelist(), bridgeSettings.getHubversion(), + bridgeSettingMaster.getBridgeControl().isLinkButton(), bridgeSettings.getHubmac()); apiResponse.setLights((Map) this.lightsListHandler(userId, ipAddress)); apiResponse.setGroups((Map) this.groupsListHandler(userId, ipAddress)); return apiResponse; } - + private Object getLight(String userId, String lightId, String ipAddress) { log.debug("hue light requested: " + lightId + " for user: " + userId + " from " + ipAddress); - HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors != null) return theErrors; @@ -1011,8 +1064,10 @@ public class HueMulator { DeviceDescriptor device = repository.findOne(lightId); if (device == null) { -// response.status(HttpStatus.SC_NOT_FOUND); - return HueErrorResponse.createResponse("3", "/api/" + userId + "/lights/" + lightId, "Object not found", null, null, null).getTheErrors(); + // response.status(HttpStatus.SC_NOT_FOUND); + return HueErrorResponse + .createResponse("3", "/api/" + userId + "/lights/" + lightId, "Object not found", null, null, null) + .getTheErrors(); } else { log.debug("found device named: " + device.getName()); } @@ -1020,15 +1075,17 @@ public class HueMulator { if (device.containsType(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { CallItem[] callItems = null; try { - if(device.getOnUrl() != null) + if (device.getOnUrl() != null) callItems = aGsonHandler.fromJson(device.getOnUrl(), CallItem[].class); - } catch(JsonSyntaxException e) { + } catch (JsonSyntaxException e) { log.warn("Could not decode Json for url items to get Hue state for device: " + device.getName()); callItems = null; } - + for (int i = 0; callItems != null && i < callItems.length; i++) { - if((callItems[i].getType() != null && callItems[i].getType().equals(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) || callItems[i].getItem().getAsString().startsWith("{\"ipAddress\":\"")) { + if ((callItems[i].getType() != null + && callItems[i].getType().equals(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) + || callItems[i].getItem().getAsString().startsWith("{\"ipAddress\":\"")) { lightResponse = myHueHome.getHueDeviceInfo(callItems[i], device); i = callItems.length; } @@ -1039,7 +1096,7 @@ public class HueMulator { lightResponse = DeviceResponse.createResponse(device); return lightResponse; - + } private String updateState(String userId, String lightId, String body, String ipAddress) { @@ -1050,9 +1107,13 @@ public class HueMulator { Integer targetBriInc = null; ColorData colorData = null; + if (bridgeSettings.isTracestate()) + log.info("Tracestate: Update state requested: " + userId + " from " + ipAddress + " body: " + body); + log.debug("Update state requested: " + userId + " from " + ipAddress + " body: " + body); - HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors != null) return aGsonHandler.toJson(theErrors); @@ -1060,8 +1121,9 @@ public class HueMulator { theStateChanges = aGsonHandler.fromJson(body, StateChangeBody.class); } catch (Exception e) { log.warn("Could not parse state change body. Light state not changed."); - return aGsonHandler.toJson(HueErrorResponse.createResponse("2", "/lights/" + lightId, - "Could not parse state change body.", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("2", "/lights/" + lightId, "Could not parse state change body.", null, null, null) + .getTheErrors(), HueError[].class); } DeviceDescriptor device = repository.findOne(lightId); @@ -1075,33 +1137,17 @@ public class HueMulator { if (body.contains("\"bri_inc\"")) targetBriInc = Integer.valueOf(theStateChanges.getBri_inc()); else if (body.contains("\"bri\"")) { - targetBri =Integer.valueOf(theStateChanges.getBri()); + targetBri = Integer.valueOf(theStateChanges.getBri()); } state = device.getDeviceState(); if (state == null) state = DeviceState.createDeviceState(device.isColorDevice()); - if (body.contains("\"xy\"") || body.contains("\"ct\"") || body.contains("\"hue\"") || body.contains("\"xy_inc\"") || body.contains("\"ct_inc\"") || body.contains("\"hue_inc\"")) { - List xy = theStateChanges.getXy(); - List xyInc = theStateChanges.getXy_inc(); - Integer ct = theStateChanges.getCt(); - Integer ctInc = theStateChanges.getCt_inc(); - if (xy != null && xy.size() == 2) { - colorData = new ColorData(ColorData.ColorMode.XY, xy); - } else if (xyInc != null && xyInc.size() == 2) { - List current = state.getXy(); - current.set(0, current.get(0) + xyInc.get(0)); - current.set(1, current.get(1) + xyInc.get(1)); - colorData = new ColorData(ColorData.ColorMode.XY, current); - } else if (ct != null && ct != 0) { - colorData = new ColorData(ColorData.ColorMode.CT, ct); - } else if (ctInc != null && ctInc != 0) { - colorData = new ColorData(ColorData.ColorMode.CT, state.getCt() + ctInc); - } - } - - responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, targetBriInc, colorData, device.isOffState()); + colorData = parseColorInfo(body, theStateChanges, state, targetBri, targetBriInc); + + responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, targetBriInc, + colorData, device.isOffState()); device.setDeviceState(state); return responseString; @@ -1121,8 +1167,12 @@ public class HueMulator { boolean isDimRequest = false; boolean isOnRequest = false; ColorData colorData = null; + if (bridgeSettings.isTracestate()) + log.info("Tracestate: hue state change requested: " + userId + " from " + ipAddress + " body: " + body); + log.debug("hue state change requested: " + userId + " from " + ipAddress + " body: " + body); - HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + HueError[] theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors != null) { log.warn("Errors in security: <<<" + aGsonHandler.toJson(theErrors) + ">>>"); return aGsonHandler.toJson(theErrors); @@ -1134,8 +1184,9 @@ public class HueMulator { } if (theStateChanges == null) { log.warn("Could not parse state change body. Light state not changed."); - return aGsonHandler.toJson(HueErrorResponse.createResponse("2", "/lights/" + lightId, - "Could not parse state change body.", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("2", "/lights/" + lightId, "Could not parse state change body.", null, null, null) + .getTheErrors(), HueError[].class); } DeviceDescriptor device = repository.findOne(lightId); @@ -1155,51 +1206,33 @@ public class HueMulator { if (body.contains("\"bri_inc\"")) { targetBriInc = Integer.valueOf(theStateChanges.getBri_inc()); isDimRequest = true; - } - else if (body.contains("\"bri\"")) { + } else if (body.contains("\"bri\"")) { targetBri = Integer.valueOf(theStateChanges.getBri()); isDimRequest = true; } - if (body.contains("\"xy\"") || body.contains("\"ct\"") || body.contains("\"hue\"") || body.contains("\"xy_inc\"") || body.contains("\"ct_inc\"") || body.contains("\"hue_inc\"")) { - List xy = theStateChanges.getXy(); - List xyInc = theStateChanges.getXy_inc(); - Integer ct = theStateChanges.getCt(); - Integer ctInc = theStateChanges.getCt_inc(); - if (xy != null && xy.size() == 2) { - colorData = new ColorData(ColorData.ColorMode.XY, xy); - } else if (xyInc != null && xyInc.size() == 2) { - List current = state.getXy(); - current.set(0, current.get(0) + xyInc.get(0)); - current.set(1, current.get(1) + xyInc.get(1)); - colorData = new ColorData(ColorData.ColorMode.XY, current); - } else if (ct != null && ct != 0) { - colorData = new ColorData(ColorData.ColorMode.CT, ct); - } else if (ctInc != null && ctInc != 0) { - colorData = new ColorData(ColorData.ColorMode.CT, state.getCt() + ctInc); - } - if(colorData != null) - isColorRequest = true; - } - + colorData = parseColorInfo(body, theStateChanges, state, targetBri, targetBriInc); + if (colorData != null) + isColorRequest = true; + if (body.contains("\"on\"")) { isOnRequest = true; } - - if(!device.isOnFirstDim() && device.isOnWhenDimPresent() && isDimRequest && !isOnRequest) { + + if (!device.isOnFirstDim() && device.isOnWhenDimPresent() && isDimRequest && !isOnRequest) { isOnRequest = true; theStateChanges.setOn(true); - } else if(!device.isOnFirstDim() && !device.isOnWhenDimPresent() && isDimRequest) { + } else if (!device.isOnFirstDim() && !device.isOnWhenDimPresent() && isDimRequest) { // isOnRequest = false; } - if(device.isOnFirstDim() && isDimRequest && !device.getDeviceState().isOn()) { + if (device.isOnFirstDim() && isDimRequest && !device.getDeviceState().isOn()) { isOnRequest = true; theStateChanges.setOn(true); isDimRequest = false; isColorRequest = false; - } else if(device.isOnFirstDim() && isDimRequest && device.getDeviceState().isOn()) { - if(device.getDeviceState().getBri() == theStateChanges.getBri()) { + } else if (device.isOnFirstDim() && isDimRequest && device.getDeviceState().isOn()) { + if (device.getDeviceState().getBri() == theStateChanges.getBri()) { isOnRequest = true; theStateChanges.setOn(true); isDimRequest = false; @@ -1210,8 +1243,11 @@ public class HueMulator { isColorRequest = false; } } - - if(isOnRequest) { + + if (isOnRequest) { + if (bridgeSettings.isTracestate()) + log.info("Tracestate: Calling on-off as requested."); + log.debug("Calling on-off as requested."); if (theStateChanges.isOn()) { url = device.getOnUrl(); @@ -1220,91 +1256,212 @@ public class HueMulator { } // code for backwards compatibility - if(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { - if(url == null) + if (device.getMapType() != null + && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { + if (url == null) url = device.getOnUrl(); } if (url != null && !url.equals("")) { - responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, targetBriInc, colorData); + responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, + targetBriInc, colorData); } else { - log.info("On/off url not available for state change, lightId: " + lightId + ", userId: " + userId + ", from IP: " - + ipAddress + ", body: " + body); + log.info("On/off url not available for state change, lightId: " + lightId + ", userId: " + userId + + ", from IP: " + ipAddress + ", body: " + body); } } if (isDimRequest) { + if (bridgeSettings.isTracestate()) + log.info("Tracestate: Calling dim as requested."); + log.debug("Calling dim as requested."); url = device.getDimUrl(); // code for backwards compatibility - if(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { - if(url == null) + if (device.getMapType() != null + && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { + if (url == null) url = device.getOnUrl(); } if (url != null && !url.equals("")) { - if(isOnRequest) { + if (isOnRequest) { try { Thread.sleep(bridgeSettings.getButtonsleep()); } catch (InterruptedException e) { // ignore } } - responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, targetBriInc, colorData); + responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, + targetBriInc, colorData); } else { - log.info("Dim url not available for state change, lightId: " + lightId + ", userId: " + userId + ", from IP: " - + ipAddress + ", body: " + body); + log.info("Dim url not available for state change, lightId: " + lightId + ", userId: " + userId + + ", from IP: " + ipAddress + ", body: " + body); } } if (isColorRequest) { + if (bridgeSettings.isTracestate()) + log.info("Tracestate: Calling color as requested. With " + colorData); + log.debug("Calling color as requested."); url = device.getColorUrl(); // code for backwards compatibility - if(device.getMapType() != null && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { - if(url == null) + if (device.getMapType() != null + && device.getMapType().equalsIgnoreCase(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { + if (url == null) url = device.getOnUrl(); } if (url != null && !url.equals("")) { - if((isOnRequest && !isDimRequest) || isDimRequest) { + if ((isOnRequest && !isDimRequest) || isDimRequest) { try { Thread.sleep(bridgeSettings.getButtonsleep()); } catch (InterruptedException e) { // ignore } } - responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, targetBriInc, colorData); + responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, + targetBriInc, colorData); } else { - log.info("Color url not available for state change, lightId: " + lightId + ", userId: " + userId + ", from IP: " - + ipAddress + ", body: " + body); + log.info("Color url not available for state change, lightId: " + lightId + ", userId: " + userId + + ", from IP: " + ipAddress + ", body: " + body); } } - + if (responseString == null || !responseString.contains("[{\"error\":")) { - if(!device.isNoState()) { - responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, targetBriInc, colorData, device.isOffState()); + if (!device.isNoState()) { + responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, + targetBriInc, colorData, device.isOffState()); device.setDeviceState(state); } else { DeviceState dummyState = DeviceState.createDeviceState(device.isColorDevice()); - responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, dummyState, targetBri, targetBriInc, colorData, device.isOffState()); + responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, dummyState, targetBri, + targetBriInc, colorData, device.isOffState()); } } return responseString; - + } + private ColorData parseColorInfo(String body, StateChangeBody theStateChanges, DeviceState state, Integer targetBri, Integer targetBriInc) { + ColorData colorData = null; + List xy = null; + List xyInc = null; + Integer ct = null; + Integer ctInc = null; + HueSatBri anHSL = null; + Integer hue = null; + Integer sat = null; + Integer hueInc = null; + Integer satInc = null; + + if (body.contains("\"xy\"")) { + xy = theStateChanges.getXy(); + } + + if (body.contains("\"ct\"")) { + ct = theStateChanges.getCt(); + } + if (body.contains("\"hue\"")) { + hue = theStateChanges.getHue(); + } + if (body.contains("\"sat\"")) { + sat = theStateChanges.getSat(); + } + + if (body.contains("\"xy_inc\"")) { + xyInc = theStateChanges.getXy_inc(); + } + + if (body.contains("\"ct_inc\"")) { + ctInc = theStateChanges.getCt_inc(); + } + + if (body.contains("\"hue_inc\"")) { + hueInc = theStateChanges.getHue_inc(); + } + + if (body.contains("\"sat_inc\"")) { + satInc = theStateChanges.getSat_inc(); + } + + if (xy != null && xy.size() == 2) { + colorData = new ColorData(ColorData.ColorMode.XY, xy); + } else if (xyInc != null && xyInc.size() == 2) { + List current = state.getXy(); + current.set(0, current.get(0) + xyInc.get(0)); + current.set(1, current.get(1) + xyInc.get(1)); + colorData = new ColorData(ColorData.ColorMode.XY, current); + } else if (ct != null) { + colorData = new ColorData(ColorData.ColorMode.CT, ct); + } else if (ctInc != null) { + colorData = new ColorData(ColorData.ColorMode.CT, state.getCt() + ctInc); + } else if (hue != null || sat != null) { + anHSL = new HueSatBri(); + int bri = 0; + if(targetBriInc != null) { + bri = state.getBri() - targetBriInc; + if(bri < 0) + bri = 0; + } else if (targetBri != null) { + bri = targetBri; + } else { + bri = state.getBri(); + } + anHSL.setBri(bri); + if(hue != null) + anHSL.setHue(hue); + else + anHSL.setHue(state.getHue()); + + if(sat != null) + anHSL.setSat(sat); + else + anHSL.setSat(state.getSat()); + log.info("hue/sat request - " + anHSL); + colorData = new ColorData(ColorData.ColorMode.HS, anHSL); + } else if (hueInc != null || satInc != null) { + anHSL = new HueSatBri(); + int bri = 0; + if(targetBriInc != null) { + bri = state.getBri() - targetBriInc; + if(bri < 0) + bri = 0; + } else if (targetBri != null) { + bri = targetBri; + } else { + bri = state.getBri(); + } + anHSL.setBri(bri); + if(hueInc != null) + anHSL.setHue(state.getHue() - hueInc); + else + anHSL.setHue(state.getHue()); + + if(satInc != null) + anHSL.setSat(state.getSat() - satInc); + else + anHSL.setSat(state.getSat()); + log.info("hue/sat inc request - " + anHSL); + colorData = new ColorData(ColorData.ColorMode.HS, anHSL); + + } + return colorData; + } @SuppressWarnings("unchecked") - private String changeGroupState(String userId, String groupId, String body, String ipAddress, boolean fakeLightResponse) { + private String changeGroupState(String userId, String groupId, String body, String ipAddress, + boolean fakeLightResponse) { ColorData colorData = null; log.debug("PUT action to group " + groupId + " from " + ipAddress + " user " + userId + " with body " + body); HueError[] theErrors = null; - theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); + theErrors = bridgeSettingMaster.getBridgeSecurity().validateWhitelistUser(userId, null, + bridgeSettingMaster.getBridgeSecurity().isUseLinkButton()); if (theErrors == null) { - if(bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) + if (bridgeSettingMaster.getBridgeSecurity().isSettingsChanged()) bridgeSettingMaster.updateConfigFile(); GroupDescriptor group = null; @@ -1313,17 +1470,21 @@ public class HueMulator { DeviceState state = null; Map lights = null; if (groupId.equalsIgnoreCase("0")) { - lights = (Map)lightsListHandler(userId, ipAddress); + lights = (Map) lightsListHandler(userId, ipAddress); } else { group = groupRepository.findOne(groupId); if (group == null || group.isInactive()) { - return aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/groups/" + groupId, - "resource, /groups/" + groupId + ", not available", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson(HueErrorResponse + .createResponse("3", "/groups/" + groupId, + "resource, /groups/" + groupId + ", not available", null, null, null) + .getTheErrors(), HueError[].class); } else { if (fakeLightResponse) { - lights = repository.findAllByGroupWithState(group.getLights(), ipAddress, myHueHome, aGsonHandler, true); + lights = repository.findAllByGroupWithState(group.getLights(), ipAddress, myHueHome, + aGsonHandler, true); } else { - lights = repository.findAllByGroupWithState(group.getLights(), ipAddress, myHueHome, aGsonHandler); + lights = repository.findAllByGroupWithState(group.getLights(), ipAddress, myHueHome, + aGsonHandler); } } } @@ -1337,15 +1498,16 @@ public class HueMulator { } if (theStateChanges == null) { log.warn("Could not parse state change body. Light state not changed."); - return aGsonHandler.toJson(HueErrorResponse.createResponse("2", "/groups/" + groupId + "/action", - "Could not parse state change body.", null, null, null).getTheErrors(), HueError[].class); + return aGsonHandler.toJson( + HueErrorResponse.createResponse("2", "/groups/" + groupId + "/action", + "Could not parse state change body.", null, null, null).getTheErrors(), + HueError[].class); } if (group != null) { if (body.contains("\"bri_inc\"")) { targetBriInc = Integer.valueOf(theStateChanges.getBri_inc()); - } - else if (body.contains("\"bri\"")) { + } else if (body.contains("\"bri\"")) { targetBri = Integer.valueOf(theStateChanges.getBri()); } @@ -1353,9 +1515,8 @@ public class HueMulator { if (state == null) { state = DeviceState.createDeviceState(true); group.setAction(state); - } + } } - boolean turnOn = false; boolean turnOff = false; @@ -1369,7 +1530,8 @@ public class HueMulator { } } for (Map.Entry light : lights.entrySet()) { - log.debug("Processing light" + light.getKey() + ": " + turnOn + " " + turnOff + " " + light.getValue().getState().isOn()); + log.debug("Processing light" + light.getKey() + ": " + turnOn + " " + turnOff + " " + + light.getValue().getState().isOn()); // ignore on/off for devices that are already on/off if (turnOff && !light.getValue().getState().isOn()) continue; @@ -1377,34 +1539,40 @@ public class HueMulator { continue; changeState(userId, light.getKey(), body, ipAddress, fakeLightResponse); } - // construct success response: one success message per changed property, but not per light + // construct success response: one success message per changed property, but not + // per light if (group != null) { // if not group 0 - String response = formatSuccessHueResponse(theStateChanges, body, String.valueOf(Integer.parseInt(groupId) + 10000), - state, targetBri, targetBriInc, colorData, true); - group.setAction(state); - if (fakeLightResponse) { - return response; - } + String response = formatSuccessHueResponse(theStateChanges, body, + String.valueOf(Integer.parseInt(groupId) + 10000), state, targetBri, targetBriInc, + colorData, true); + group.setAction(state); + if (fakeLightResponse) { + return response; + } } String successString = "["; for (String pairStr : body.replaceAll("[{|}]", "").split(",\\s*\"")) { String[] pair = pairStr.split(":"); if (fakeLightResponse) { - successString += "{\"success\":{ \"/lights/" + String.valueOf(Integer.parseInt(groupId) + 10000) + "/state/" + pair[0].replaceAll("\"", "").trim() + "\": " + pair[1].trim() + "}},"; + successString += "{\"success\":{ \"/lights/" + String.valueOf(Integer.parseInt(groupId) + 10000) + + "/state/" + pair[0].replaceAll("\"", "").trim() + "\": " + pair[1].trim() + "}},"; } else { - successString += "{\"success\":{ \"address\": \"/groups/" + groupId + "/action/" + pair[0].replaceAll("\"", "").trim() + "\", \"value\": " + pair[1].trim() + "}},"; + successString += "{\"success\":{ \"address\": \"/groups/" + groupId + "/action/" + + pair[0].replaceAll("\"", "").trim() + "\", \"value\": " + pair[1].trim() + "}},"; } - + } - return (successString.length() == 1) ? "[]" : successString.substring(0, successString.length()-1) + "]"; + return (successString.length() == 1) ? "[]" + : successString.substring(0, successString.length() - 1) + "]"; } } return aGsonHandler.toJson(theErrors); } - - protected String callUrl(String url, DeviceDescriptor device, String userId, String lightId, String body, String ipAddress, boolean ignoreRequester, Integer targetBri, Integer targetBriInc, ColorData colorData) { + + protected String callUrl(String url, DeviceDescriptor device, String userId, String lightId, String body, + String ipAddress, boolean ignoreRequester, Integer targetBri, Integer targetBriInc, ColorData colorData) { String responseString = null; MultiCommandUtil aMultiUtil = new MultiCommandUtil(); aMultiUtil.setTheDelay(bridgeSettings.getButtonsleep()); @@ -1415,42 +1583,44 @@ public class HueMulator { if (url.startsWith("{\"item")) url = "[" + url + "]"; else { - if(url.startsWith("{")) + if (url.startsWith("{")) url = "[{\"item\":" + url + "}]"; else url = "[{\"item\":\"" + url + "\"}]"; } - } else if(!url.startsWith("[{\"item\"")) + } else if (!url.startsWith("[{\"item\"")) url = "[{\"item\":" + url + "}]"; log.debug("Decode Json for url items: " + url); CallItem[] callItems = null; try { callItems = aGsonHandler.fromJson(url, CallItem[].class); - } catch(JsonSyntaxException e) { - log.warn("Could not decode Json for url items: " + lightId + " for hue state change request: " + userId + " from " - + ipAddress + " body: " + body + " url items: " + url); + } catch (JsonSyntaxException e) { + log.warn("Could not decode Json for url items: " + lightId + " for hue state change request: " + userId + + " from " + ipAddress + " body: " + body + " url items: " + url); return aGsonHandler.toJson(HueErrorResponse.createResponse("3", "/lights/" + lightId, "Could decode json in request", "/lights/" + lightId, null, null).getTheErrors(), HueError[].class); } - + for (int i = 0; callItems != null && i < callItems.length; i++) { if (!ignoreRequester) { - if(!filterByRequester(device.getRequesterAddress(), ipAddress) || !filterByRequester(callItems[i].getFilterIPs(), ipAddress)) { - log.warn("filter for requester address not present in: (device)" + device.getRequesterAddress() + " OR then (item)" + callItems[i].getFilterIPs() + " with request ip of: " + ipAddress); + if (!filterByRequester(device.getRequesterAddress(), ipAddress) + || !filterByRequester(callItems[i].getFilterIPs(), ipAddress)) { + log.warn("filter for requester address not present in: (device)" + device.getRequesterAddress() + + " OR then (item)" + callItems[i].getFilterIPs() + " with request ip of: " + ipAddress); continue; - } + } } - + if (callItems[i].getCount() != null && callItems[i].getCount() > 0) aMultiUtil.setSetCount(callItems[i].getCount()); else aMultiUtil.setSetCount(1); // code for backwards compatibility - if((callItems[i].getType() == null || callItems[i].getType().trim().isEmpty())) { - if(validMapTypes.validateType(device.getMapType())) + if ((callItems[i].getType() == null || callItems[i].getType().trim().isEmpty())) { + if (validMapTypes.validateType(device.getMapType())) callItems[i].setType(device.getMapType().trim()); - else if(validMapTypes.validateType(device.getDeviceType())) + else if (validMapTypes.validateType(device.getDeviceType())) callItems[i].setType(device.getDeviceType().trim()); else callItems[i].setType(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex]); @@ -1471,13 +1641,14 @@ public class HueMulator { aMultiUtil.setTheDelay(aMultiUtil.getDelayDefault()); log.debug("Calling Home device handler for type : " + callItems[i].getType().trim()); - responseString = homeManager.findHome(callItems[i].getType().trim()).deviceHandler(callItems[i], aMultiUtil, lightId, device.getDeviceState().getBri(), targetBri, targetBriInc, colorData, device, body); - if(responseString != null && responseString.contains("{\"error\":")) { + responseString = homeManager.findHome(callItems[i].getType().trim()).deviceHandler(callItems[i], + aMultiUtil, lightId, device.getDeviceState().getBri(), targetBri, targetBriInc, colorData, + device, body); + if (responseString != null && responseString.contains("{\"error\":")) { x = aMultiUtil.getSetCount(); } } - } - else + } else log.warn("Call Items type is null <<<" + callItems[i] + ">>>"); } diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueSatBri.java b/src/main/java/com/bwssystems/HABridge/hue/HueSatBri.java new file mode 100644 index 0000000..ce60fc6 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/hue/HueSatBri.java @@ -0,0 +1,38 @@ +package com.bwssystems.HABridge.hue; + +public class HueSatBri { + int hue; + int sat; + int bri; + + public int getHue() { + return hue; + } + + public void setHue(int hue) { + this.hue = hue; + } + + public int getSat() { + return sat; + } + + public void setSat(int sat) { + this.sat = sat; + } + + public int getBri() { + return bri; + } + + public void setBri(int bri) { + this.bri = bri; + } + + public String toString() { + String formatString = new String(); + + formatString = "Hue: " + Integer.toString(hue) + ", Sat: " + Integer.toString(sat) + ", Bri: " + Integer.toString(bri); + return formatString; + } +} \ No newline at end of file diff --git a/src/main/resources/public/views/system.html b/src/main/resources/public/views/system.html index dfcdd72..eb4c8d6 100644 --- a/src/main/resources/public/views/system.html +++ b/src/main/resources/public/views/system.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • @@ -738,6 +739,73 @@ + + Mozilla IOT Names and IP Addresses + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameIPPortUsername (opt)Password (opt)Use SSLManage
    + Nest @@ -803,6 +871,12 @@ ng-model="bridge.settings.traceupnp" ng-true-value=true ng-false-value=false> {{bridge.settings.traceupnp}} + + + + + placeholder="An Mozilla IOT "> @@ -766,23 +766,20 @@ placeholder="8080"> + placeholder="Mozilla IOT username"> - + placeholder="Mozilla IOT password"> + ng-click="removeMozIottoSettings(moziot.name, moziot.ip)">Del + placeholder="A Mozilla IOT "> @@ -791,18 +788,15 @@ placeholder="8080"> + placeholder="Mozilla IOT username"> - + placeholder="Mozilla IOT password "> + ng-click="addMozIottoSettings(newmoziotname, newmoziotip, newmoziotport, newsmoziotusername, newmoziotpassword, newmoziotwebhook, newmoziotsecure)">Add
    Trace State Changes {{bridge.settings.tracestate}}
    UPNP Send Delay Date: Fri, 24 May 2019 15:22:34 -0500 Subject: [PATCH 20/52] Debugging MOzilla IOT impl --- .../bwssystems/HABridge/BridgeSettings.java | 10 +- .../HABridge/BridgeSettingsDescriptor.java | 36 ++- .../bwssystems/HABridge/DeviceMapTypes.java | 2 + .../com/bwssystems/HABridge/HomeManager.java | 7 +- .../devicemanagmeent/DeviceResource.java | 6 + .../HABridge/plugins/moziot/Actions.java | 8 + .../HABridge/plugins/moziot/Events.java | 8 + .../HABridge/plugins/moziot/JWT.java | 21 ++ .../HABridge/plugins/moziot/Level.java | 88 ++++++ .../HABridge/plugins/moziot/Link.java | 43 +++ .../plugins/moziot/MozIotCommand.java | 19 ++ .../HABridge/plugins/moziot/MozIotHome.java | 207 ++++++++++++++ .../plugins/moziot/MozIotInstance.java | 131 +++++++++ .../HABridge/plugins/moziot/MozillaThing.java | 154 +++++++++++ .../HABridge/plugins/moziot/On.java | 55 ++++ .../HABridge/plugins/moziot/Properties.java | 32 +++ .../HABridge/upnp/UpnpListener.java | 259 ++++++++++-------- src/main/resources/public/scripts/app.js | 185 ++++++++++++- .../public/views/broadlinkdevice.html | 1 + .../resources/public/views/configuration.html | 1 + .../public/views/domoticzdevice.html | 1 + .../resources/public/views/editdevice.html | 1 + .../resources/public/views/fhemdevice.html | 1 + .../resources/public/views/fibarodevice.html | 1 + .../resources/public/views/fibaroscene.html | 1 + .../resources/public/views/haldevice.html | 1 + .../public/views/harmonyactivity.html | 1 + .../resources/public/views/harmonydevice.html | 1 + .../resources/public/views/hassdevice.html | 1 + .../public/views/homewizarddevice.html | 1 + .../resources/public/views/huedevice.html | 1 + .../resources/public/views/lifxdevice.html | 1 + src/main/resources/public/views/logs.html | 1 + .../resources/public/views/moziotdevice.html | 151 ++++++++++ .../resources/public/views/mqttpublish.html | 1 + .../resources/public/views/nestactions.html | 1 + .../resources/public/views/openhabdevice.html | 1 + .../resources/public/views/somfydevice.html | 1 + src/main/resources/public/views/system.html | 28 +- .../resources/public/views/veradevice.html | 1 + .../resources/public/views/verascene.html | 1 + 41 files changed, 1319 insertions(+), 152 deletions(-) create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/Actions.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/Events.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/JWT.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/Level.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/Link.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommand.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/MozillaThing.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/On.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/Properties.java create mode 100644 src/main/resources/public/views/moziotdevice.html diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index 40396c5..2fe3326 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -160,7 +160,7 @@ public class BridgeSettings extends BackupHandler { } theBridgeSettings.setSomfyAddress(theSomfyList); - theBridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "true"))); + // theBridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "true"))); theBridgeSettings.setTraceupnp(Boolean.parseBoolean(System.getProperty("trace.upnp", "false"))); theBridgeSettings.setButtonsleep(Integer.parseInt(System.getProperty("button.sleep", Configuration.DEFAULT_BUTTON_SLEEP))); theBridgeSettings.setNestuser(System.getProperty("nest.user")); @@ -223,9 +223,13 @@ public class BridgeSettings extends BackupHandler { if(serverIpOverride != null) { theBridgeSettings.setWebaddress(serverIpOverride); theBridgeSettings.setUpnpConfigAddress(serverIpOverride); - } + } + + /* if(upnpStrictOverride != null) - theBridgeSettings.setUpnpStrict(Boolean.parseBoolean(upnpStrictOverride)); + theBridgeSettings.setUpnpStrict(Boolean.parseBoolean(upnpStrictOverride)); + */ + setupParams(Paths.get(theBridgeSettings.getConfigfile()), ".cfgbk", "habridge.config-"); bridgeSecurity.setSecurityData(theBridgeSettings.getSecurityData()); diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java index a72edb7..41b608e 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java @@ -90,9 +90,9 @@ public class BridgeSettingsDescriptor { @SerializedName("openhabaddress") @Expose private IpList openhabaddress; - @SerializedName("moziotgateway") + @SerializedName("moziotaddress") @Expose - private IpList moziotgateway; + private IpList moziotaddress; @SerializedName("hubversion") @Expose private String hubversion; @@ -120,6 +120,9 @@ public class BridgeSettingsDescriptor { @SerializedName("tracestate") @Expose private boolean tracestate; + @SerializedName("upnporiginal") + @Expose + private boolean upnporiginal; // @SerializedName("activeloggers") // @Expose // private List activeloggers; @@ -142,11 +145,11 @@ public class BridgeSettingsDescriptor { // Deprecated settings private String haltoken; - private boolean upnpstrict; + // private boolean upnpstrict; public BridgeSettingsDescriptor() { super(); - this.upnpstrict = true; + // this.upnpstrict = true; this.useupnpiface = false; this.userooms = false; this.traceupnp = false; @@ -175,6 +178,7 @@ public class BridgeSettingsDescriptor { this.upnpsenddelay = Configuration.UPNP_SEND_DELAY; this.broadlinkconfigured = false; this.tracestate = false; + this.upnporiginal = false; } public String getUpnpConfigAddress() { @@ -280,7 +284,7 @@ public class BridgeSettingsDescriptor { public void setHarmonyAddress(IpList harmonyaddress) { this.harmonyaddress = harmonyaddress; } - +/* public boolean isUpnpStrict() { return upnpstrict; } @@ -288,7 +292,7 @@ public class BridgeSettingsDescriptor { public void setUpnpStrict(boolean upnpStrict) { this.upnpstrict = upnpStrict; } - +*/ public boolean isTraceupnp() { return traceupnp; } @@ -753,19 +757,19 @@ public class BridgeSettingsDescriptor { this.tracestate = tracestate; } - public IpList getMoziotgateway() { - return moziotgateway; + public IpList getMoziotaddress() { + return moziotaddress; } - public void setMoziotgateway(IpList moziotgateway) { - this.moziotgateway = moziotgateway; + public void setMoziotgaddress(IpList moziotgateway) { + this.moziotaddress = moziotgateway; } public Boolean isValidMozIot() { - if (this.getMoziotgateway() == null || this.getMoziotgateway().getDevices().size() <= 0) + if (this.getMoziotaddress() == null || this.getMoziotaddress().getDevices().size() <= 0) return false; - List devicesList = this.getMoziotgateway().getDevices(); + List devicesList = this.getMoziotaddress().getDevices(); if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) return false; @@ -779,4 +783,12 @@ public class BridgeSettingsDescriptor { public void setMoziotconfigured(boolean moziotconfigured) { this.moziotconfigured = moziotconfigured; } + + public boolean isUpnporiginal() { + return upnporiginal; + } + + public void setUpnporiginal(boolean upnporiginal) { + this.upnporiginal = upnporiginal; + } } diff --git a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java index 24f8f5f..9fc09ad 100644 --- a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java +++ b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java @@ -32,6 +32,7 @@ public class DeviceMapTypes { public final static String[] SOMFY_DEVICE = { "somfyDevice", "Somfy Device"}; public final static String[] LIFX_DEVICE = { "lifxDevice", "LIFX Device"}; public final static String[] OPENHAB_DEVICE = { "openhabDevice", "OpenHAB Device"}; + public final static String[] MOZIOT_DEVICE = { "moziotDevice", "Mozilla IOT Device"}; public final static String[] FHEM_DEVICE = { "fhemDevice", "FHEM Device"}; public final static String[] BROADLINK_DEVICE = { "broadlinkDevice", "Broadlink Device"}; @@ -67,6 +68,7 @@ public class DeviceMapTypes { deviceMapTypes.add(FIBARO_SCENE); deviceMapTypes.add(SOMFY_DEVICE); deviceMapTypes.add(OPENHAB_DEVICE); + deviceMapTypes.add(MOZIOT_DEVICE); deviceMapTypes.add(FHEM_DEVICE); deviceMapTypes.add(BROADLINK_DEVICE); } diff --git a/src/main/java/com/bwssystems/HABridge/HomeManager.java b/src/main/java/com/bwssystems/HABridge/HomeManager.java index 30d7b17..a9e56fa 100644 --- a/src/main/java/com/bwssystems/HABridge/HomeManager.java +++ b/src/main/java/com/bwssystems/HABridge/HomeManager.java @@ -20,6 +20,7 @@ import com.bwssystems.HABridge.plugins.homewizard.HomeWizardHome; import com.bwssystems.HABridge.plugins.http.HTTPHome; import com.bwssystems.HABridge.plugins.hue.HueHome; import com.bwssystems.HABridge.plugins.lifx.LifxHome; +import com.bwssystems.HABridge.plugins.moziot.MozIotHome; import com.bwssystems.HABridge.plugins.mqtt.MQTTHome; import com.bwssystems.HABridge.plugins.openhab.OpenHABHome; import com.bwssystems.HABridge.plugins.somfy.SomfyHome; @@ -120,7 +121,11 @@ public class HomeManager { aHome = new OpenHABHome(bridgeSettings); resourceList.put(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex], aHome); homeList.put(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex], aHome); - //setup the OpenHAB configuration if available + //setup the Mozilla IOT configuration if available + aHome = new MozIotHome(bridgeSettings); + resourceList.put(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex], aHome); + homeList.put(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex], aHome); + //setup the FHEM configuration if available aHome = new FHEMHome(bridgeSettings); resourceList.put(DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex], aHome); homeList.put(DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex], aHome); diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index 6b2e14f..bad312f 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -321,6 +321,12 @@ public class DeviceResource { return homeManager.findResource(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex]); }, new JsonTransformer()); + get (API_CONTEXT + "/moziot/devices", "application/json", (request, response) -> { + log.debug("Get MOzilla IOT devices"); + response.status(HttpStatus.SC_OK); + return homeManager.findResource(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex]); + }, new JsonTransformer()); + get (API_CONTEXT + "/fhem/devices", "application/json", (request, response) -> { log.debug("Get FHEM devices"); response.status(HttpStatus.SC_OK); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/Actions.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Actions.java new file mode 100644 index 0000000..6c0b84b --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Actions.java @@ -0,0 +1,8 @@ + +package com.bwssystems.HABridge.plugins.moziot; + + +public class Actions { + + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/Events.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Events.java new file mode 100644 index 0000000..4a4a5df --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Events.java @@ -0,0 +1,8 @@ + +package com.bwssystems.HABridge.plugins.moziot; + + +public class Events { + + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/JWT.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/JWT.java new file mode 100644 index 0000000..e399897 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/JWT.java @@ -0,0 +1,21 @@ + +package com.bwssystems.HABridge.plugins.moziot; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class JWT { + + @SerializedName("jwt") + @Expose + private String jwt; + + public String getJwt() { + return jwt; + } + + public void setJwt(String jwt) { + this.jwt = jwt; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/Level.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Level.java new file mode 100644 index 0000000..9357051 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Level.java @@ -0,0 +1,88 @@ + +package com.bwssystems.HABridge.plugins.moziot; + +import java.util.List; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Level { + + @SerializedName("title") + @Expose + private String title; + @SerializedName("type") + @Expose + private String type; + @SerializedName("@type") + @Expose + private String attype; + @SerializedName("unit") + @Expose + private String unit; + @SerializedName("minimum") + @Expose + private Integer minimum; + @SerializedName("maximum") + @Expose + private Integer maximum; + @SerializedName("links") + @Expose + private List links = null; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getAttype() { + return attype; + } + + public void setAttype(String attype) { + this.attype = attype; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public Integer getMinimum() { + return minimum; + } + + public void setMinimum(Integer minimum) { + this.minimum = minimum; + } + + public Integer getMaximum() { + return maximum; + } + + public void setMaximum(Integer maximum) { + this.maximum = maximum; + } + + public List getLinks() { + return links; + } + + public void setLinks(List links) { + this.links = links; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/Link.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Link.java new file mode 100644 index 0000000..ed9ae99 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Link.java @@ -0,0 +1,43 @@ + +package com.bwssystems.HABridge.plugins.moziot; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Link { + + @SerializedName("rel") + @Expose + private String rel; + @SerializedName("href") + @Expose + private String href; + @SerializedName("mediaType") + @Expose + private String mediaType; + + public String getRel() { + return rel; + } + + public void setRel(String rel) { + this.rel = rel; + } + + public String getHref() { + return href; + } + + public void setHref(String href) { + this.href = href; + } + + public String getMediaType() { + return mediaType; + } + + public void setMediaType(String mediaType) { + this.mediaType = mediaType; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommand.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommand.java new file mode 100644 index 0000000..acb78fe --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommand.java @@ -0,0 +1,19 @@ +package com.bwssystems.HABridge.plugins.moziot; + +public class MozIotCommand { + private String url; + private String command; + public String getUrl() { + return url; + } + public void setUrl(String url) { + this.url = url; + } + public String getCommand() { + return command; + } + public void setCommand(String command) { + this.command = command; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java new file mode 100644 index 0000000..a351be6 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java @@ -0,0 +1,207 @@ +package com.bwssystems.HABridge.plugins.moziot; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bwssystems.HABridge.BridgeSettings; +import com.bwssystems.HABridge.Home; +import com.bwssystems.HABridge.NamedIP; +import com.bwssystems.HABridge.api.CallItem; +import com.bwssystems.HABridge.api.hue.HueError; +import com.bwssystems.HABridge.api.hue.HueErrorResponse; +import com.bwssystems.HABridge.dao.DeviceDescriptor; +import com.bwssystems.HABridge.hue.BrightnessDecode; +import com.bwssystems.HABridge.hue.ColorData; +import com.bwssystems.HABridge.hue.ColorDecode; +import com.bwssystems.HABridge.hue.DeviceDataDecode; +import com.bwssystems.HABridge.hue.MultiCommandUtil; +import com.bwssystems.HABridge.hue.TimeDecode; +import com.bwssystems.HABridge.plugins.http.HTTPHandler; +import com.bwssystems.HABridge.plugins.http.HTTPHome; +import com.google.gson.Gson; + +public class MozIotHome implements Home { + private static final Logger log = LoggerFactory.getLogger(MozIotHome.class); + private Map moziotMap; + private Boolean validMoziot; + private HTTPHandler httpClient; + private boolean closed; + + public MozIotHome(BridgeSettings bridgeSettings) { + super(); + closed = true; + createHome(bridgeSettings); + closed = false; + } + + @Override + public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, + Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) { + + String theUrl = anItem.getItem().getAsString(); + String responseString = null; + + if(theUrl != null && !theUrl.isEmpty()) { + MozIotCommand theCommand = null; + try { + theCommand = new Gson().fromJson(theUrl, MozIotCommand.class); + } catch(Exception e) { + log.warn("Cannot parse command to Mozilla IOT <<<" + theUrl + ">>>", e); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + + lightId + "state", null, null).getTheErrors(), HueError[].class); + return responseString; + } + String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("://") + 3); + String hostPortion = intermediate.substring(0, intermediate.indexOf('/')); + String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1); + String hostAddr = null; + if (hostPortion.contains(":")) { + hostAddr = hostPortion.substring(0, intermediate.indexOf(':')); + } else + hostAddr = hostPortion; + MozIotInstance theHandler = findHandlerByAddress(hostAddr); + if(theHandler != null) { + String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, + intensity, targetBri, targetBriInc, false); + if (colorData != null) { + anUrl = ColorDecode.replaceColorData(anUrl, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false); + } + anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device); + anUrl = TimeDecode.replaceTimeValue(anUrl); + + String aCommand = null; + if(theCommand.getCommand() != null && !theCommand.getCommand().isEmpty()) { + aCommand = BrightnessDecode.calculateReplaceIntensityValue(theCommand.getCommand(), + intensity, targetBri, targetBriInc, false); + if (colorData != null) { + aCommand = ColorDecode.replaceColorData(aCommand, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false); + } + aCommand = DeviceDataDecode.replaceDeviceData(aCommand, device); + aCommand = TimeDecode.replaceTimeValue(aCommand); + } + try { + boolean success = theHandler.callCommand(anUrl, aCommand, httpClient); + if(!success) { + log.warn("Comand had error to Mozilla IOT"); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + + lightId + "state", null, null).getTheErrors(), HueError[].class); + } + } catch (Exception e) { + log.warn("Cannot send comand to Mozilla IOT", e); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + + lightId + "state", null, null).getTheErrors(), HueError[].class); + } + } else { + log.warn("Mozilla IOT Call could not complete, no address found: " + theUrl); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + + lightId + "state", null, null).getTheErrors(), HueError[].class); + } + } else { + log.warn("Mozilla IOT Call to be presented as http(s)://(:)/payload, format of request unknown: " + theUrl); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + + lightId + "state", null, null).getTheErrors(), HueError[].class); + } + return responseString; + } + + @Override + public Object getItems(String type) { + + if(!validMoziot) + return null; + log.debug("consolidating devices for Mozilla IOT"); + List theResponse = null; + Iterator keys = moziotMap.keySet().iterator(); + List deviceList = new ArrayList(); + while(keys.hasNext()) { + String key = keys.next(); + theResponse = moziotMap.get(key).getDevices(httpClient); + if(theResponse != null) + addMozIotDevices(deviceList, theResponse, key); + else { + log.warn("Cannot get devices for Mozilla IOT with name: " + key + ", skipping this Mozilla IOT."); + continue; + } + } + return deviceList; + } + + private Boolean addMozIotDevices(List theDeviceList, List theSourceList, String theKey) { + Iterator devices = theSourceList.iterator(); + while(devices.hasNext()) { + MozillaThing theDevice = devices.next(); + theDeviceList.add(theDevice); + } + return true; + } + + @Override + public Home createHome(BridgeSettings bridgeSettings) { + moziotMap = null; + validMoziot = bridgeSettings.getBridgeSettingsDescriptor().isValidMozIot(); + log.info("Mozilla IOT Home created." + (validMoziot ? "" : " No Mozilla IOTs configured.")); + if(validMoziot) { + moziotMap = new HashMap(); + httpClient = HTTPHome.getHandler(); + Iterator theList = bridgeSettings.getBridgeSettingsDescriptor().getMoziotaddress().getDevices().iterator(); + while(theList.hasNext() && validMoziot) { + NamedIP aMoziot = theList.next(); + try { + moziotMap.put(aMoziot.getName(), new MozIotInstance(aMoziot, httpClient)); + } catch (Exception e) { + log.error("Cannot get Mozilla IOT (" + aMoziot.getName() + ") setup, Exiting with message: " + e.getMessage(), e); + validMoziot = false; + } + } + } + return this; + } + + private MozIotInstance findHandlerByAddress(String hostAddress) { + MozIotInstance aHandler = null; + boolean found = false; + Iterator keys = moziotMap.keySet().iterator(); + while(keys.hasNext()) { + String key = keys.next(); + aHandler = moziotMap.get(key); + if(aHandler != null && aHandler.getMozIotIP().getIp().equals(hostAddress)) { + found = true; + break; + } + } + if(!found) + aHandler = null; + return aHandler; + } + + @Override + public void closeHome() { + log.debug("Closing Home."); + if(!closed && validMoziot) { + log.debug("Home is already closed...."); + return; + } + + if(httpClient != null) + httpClient.closeHandler(); + + moziotMap = null; + closed = true; + } + + @Override + public void refresh() { + // noop + } +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java new file mode 100644 index 0000000..b6de7b5 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java @@ -0,0 +1,131 @@ +package com.bwssystems.HABridge.plugins.moziot; + +import java.util.ArrayList; +import java.util.List; + +import com.bwssystems.HABridge.NamedIP; +import com.bwssystems.HABridge.api.NameValue; +import com.bwssystems.HABridge.plugins.http.HTTPHandler; +import com.google.gson.Gson; + +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpPost; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MozIotInstance { + private static final Logger log = LoggerFactory.getLogger(MozIotInstance.class); + private JWT moziotToken; + private NamedIP mozIotIP; + private NameValue[] headers; + + public MozIotInstance(NamedIP theNamedIp, HTTPHandler httpClient) { + mozIotIP = theNamedIp; + headers = null; + gatewayLogin(httpClient); + } + + public Boolean callCommand(String aCommand, String commandData, HTTPHandler httpClient) { + log.debug("calling Mozilla IOT: " + mozIotIP.getIp() + ":" + mozIotIP.getPort() + aCommand); + String aUrl = null; + + if (mozIotIP.getSecure() != null && mozIotIP.getSecure()) + aUrl = "https://"; + else + aUrl = "http://"; + headers = getAuthHeader(); + + aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/" + aCommand; + String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", commandData, headers); + log.debug("call Command return is: <" + theData + ">"); + if (theData.contains("error") || theData.contains("ERROR") || theData.contains("Error")) + return false; + return true; + } + + public List getDevices(HTTPHandler httpClient) { + log.debug("calling Mozilla IOT: " + mozIotIP.getIp() + ":" + mozIotIP.getPort()); + List deviceList = null; + MozillaThing[] theThings; + String theUrl = null; + String theData; + + if (mozIotIP.getSecure() != null && mozIotIP.getSecure()) + theUrl = "https://"; + else + theUrl = "http://"; + headers = getAuthHeader(); + + theUrl = theUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/things"; + theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers); + if (theData != null) { + log.debug("GET Mozilla IOT Devices - data: " + theData); + try { + theThings = new Gson().fromJson(theData, MozillaThing[].class); + if (theThings != null && theThings.length > 0) { + deviceList = new ArrayList(); + for (int i = 0; i < theThings.length; i++) { + deviceList.add(theThings[i]); + } + } + } catch (Exception e) { + log.warn("Cannot get an devices for Mozilla IOT " + mozIotIP.getName() + " Gson Parse Error."); + } + } + return deviceList; + } + + private NameValue[] getAuthHeader() { + if (headers == null) { + headers = new NameValue[1]; + headers[0] = new NameValue(); + headers[0].setName("Authorization"); + headers[0].setValue("Bearer " + moziotToken.getJwt()); + } + return headers; + } + + private void gatewayLogin(HTTPHandler httpClient) { + String aUrl = null; + + if (mozIotIP.getSecure() != null && mozIotIP.getSecure()) + aUrl = "https://"; + else + aUrl = "http://"; + + aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/login"; + String commandData = "{\"email\": \"" + mozIotIP.getUsername() + "\", \"password\":\"" + mozIotIP.getPassword() + + "\"}"; + String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, null); + if (theData != null) { + log.info("GET Mozilla login - data: " + theData); + try { + moziotToken = new Gson().fromJson(theData, JWT.class); + } catch (Exception e) { + log.warn("Cannot get login for Mozilla IOT " + mozIotIP.getName() + " Gson Parse Error."); + } + } else { + log.warn("Could not login " + mozIotIP.getName() + " error: <<<" + theData + ">>>"); + } + } + + public NamedIP getMozIotIP() { + return mozIotIP; + } + + public void setMozIotIP(NamedIP mozIotIP) { + this.mozIotIP = mozIotIP; + } + + protected void closeClient() { + } + + public JWT getMoziotToken() { + return moziotToken; + } + + public void setMoziotToken(JWT moziotToken) { + this.moziotToken = moziotToken; + } +} \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozillaThing.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozillaThing.java new file mode 100644 index 0000000..cc54c62 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozillaThing.java @@ -0,0 +1,154 @@ + +package com.bwssystems.HABridge.plugins.moziot; + +import java.util.List; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class MozillaThing { + + @SerializedName("name") + @Expose + private String name; + @SerializedName("type") + @Expose + private String type; + @SerializedName("@context") + @Expose + private String atcontext; + @SerializedName("@type") + @Expose + private List attype = null; + @SerializedName("description") + @Expose + private String description; + @SerializedName("href") + @Expose + private String href; + @SerializedName("properties") + @Expose + private Properties properties; + @SerializedName("actions") + @Expose + private Actions actions; + @SerializedName("events") + @Expose + private Events events; + @SerializedName("links") + @Expose + private List links = null; + @SerializedName("layoutIndex") + @Expose + private Integer layoutIndex; + @SerializedName("selectedCapability") + @Expose + private String selectedCapability; + @SerializedName("iconHref") + @Expose + private Object iconHref; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getAtcontext() { + return atcontext; + } + + public void setAtcontext(String atcontext) { + this.atcontext = atcontext; + } + + public List getAttype() { + return attype; + } + + public void setAttype(List attype) { + this.attype = attype; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getHref() { + return href; + } + + public void setHref(String href) { + this.href = href; + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + public Actions getActions() { + return actions; + } + + public void setActions(Actions actions) { + this.actions = actions; + } + + public Events getEvents() { + return events; + } + + public void setEvents(Events events) { + this.events = events; + } + + public List getLinks() { + return links; + } + + public void setLinks(List links) { + this.links = links; + } + + public Integer getLayoutIndex() { + return layoutIndex; + } + + public void setLayoutIndex(Integer layoutIndex) { + this.layoutIndex = layoutIndex; + } + + public String getSelectedCapability() { + return selectedCapability; + } + + public void setSelectedCapability(String selectedCapability) { + this.selectedCapability = selectedCapability; + } + + public Object getIconHref() { + return iconHref; + } + + public void setIconHref(Object iconHref) { + this.iconHref = iconHref; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/On.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/On.java new file mode 100644 index 0000000..ad0588b --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/On.java @@ -0,0 +1,55 @@ + +package com.bwssystems.HABridge.plugins.moziot; + +import java.util.List; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class On { + + @SerializedName("title") + @Expose + private String title; + @SerializedName("type") + @Expose + private String type; + @SerializedName("attype") + @Expose + private String attype; + @SerializedName("links") + @Expose + private List links = null; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getAttype() { + return attype; + } + + public void setAttype(String attype) { + this.attype = attype; + } + + public List getLinks() { + return links; + } + + public void setLinks(List links) { + this.links = links; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/Properties.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Properties.java new file mode 100644 index 0000000..4a9c21b --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/Properties.java @@ -0,0 +1,32 @@ + +package com.bwssystems.HABridge.plugins.moziot; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Properties { + + @SerializedName("on") + @Expose + private On on; + @SerializedName("level") + @Expose + private Level level; + + public On getOn() { + return on; + } + + public void setOn(On on) { + this.on = on; + } + + public Level getLevel() { + return level; + } + + public void setLevel(Level level) { + this.level = level; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java index 26e4925..c2039b9 100644 --- a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java +++ b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java @@ -17,13 +17,13 @@ import java.time.temporal.ChronoUnit; import java.util.Enumeration; import org.apache.http.conn.util.*; - public class UpnpListener { private Logger log = LoggerFactory.getLogger(UpnpListener.class); private MulticastSocket upnpMulticastSocket; private int httpServerPort; private String upnpConfigIP; - private boolean strict; + // private boolean strict; + private boolean upnpOriginal; private boolean traceupnp; private boolean useUpnpIface; private BridgeControlDescriptor bridgeControl; @@ -31,77 +31,67 @@ public class UpnpListener { private String bridgeSNUUID; private HuePublicConfig aHueConfig; private Integer theUpnpSendDelay; - private String responseTemplate1 = "HTTP/1.1 200 OK\r\n" + - "HOST: %s:%s\r\n" + - "CACHE-CONTROL: max-age=100\r\n" + - "EXT:\r\n" + - "LOCATION: http://%s:%s/description.xml\r\n" + - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + HueConstants.API_VERSION + "\r\n" + - "hue-bridgeid: %s\r\n" + - "ST: upnp:rootdevice\r\n" + - "USN: uuid:" + HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n"; - private String responseTemplate2 = "HTTP/1.1 200 OK\r\n" + - "HOST: %s:%s\r\n" + - "CACHE-CONTROL: max-age=100\r\n" + - "EXT:\r\n" + - "LOCATION: http://%s:%s/description.xml\r\n" + - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + HueConstants.API_VERSION + "\r\n" + - "hue-bridgeid: %s\r\n" + - "ST: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n" + - "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n"; - private String responseTemplate3 = "HTTP/1.1 200 OK\r\n" + - "HOST: %s:%s\r\n" + - "CACHE-CONTROL: max-age=100\r\n" + - "EXT:\r\n" + - "LOCATION: http://%s:%s/description.xml\r\n" + - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + HueConstants.API_VERSION + "\r\n" + - "hue-bridgeid: %s\r\n" + - "ST: urn:schemas-upnp-org:device:basic:1\r\n" + - "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n"; + private String responseTemplateOriginal = "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/6.0.5, UPnP/1.0, IpBridge/" + + HueConstants.API_VERSION + "\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n" + "USN: uuid:" + + HueConstants.UUID_PREFIX + "%s::urn:schemas-upnp-org:device:basic:1\r\n\r\n"; + private String responseTemplate1 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n" + + "EXT:\r\n" + "LOCATION: http://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + + HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: upnp:rootdevice\r\n" + "USN: uuid:" + + HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n"; + private String responseTemplate2 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n" + + "EXT:\r\n" + "LOCATION: http://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + + HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: uuid:" + HueConstants.UUID_PREFIX + + "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n"; + private String responseTemplate3 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n" + + "EXT:\r\n" + "LOCATION: http://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + + HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n" + + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n"; - private String notifyTemplate = "NOTIFY * HTTP/1.1\r\n" + - "HOST: %s:%s\r\n" + - "CACHE-CONTROL: max-age=100\r\n" + - "LOCATION: http://%s:%s/description.xml\r\n" + - "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + HueConstants.API_VERSION + "\r\n" + - "NTS: ssdp:alive\r\n" + - "hue-bridgeid: %s\r\n" + - "NT: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n" + - "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n"; + private String notifyTemplate = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n" + + "LOCATION: http://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + + HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n" + "NT: uuid:" + + HueConstants.UUID_PREFIX + "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n"; - public UpnpListener(BridgeSettingsDescriptor theSettings, BridgeControlDescriptor theControl, UDPDatagramSender aUdpDatagramSender) throws IOException { + public UpnpListener(BridgeSettingsDescriptor theSettings, BridgeControlDescriptor theControl, + UDPDatagramSender aUdpDatagramSender) throws IOException { super(); upnpMulticastSocket = null; httpServerPort = Integer.valueOf(theSettings.getServerPort()); upnpConfigIP = theSettings.getUpnpConfigAddress(); - strict = theSettings.isUpnpStrict(); + // strict = theSettings.isUpnpStrict(); + upnpOriginal = theSettings.isUpnporiginal(); traceupnp = theSettings.isTraceupnp(); useUpnpIface = theSettings.isUseupnpiface(); theUpnpSendDelay = theSettings.getUpnpsenddelay(); bridgeControl = theControl; - aHueConfig = HuePublicConfig.createConfig("temp", upnpConfigIP, HueConstants.HUB_VERSION, theSettings.getHubmac()); + aHueConfig = HuePublicConfig.createConfig("temp", upnpConfigIP, HueConstants.HUB_VERSION, + theSettings.getHubmac()); bridgeId = aHueConfig.getBridgeid(); bridgeSNUUID = aHueConfig.getSNUUIDFromMac(); try { - if(useUpnpIface) - upnpMulticastSocket = new MulticastSocket(new InetSocketAddress(upnpConfigIP, Configuration.UPNP_DISCOVERY_PORT)); + if (useUpnpIface) + upnpMulticastSocket = new MulticastSocket( + new InetSocketAddress(upnpConfigIP, Configuration.UPNP_DISCOVERY_PORT)); else - upnpMulticastSocket = new MulticastSocket(Configuration.UPNP_DISCOVERY_PORT); - } catch(IOException e){ - log.error("Upnp Discovery Port is in use, or restricted by admin (try running with sudo or admin privs): " + Configuration.UPNP_DISCOVERY_PORT + " with message: " + e.getMessage()); - throw(e); + upnpMulticastSocket = new MulticastSocket(Configuration.UPNP_DISCOVERY_PORT); + } catch (IOException e) { + log.error("Upnp Discovery Port is in use, or restricted by admin (try running with sudo or admin privs): " + + Configuration.UPNP_DISCOVERY_PORT + " with message: " + e.getMessage()); + throw (e); } - + } - public boolean startListening(){ + public boolean startListening() { log.info("UPNP Discovery Listener starting...."); Enumeration ifs = null; - InetSocketAddress socketAddress = new InetSocketAddress(Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT); + InetSocketAddress socketAddress = new InetSocketAddress(Configuration.UPNP_MULTICAST_ADDRESS, + Configuration.UPNP_DISCOVERY_PORT); try { - ifs = NetworkInterface.getNetworkInterfaces(); - } catch (SocketException e) { + ifs = NetworkInterface.getNetworkInterfaces(); + } catch (SocketException e) { log.error("Could not get network interfaces for this machine: " + e.getMessage()); return false; } @@ -116,14 +106,14 @@ public class UpnpListener { InetAddress addr = addrs.nextElement(); log.debug(name + " ... has addr " + addr); if (InetAddressUtils.isIPv4Address(addr.getHostAddress())) { - if(!useUpnpIface) { - if(traceupnp) + if (!useUpnpIface) { + if (traceupnp) log.info("Traceupnp: Interface: " + name + " valid usable IP address: " + addr); IPsPerNic++; - } - else if(addr.getHostAddress().equals(upnpConfigIP)) { - if(traceupnp) - log.info("Traceupnp: Interface: " + name + " matches upnp config address of IP address: " + addr); + } else if (addr.getHostAddress().equals(upnpConfigIP)) { + if (traceupnp) + log.info("Traceupnp: Interface: " + name + " matches upnp config address of IP address: " + + addr); IPsPerNic++; } } @@ -162,13 +152,14 @@ public class UpnpListener { try { sendUpnpResponse(packet); } catch (IOException e) { - log.warn("UpnpListener encountered an error sending upnp response packet. IP: " + packet.getAddress().getHostAddress() + " with message: " + e.getMessage()); + log.warn("UpnpListener encountered an error sending upnp response packet. IP: " + + packet.getAddress().getHostAddress() + " with message: " + e.getMessage()); log.debug("UpnpListener send upnp exception: ", e); } } current = Instant.now(); - if(ChronoUnit.MILLIS.between(previous, current) > Configuration.UPNP_NOTIFY_TIMEOUT) { + if (ChronoUnit.MILLIS.between(previous, current) > Configuration.UPNP_NOTIFY_TIMEOUT) { sendUpnpNotify(socketAddress.getAddress()); previous = Instant.now(); } @@ -203,32 +194,33 @@ public class UpnpListener { /** * ssdp discovery packet detection */ - protected boolean isSSDPDiscovery(DatagramPacket packet){ - //Only respond to discover request for strict upnp form + protected boolean isSSDPDiscovery(DatagramPacket packet) { + // Only respond to discover request for strict upnp form String packetString = new String(packet.getData(), 0, packet.getLength()); - if(packetString != null && packetString.startsWith("M-SEARCH * HTTP/1.1") && packetString.contains("\"ssdp:discover\"")){ - if(strict && (packetString.contains("ST: urn:schemas-upnp-org:device:basic:1") || packetString.contains("ST: upnp:rootdevice") || packetString.contains("ST: ssdp:all"))) - { - if(traceupnp) { - log.info("Traceupnp: SSDP M-SEARCH packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort()); - } - else - log.debug("SSDP M-SEARCH packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: <<<" + packetString + ">>>"); + if (packetString != null && packetString.startsWith("M-SEARCH * HTTP/1.1") + && packetString.contains("\"ssdp:discover\"")) { + if ((packetString.contains("ST: urn:schemas-upnp-org:device:basic:1") + || packetString.contains("ST: upnp:rootdevice") || packetString.contains("ST: ssdp:all"))) { + if (traceupnp) { + log.info("Traceupnp: SSDP M-SEARCH packet from " + packet.getAddress().getHostAddress() + ":" + + packet.getPort()); + } else + log.debug("SSDP M-SEARCH packet from " + packet.getAddress().getHostAddress() + ":" + + packet.getPort() + ", body: <<<" + packetString + ">>>"); return true; - } - else if (!strict) - { - if(traceupnp) { - log.info("Traceupnp: SSDP M-SEARCH packet (!strict) from " + packet.getAddress().getHostAddress() + ":" + packet.getPort()); - } - else - log.debug("SSDP M-SEARCH packet (!strict) from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: <<<" + packetString + ">>>"); - return true; - } - } - else { -// log.debug("isSSDPDiscovery found message to not be valid - strict: " + strict); -// log.debug("SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + packetString); + } /* + * else if (!strict) { if(traceupnp) { + * log.info("Traceupnp: SSDP M-SEARCH packet (!strict) from " + + * packet.getAddress().getHostAddress() + ":" + packet.getPort()); } else + * log.debug("SSDP M-SEARCH packet (!strict) from " + + * packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: <<<" + * + packetString + ">>>"); return true; } + */ + } else { + // log.debug("isSSDPDiscovery found message to not be valid - strict: " + + // strict); + log.debug("SSDP packet from " + packet.getAddress().getHostAddress() + ":" + packet.getPort() + ", body: " + + packetString); } return false; } @@ -245,65 +237,90 @@ public class UpnpListener { } catch (InterruptedException e) { // noop } - discoveryResponse = String.format(responseTemplate1, Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT, httpLocationAddress, httpServerPort, bridgeId, bridgeSNUUID); - if(traceupnp) { - log.info("Traceupnp: send upnp discovery template 1 with response address: " + httpLocationAddress + ":" + httpServerPort + " to address: " + requester + ":" + sourcePort); - } - else - log.debug("sendUpnpResponse to address: " + requester + ":" + sourcePort + " with discovery responseTemplate1 is <<<" + discoveryResponse + ">>>"); - sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); - try { - Thread.sleep(theUpnpSendDelay); - } catch (InterruptedException e) { - // noop - } - discoveryResponse = String.format(responseTemplate2, Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT, httpLocationAddress, httpServerPort, bridgeId, bridgeSNUUID, bridgeSNUUID); - if(traceupnp) { - log.info("Traceupnp: send upnp discovery template 2 with response address: " + httpLocationAddress + ":" + httpServerPort + " to address: " + requester + ":" + sourcePort); - } - else - log.debug("sendUpnpResponse to address: " + requester + ":" + sourcePort + " discovery responseTemplate2 is <<<" + discoveryResponse + ">>>"); - sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); + if (upnpOriginal) { + discoveryResponse = String.format(responseTemplateOriginal, Configuration.UPNP_MULTICAST_ADDRESS, + Configuration.UPNP_DISCOVERY_PORT, httpLocationAddress, httpServerPort, bridgeId, bridgeSNUUID); + if (traceupnp) { + log.info("Traceupnp: send upnp discovery template Original with response address: " + httpLocationAddress + ":" + + httpServerPort + " to address: " + requester + ":" + sourcePort); + } else + log.debug("sendUpnpResponse to address: " + requester + ":" + sourcePort + + " with discovery responseTemplateOriginal is <<<" + discoveryResponse + ">>>"); + sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); + } else { + discoveryResponse = String.format(responseTemplate1, Configuration.UPNP_MULTICAST_ADDRESS, + Configuration.UPNP_DISCOVERY_PORT, httpLocationAddress, httpServerPort, bridgeId, bridgeSNUUID); + if (traceupnp) { + log.info("Traceupnp: send upnp discovery template 1 with response address: " + httpLocationAddress + ":" + + httpServerPort + " to address: " + requester + ":" + sourcePort); + } else + log.debug("sendUpnpResponse to address: " + requester + ":" + sourcePort + + " with discovery responseTemplate1 is <<<" + discoveryResponse + ">>>"); + sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); - try { - Thread.sleep(theUpnpSendDelay); - } catch (InterruptedException e) { - // noop + try { + Thread.sleep(theUpnpSendDelay); + } catch (InterruptedException e) { + // noop + } + discoveryResponse = String.format(responseTemplate2, Configuration.UPNP_MULTICAST_ADDRESS, + Configuration.UPNP_DISCOVERY_PORT, httpLocationAddress, httpServerPort, bridgeId, bridgeSNUUID, + bridgeSNUUID); + if (traceupnp) { + log.info("Traceupnp: send upnp discovery template 2 with response address: " + httpLocationAddress + ":" + + httpServerPort + " to address: " + requester + ":" + sourcePort); + } else + log.debug("sendUpnpResponse to address: " + requester + ":" + sourcePort + + " discovery responseTemplate2 is <<<" + discoveryResponse + ">>>"); + sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); + + try { + Thread.sleep(theUpnpSendDelay); + } catch (InterruptedException e) { + // noop + } + discoveryResponse = String.format(responseTemplate3, Configuration.UPNP_MULTICAST_ADDRESS, + Configuration.UPNP_DISCOVERY_PORT, httpLocationAddress, httpServerPort, bridgeId, bridgeSNUUID); + if (traceupnp) { + log.info("Traceupnp: send upnp discovery template 3 with response address: " + httpLocationAddress + ":" + + httpServerPort + " to address: " + requester + ":" + sourcePort); + } else + log.debug("sendUpnpResponse to address: " + requester + ":" + sourcePort + + " discovery responseTemplate3 is <<<" + discoveryResponse + ">>>"); + sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); } - discoveryResponse = String.format(responseTemplate3, Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT, httpLocationAddress, httpServerPort, bridgeId, bridgeSNUUID); - if(traceupnp) { - log.info("Traceupnp: send upnp discovery template 3 with response address: " + httpLocationAddress + ":" + httpServerPort + " to address: " + requester + ":" + sourcePort); - } - else - log.debug("sendUpnpResponse to address: " + requester + ":" + sourcePort + " discovery responseTemplate3 is <<<" + discoveryResponse + ">>>"); - sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); } private void sendUDPResponse(byte[] udpMessage, InetAddress requester, int sourcePort) throws IOException { log.debug("Sending response string: <<<" + new String(udpMessage) + ">>>"); - if(upnpMulticastSocket == null) + if (upnpMulticastSocket == null) throw new IOException("Socket not initialized"); DatagramPacket response = new DatagramPacket(udpMessage, udpMessage.length, requester, sourcePort); upnpMulticastSocket.send(response); } - + protected void sendUpnpNotify(InetAddress aSocketAddress) { String notifyData = null; - notifyData = String.format(notifyTemplate, Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT, upnpConfigIP, httpServerPort, bridgeId, bridgeSNUUID, bridgeSNUUID); + notifyData = String.format(notifyTemplate, Configuration.UPNP_MULTICAST_ADDRESS, + Configuration.UPNP_DISCOVERY_PORT, upnpConfigIP, httpServerPort, bridgeId, bridgeSNUUID, bridgeSNUUID); log.debug("sendUpnpNotify notifyTemplate is <<<" + notifyData + ">>>"); - DatagramPacket notifyPacket = new DatagramPacket(notifyData.getBytes(), notifyData.length(), aSocketAddress, Configuration.UPNP_DISCOVERY_PORT); + DatagramPacket notifyPacket = new DatagramPacket(notifyData.getBytes(), notifyData.length(), aSocketAddress, + Configuration.UPNP_DISCOVERY_PORT); try { upnpMulticastSocket.send(notifyPacket); } catch (IOException e1) { - log.warn("UpnpListener encountered an error sending upnp notify packet. IP: " + notifyPacket.getAddress().getHostAddress() + " with message: " + e1.getMessage()); + log.warn("UpnpListener encountered an error sending upnp notify packet. IP: " + + notifyPacket.getAddress().getHostAddress() + " with message: " + e1.getMessage()); log.debug("UpnpListener send upnp notify exception: ", e1); } } // added by https://github.com/pvint - // Ruthlessly stolen from https://stackoverflow.com/questions/22045165/java-datagrampacket-receive-how-to-determine-local-ip-interface - // Try to get a source IP that makes sense for the requestor to contact for use in the LOCATION header in replies + // Ruthlessly stolen from + // https://stackoverflow.com/questions/22045165/java-datagrampacket-receive-how-to-determine-local-ip-interface + // Try to get a source IP that makes sense for the requestor to contact for use + // in the LOCATION header in replies private InetAddress getOutboundAddress(SocketAddress remoteAddress) throws SocketException { DatagramSocket sock = new DatagramSocket(); // connect is needed to bind the socket and retrieve the local address diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 2e5c28b..b9823f0 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -83,6 +83,10 @@ app.config (function ($locationProvider, $routeProvider) { templateUrl: 'views/openhabdevice.html', controller: 'OpenHABController', requiresAuthentication: true + }).when ('/moziotdevices', { + templateUrl: 'views/moziotdevice.html', + controller: 'MozIotController', + requiresAuthentication: true }).when ('/fhemdevices', { templateUrl: 'views/fhemdevice.html', controller: 'FhemController', @@ -159,7 +163,8 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n this.state = {base: "./api/devices", bridgelocation: ".", systemsbase: "./system", huebase: "./api", configs: [], backups: [], devices: [], device: {}, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showFibaro: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, - showHomeWizard: false, showDomoticz: false, showSomfy: false, showLifx: false, showOpenHAB: false, showFHEM: false, showBroadlink: false, habridgeversion: {}, viewDevId: "", queueDevId: "", securityInfo: {}, filterDevicesByIpAddress: null, + showHomeWizard: false, showDomoticz: false, showSomfy: false, showLifx: false, showOpenHAB: false, showMozIot: false, showFHEM: false, showBroadlink: false, habridgeversion: {}, + viewDevId: "", queueDevId: "", securityInfo: {}, filterDevicesByIpAddress: null, filterDevicesOnlyFiltered: false, filterDeviceType: null}; this.displayWarn = function(errorTitle, error) { @@ -575,6 +580,11 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n return; }; + this.updateShowMozIot = function () { + this.state.showMozIot = self.state.settings.moziotconfigured; + return; + }; + this.updateShowFhem = function () { this.state.showFHEM = self.state.settings.fhemconfigured; return; @@ -602,6 +612,7 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n self.updateShowSomfy(); self.updateShowLifx(); self.updateShowOpenHAB(); + self.updateShowMozIot(); self.updateShowFhem(); self.updateShowBroadlink(); }, @@ -927,6 +938,22 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n ); }; + this.viewMozIotDevices = function () { + if (!this.state.showMozIot) + return; + return $http.get(this.state.base + "/moziot/devices").then( + function (response) { + self.state.moziotdevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Get Mozilla IOT Devices Error: ", error); + } + ); + }; + this.viewFhemDevices = function () { if (!this.state.showFHEM) return; @@ -1740,6 +1767,26 @@ app.controller ('SystemController', function ($scope, $location, bridgeService, } }; + $scope.addMozIottoSettings = function (newmoziotname, newmoziotip, newmoziotport, newmoziotusername, newmoziotpassword, newmoziotsecure) { + if($scope.bridge.settings.moziotaddress === undefined || $scope.bridge.settings.moziotaddress === null) { + $scope.bridge.settings.moziotaddress = { devices: [] }; + } + var newmoziot = {name: newmoziotname, ip: newmoziotip, port: newmoziotport, username: newmoziotusername, password: newmoziotpassword, secure: newmoziotsecure }; + $scope.bridge.settings.moziotaddress.devices.push(newmoziot); + $scope.newmoziotname = null; + $scope.newmoziotip = null; + $scope.newmoziotport = "4443"; + $scope.newmoziotusername = null; + $scope.newmoziotpassword = null; + }; + $scope.removeMozIottoSettings = function (moziotname, moziotip) { + for(var i = $scope.bridge.settings.moziotaddress.devices.length - 1; i >= 0; i--) { + if($scope.bridge.settings.moziotaddress.devices[i].name === moziotname && $scope.bridge.settings.moziotaddress.devices[i].ip === moziotip) { + $scope.bridge.settings.moziotaddress.devices.splice(i, 1); + } + } + }; + $scope.addFhemtoSettings = function (newfhemname, newfhemip, newfhemport, newfhemusername, newfhempassword, newfhemwebhook, newfhemsecure) { if($scope.bridge.settings.fhemaddress === undefined || $scope.bridge.settings.fhemaddress === null) { $scope.bridge.settings.fhemaddress = { devices: [] }; @@ -3931,6 +3978,142 @@ app.controller('OpenHABController', function ($scope, $location, bridgeService, }; }); +app.controller('MozIotController', function ($scope, $location, bridgeService, ngDialog) { + $scope.bridge = bridgeService.state; + $scope.device = bridgeService.state.device; + $scope.device_dim_control = ""; + $scope.bulk = { devices: [] }; + $scope.selectAll = false; + bridgeService.viewMozIotDevices(); + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + $scope.buttonsVisible = false; + + $scope.clearDevice = function () { + bridgeService.clearDevice(); + $scope.device = bridgeService.state.device; + }; + + $scope.buildDeviceUrls = function (moziotdevice, dim_control, colordata, buildonly) { + var preCmd = moziotdevice.href + "/"; + onpayload = null; + offpayload = null; + dimpayload = null; + colorpayload = null; + if(moziotdevice.properties.on !== undefined) { + onpayload = "{\"url\":\"" + preCmd + "on\",\"command\":{\"on\":true}}"; + offpayload = "{\"url\":\"" + preCmd + "on\",\"command\":{\"on\":false}}"; + } + if(moziotdevice.properties.level !== undefined) { + dimpayload = "{\"url\":\"" + preCmd + "level\",\"command\":{\"level\":" + dim_control + "}}"; + } + if(moziotdevice.properties.color !== undefined) { + colorpayload = "{\"url\":\"" + preCmd + "color\",\"command\":\"{\"color\":" + colordata + "}}"; + } + + bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, moziotdevice.name + "-" + moziotdevice.type, moziotdevice.name, moziotdevice.name, moziotdevice.type, "moziotDevice", null, null); + $scope.device = bridgeService.state.device; + if (!buildonly) { + bridgeService.editNewDevice($scope.device); + $location.path('/editdevice'); + } + }; + + $scope.bulkAddDevices = function(dim_control) { + var devicesList = []; + $scope.clearDevice(); + for(var i = 0; i < $scope.bulk.devices.length; i++) { + for(var x = 0; x < bridgeService.state.moziotdevices.length; x++) { + if(bridgeService.state.moziotdevices[x].devicename === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.moziotdevices[x],dim_control, null, true); + devicesList[i] = { + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff + }; + $scope.clearDevice(); + } + } + } + bridgeService.bulkAddDevice(devicesList).then( + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHalDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding Mozilla IOT devices in bulk.", error); + } + ); + $scope.bulk = { devices: [] }; + $scope.selectAll = false; + }; + + $scope.toggleSelection = function toggleSelection(deviceId) { + var idx = $scope.bulk.devices.indexOf(deviceId); + + // is currently selected + if (idx > -1) { + $scope.bulk.devices.splice(idx, 1); + if($scope.bulk.devices.length === 0 && $scope.selectAll) + $scope.selectAll = false; + } + + // is newly selected + else { + $scope.bulk.devices.push(deviceId); + $scope.selectAll = true; + } + }; + + $scope.toggleSelectAll = function toggleSelectAll() { + if($scope.selectAll) { + $scope.selectAll = false; + $scope.bulk = { devices: [] }; + } + else { + $scope.selectAll = true; + for(var x = 0; x < bridgeService.state.moziotdevices.length; x++) { + if($scope.bulk.devices.indexOf(bridgeService.state.moziotdevices[x]) < 0) + $scope.bulk.devices.push(bridgeService.state.moziotdevices[x].devicename); + } + } + }; + + $scope.toggleButtons = function () { + $scope.buttonsVisible = !$scope.buttonsVisible; + if($scope.buttonsVisible) + $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; + else + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + }; + + $scope.deleteDevice = function (device) { + $scope.bridge.device = device; + ngDialog.open({ + template: 'deleteDialog', + controller: 'DeleteDialogCtrl', + className: 'ngdialog-theme-default' + }); + }; + + $scope.editDevice = function (device) { + bridgeService.editDevice(device); + $location.path('/editdevice'); + }; +}); + app.controller('FhemController', function ($scope, $location, bridgeService, ngDialog) { $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; diff --git a/src/main/resources/public/views/broadlinkdevice.html b/src/main/resources/public/views/broadlinkdevice.html index 2ae1206..f4ee90f 100644 --- a/src/main/resources/public/views/broadlinkdevice.html +++ b/src/main/resources/public/views/broadlinkdevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/configuration.html b/src/main/resources/public/views/configuration.html index 4e19e96..d351cac 100644 --- a/src/main/resources/public/views/configuration.html +++ b/src/main/resources/public/views/configuration.html @@ -20,6 +20,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/domoticzdevice.html b/src/main/resources/public/views/domoticzdevice.html index c68282e..c2d365f 100644 --- a/src/main/resources/public/views/domoticzdevice.html +++ b/src/main/resources/public/views/domoticzdevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/editdevice.html b/src/main/resources/public/views/editdevice.html index 37c715c..09a41cf 100644 --- a/src/main/resources/public/views/editdevice.html +++ b/src/main/resources/public/views/editdevice.html @@ -20,6 +20,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • diff --git a/src/main/resources/public/views/fhemdevice.html b/src/main/resources/public/views/fhemdevice.html index 9e7d8f0..61ac469 100644 --- a/src/main/resources/public/views/fhemdevice.html +++ b/src/main/resources/public/views/fhemdevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/fibarodevice.html b/src/main/resources/public/views/fibarodevice.html index cbe8cd7..da4d4ba 100644 --- a/src/main/resources/public/views/fibarodevice.html +++ b/src/main/resources/public/views/fibarodevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/fibaroscene.html b/src/main/resources/public/views/fibaroscene.html index cc41ce7..9913c3e 100644 --- a/src/main/resources/public/views/fibaroscene.html +++ b/src/main/resources/public/views/fibaroscene.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/haldevice.html b/src/main/resources/public/views/haldevice.html index 11a0a0d..d269a90 100644 --- a/src/main/resources/public/views/haldevice.html +++ b/src/main/resources/public/views/haldevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/harmonyactivity.html b/src/main/resources/public/views/harmonyactivity.html index eff91fc..bfd79c3 100644 --- a/src/main/resources/public/views/harmonyactivity.html +++ b/src/main/resources/public/views/harmonyactivity.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/harmonydevice.html b/src/main/resources/public/views/harmonydevice.html index 475477d..bef18ca 100644 --- a/src/main/resources/public/views/harmonydevice.html +++ b/src/main/resources/public/views/harmonydevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/hassdevice.html b/src/main/resources/public/views/hassdevice.html index 574609b..4144fbb 100644 --- a/src/main/resources/public/views/hassdevice.html +++ b/src/main/resources/public/views/hassdevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/homewizarddevice.html b/src/main/resources/public/views/homewizarddevice.html index 0096871..45df646 100644 --- a/src/main/resources/public/views/homewizarddevice.html +++ b/src/main/resources/public/views/homewizarddevice.html @@ -19,6 +19,7 @@
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/huedevice.html b/src/main/resources/public/views/huedevice.html index 7a992ae..f1fadd3 100644 --- a/src/main/resources/public/views/huedevice.html +++ b/src/main/resources/public/views/huedevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/lifxdevice.html b/src/main/resources/public/views/lifxdevice.html index 2230dd1..c3462cf 100644 --- a/src/main/resources/public/views/lifxdevice.html +++ b/src/main/resources/public/views/lifxdevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/logs.html b/src/main/resources/public/views/logs.html index fd051d4..8d043ba 100644 --- a/src/main/resources/public/views/logs.html +++ b/src/main/resources/public/views/logs.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/moziotdevice.html b/src/main/resources/public/views/moziotdevice.html new file mode 100644 index 0000000..7d35cf4 --- /dev/null +++ b/src/main/resources/public/views/moziotdevice.html @@ -0,0 +1,151 @@ + + +
    +
    +

    Mozilla show Device List + ({{bridge.moziotdevices.length}})

    +
    +
    +

    For any Mozilla IOT Device, use the build action buttons + to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then + you can modify the name to anything you want that will be the keyword + for the Echo or Google Home. Also, you can go back to any helper tab and click a build + action button to add another item for a multi-command. After you are + done in the edit tab, click the 'Add Bridge Device' to finish that selection + setup. The 'Already Configured Mozilla IOT Devices' list below will show what + is already setup for your Mozilla IOT.

    +

    + Also, use this select menu for which type of dim control you would + like to be generated: +

    +

    Use the check boxes by the names to use the bulk addition + feature. Select your items and dim control type if wanted, then click + bulk add below. Your items will be added with on and off or dim and + off if selected with the name of the device from the Mozilla IOT.

    + + + + + + + + + + + + + + + + + + + + +
    Row + NameTypeMozilla IOTColor ActionsBuild Actions
    {{$index+1}} + {{moziotdevice.name}}{{moziotdevice.type}}{{moziotdevice.name}} + + + +
    +
    + +
    +
    +
    +
    +

    + Already Configured OpenHAB Devices +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    RowNameCategoryMozilla IOTMap IdActions
    {{$index+1}}{{device.name}}{{device.deviceType}}{{device.targetDevice}}{{device.mapId}} +

    + + +

    +
    +
    +
    +
    + diff --git a/src/main/resources/public/views/mqttpublish.html b/src/main/resources/public/views/mqttpublish.html index 5ee77ad..4bcdac8 100644 --- a/src/main/resources/public/views/mqttpublish.html +++ b/src/main/resources/public/views/mqttpublish.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/nestactions.html b/src/main/resources/public/views/nestactions.html index 92355da..7ce237b 100644 --- a/src/main/resources/public/views/nestactions.html +++ b/src/main/resources/public/views/nestactions.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/openhabdevice.html b/src/main/resources/public/views/openhabdevice.html index 3b658b4..d7660d2 100644 --- a/src/main/resources/public/views/openhabdevice.html +++ b/src/main/resources/public/views/openhabdevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/somfydevice.html b/src/main/resources/public/views/somfydevice.html index 208555f..a0d99a9 100644 --- a/src/main/resources/public/views/somfydevice.html +++ b/src/main/resources/public/views/somfydevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/system.html b/src/main/resources/public/views/system.html index eb4c8d6..fd4d5f7 100644 --- a/src/main/resources/public/views/system.html +++ b/src/main/resources/public/views/system.html @@ -757,7 +757,7 @@
    @@ -865,6 +859,12 @@ ng-model="bridge.settings.numberoflogmessages" min="100" max="65535"> + + UPNP Original (simple version) + {{bridge.settings.upnporiginal}} + Trace UPNP Calls HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/verascene.html b/src/main/resources/public/views/verascene.html index 35644dc..37695ae 100644 --- a/src/main/resources/public/views/verascene.html +++ b/src/main/resources/public/views/verascene.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • Mozilla IOT Devices
  • Broadlink Devices
  • Add/Edit
  • From 2d3fac691bce44200b912f30aca69799e4132c1d Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Thu, 30 May 2019 15:45:35 -0500 Subject: [PATCH 21/52] Update state error messages Homes, update gateway login --- .../bwssystems/HABridge/hue/HueMulator.java | 37 +++++++++++++------ .../HABridge/plugins/NestBridge/NestHome.java | 4 +- .../plugins/broadlink/BroadlinkHome.java | 21 ++++++----- .../plugins/domoticz/DomoticzHome.java | 8 ++-- .../HABridge/plugins/exec/CommandHome.java | 4 +- .../HABridge/plugins/fhem/FHEMHome.java | 7 +++- .../HABridge/plugins/hal/HalHome.java | 4 +- .../HABridge/plugins/harmony/HarmonyHome.java | 8 ++-- .../HABridge/plugins/hass/HassHome.java | 4 +- .../plugins/homewizard/HomeWizardHome.java | 6 +-- .../HABridge/plugins/http/HTTPHome.java | 4 +- .../HABridge/plugins/hue/HueInfo.java | 2 +- .../HABridge/plugins/lifx/LifxHome.java | 4 +- .../HABridge/plugins/moziot/MozIotHome.java | 3 +- .../plugins/moziot/MozIotInstance.java | 11 +++++- .../HABridge/plugins/mqtt/MQTTHome.java | 2 +- .../HABridge/plugins/openhab/OpenHABHome.java | 7 +++- .../HABridge/plugins/somfy/SomfyHome.java | 6 +-- .../HABridge/upnp/UpnpListener.java | 14 +++++++ 19 files changed, 101 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 4b7de93..5350a96 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -1246,7 +1246,7 @@ public class HueMulator { if (isOnRequest) { if (bridgeSettings.isTracestate()) - log.info("Tracestate: Calling on-off as requested."); + log.info("Tracestate: Calling on-off as requested: " + theStateChanges.isOn()); log.debug("Calling on-off as requested."); if (theStateChanges.isOn()) { @@ -1265,6 +1265,9 @@ public class HueMulator { if (url != null && !url.equals("")) { responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, targetBriInc, colorData); + if (responseString != null && responseString.contains("[{\"error\":")) { + log.warn("On/Off Request failed with: " + responseString); + } } else { log.info("On/off url not available for state change, lightId: " + lightId + ", userId: " + userId + ", from IP: " + ipAddress + ", body: " + body); @@ -1273,7 +1276,7 @@ public class HueMulator { if (isDimRequest) { if (bridgeSettings.isTracestate()) - log.info("Tracestate: Calling dim as requested."); + log.info("Tracestate: Calling dim as requested: " + targetBri + ", inc: " + targetBriInc); log.debug("Calling dim as requested."); url = device.getDimUrl(); @@ -1295,6 +1298,9 @@ public class HueMulator { } responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, targetBriInc, colorData); + if (responseString != null && responseString.contains("[{\"error\":")) { + log.warn("Dim Request failed with: " + responseString); + } } else { log.info("Dim url not available for state change, lightId: " + lightId + ", userId: " + userId + ", from IP: " + ipAddress + ", body: " + body); @@ -1324,6 +1330,9 @@ public class HueMulator { } responseString = callUrl(url, device, userId, lightId, body, ipAddress, ignoreRequester, targetBri, targetBriInc, colorData); + if (responseString != null && responseString.contains("[{\"error\":")) { + log.warn("Color Request failed with: " + responseString); + } } else { log.info("Color url not available for state change, lightId: " + lightId + ", userId: " + userId + ", from IP: " + ipAddress + ", body: " + body); @@ -1346,7 +1355,8 @@ public class HueMulator { } - private ColorData parseColorInfo(String body, StateChangeBody theStateChanges, DeviceState state, Integer targetBri, Integer targetBriInc) { + private ColorData parseColorInfo(String body, StateChangeBody theStateChanges, DeviceState state, Integer targetBri, + Integer targetBriInc) { ColorData colorData = null; List xy = null; List xyInc = null; @@ -1402,9 +1412,9 @@ public class HueMulator { } else if (hue != null || sat != null) { anHSL = new HueSatBri(); int bri = 0; - if(targetBriInc != null) { + if (targetBriInc != null) { bri = state.getBri() - targetBriInc; - if(bri < 0) + if (bri < 0) bri = 0; } else if (targetBri != null) { bri = targetBri; @@ -1412,12 +1422,12 @@ public class HueMulator { bri = state.getBri(); } anHSL.setBri(bri); - if(hue != null) + if (hue != null) anHSL.setHue(hue); else anHSL.setHue(state.getHue()); - if(sat != null) + if (sat != null) anHSL.setSat(sat); else anHSL.setSat(state.getSat()); @@ -1426,9 +1436,9 @@ public class HueMulator { } else if (hueInc != null || satInc != null) { anHSL = new HueSatBri(); int bri = 0; - if(targetBriInc != null) { + if (targetBriInc != null) { bri = state.getBri() - targetBriInc; - if(bri < 0) + if (bri < 0) bri = 0; } else if (targetBri != null) { bri = targetBri; @@ -1436,12 +1446,12 @@ public class HueMulator { bri = state.getBri(); } anHSL.setBri(bri); - if(hueInc != null) + if (hueInc != null) anHSL.setHue(state.getHue() - hueInc); else anHSL.setHue(state.getHue()); - if(satInc != null) + if (satInc != null) anHSL.setSat(state.getSat() - satInc); else anHSL.setSat(state.getSat()); @@ -1591,6 +1601,8 @@ public class HueMulator { } else if (!url.startsWith("[{\"item\"")) url = "[{\"item\":" + url + "}]"; + if (bridgeSettings.isTracestate()) + log.info("Tracestate: Decode Json for url items: " + url); log.debug("Decode Json for url items: " + url); CallItem[] callItems = null; try { @@ -1639,7 +1651,8 @@ public class HueMulator { aMultiUtil.setTheDelay(callItems[i].getDelay()); else aMultiUtil.setTheDelay(aMultiUtil.getDelayDefault()); - + if (bridgeSettings.isTracestate()) + log.info("Tracestate: Calling Home device handler for type : " + callItems[i].getType().trim()); log.debug("Calling Home device handler for type : " + callItems[i].getType().trim()); responseString = homeManager.findHome(callItems[i].getType().trim()).deviceHandler(callItems[i], aMultiUtil, lightId, device.getDeviceState().getBri(), targetBri, targetBriInc, colorData, diff --git a/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java b/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java index 701fc4f..785f751 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java @@ -119,7 +119,7 @@ public class NestHome implements com.bwssystems.HABridge.Home { log.warn("Should not get here, no Nest available"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no Nest available\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_HOMEAWAY[DeviceMapTypes.typeIndex])) { NestInstruction homeAway = null; if(anItem.getItem().isJsonObject()) @@ -167,7 +167,7 @@ public class NestHome implements com.bwssystems.HABridge.Home { log.warn("no valid Nest control info: " + thermoSetting.getControl()); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"no valid Nest control info\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } } return responseString; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java index ddc46d0..76569a6 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java @@ -106,11 +106,14 @@ public class BroadlinkHome implements Home { log.warn("Should not get here, no Broadlinks configured"); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no LifxDevices configured\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { BroadlinkEntry broadlinkCommand = null; - broadlinkCommand = new Gson().fromJson(anItem.getItem().getAsString(), BroadlinkEntry.class); + if(anItem.getItem().isJsonObject()) + broadlinkCommand = new Gson().fromJson(anItem.getItem(), BroadlinkEntry.class); + else + broadlinkCommand = new Gson().fromJson(anItem.getItem().getAsString(), BroadlinkEntry.class); BLDevice theDevice = null; if(broadlinkMap != null && !broadlinkMap.isEmpty()) theDevice = broadlinkMap.get(broadlinkCommand.getId()); @@ -126,17 +129,17 @@ public class BroadlinkHome implements Home { log.warn("Could not initialize BroadlinkDevice device due to Mac (" + broadlinkCommand.getId() + ") format exception: " + e.getMessage()); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Could not initialize BroadlinkDevice device due to Mac format exception\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } catch (IOException e) { log.warn("Could not initialize BroadlinkDevice device due to IP Address (" + broadlinkCommand.getId() + ") exception: " + e.getMessage()); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Could not initialize BroadlinkDevice device due to IP Address exception\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } catch (Exception e) { log.warn("Could not initialize BroadlinkDevice device due to (" + broadlinkCommand.getId() + ") exception: " + e.getMessage()); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Could not initialize BroadlinkDevice device due to exception\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } if(broadlinkMap == null) @@ -154,7 +157,7 @@ public class BroadlinkHome implements Home { log.warn("Should not get here, no BroadlinkDevice not available"); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no Broadlinks available\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { log.debug("calling BroadlinkDevice: " + broadlinkCommand.getName()); try { @@ -163,7 +166,7 @@ public class BroadlinkHome implements Home { log.error("Call to " + broadlinkCommand.getId() + " device authorization failed."); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"" + broadlinkCommand.getId() + " device auth error.\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } } switch (theDevice.getDeviceType()) { @@ -235,7 +238,7 @@ public class BroadlinkHome implements Home { log.error("Call to " + broadlinkCommand.getId() + " with no data, noop"); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"" + broadlinkCommand.getId() + " could not call device without data.\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } break; @@ -244,7 +247,7 @@ public class BroadlinkHome implements Home { log.error("Call to " + broadlinkCommand.getId() + " device failed with exception: " + e.getMessage(), e); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"" + broadlinkCommand.getId() + " device call error.\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java index 1806b3c..57f2afb 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java @@ -128,25 +128,25 @@ public class DomoticzHome implements Home { log.warn("Call failed for Domoticz " + theHandler.getDomoticzAddress().getName() + " with status " + theDomoticzApiResponse.getStatus() + " for item " + theDomoticzApiResponse.getTitle()); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); } } catch (Exception e) { log.warn("Cannot interrpret result from call for Domoticz " + theHandler.getDomoticzAddress().getName() + " as response is not parsable."); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); } } else { log.warn("Domoticz Call could not complete, no address found: " + theUrl); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); } } else { log.warn("Domoticz Call to be presented as http(s)://(:)/payload, format of request unknown: " + theUrl); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); } return responseString; } 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 984a01c..26340d1 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java @@ -67,13 +67,13 @@ public class CommandHome implements Home { log.warn("Could not execute request: " + anItem + " with message: " + e.getMessage()); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId - + "state\"}}]"; + + "/state\"}}]"; } } else { log.warn("Could not execute request. Request is empty."); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId - + "state\"}}]"; + + "/state\"}}]"; } return responseString; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java b/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java index e9af62c..d2d514e 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java @@ -55,12 +55,15 @@ public class FHEMHome implements Home { if(theUrl != null && !theUrl.isEmpty()) { FHEMCommand theCommand = null; try { - theCommand = new Gson().fromJson(theUrl, FHEMCommand.class); + if(anItem.getItem().isJsonObject()) + theCommand = new Gson().fromJson(anItem.getItem(), FHEMCommand.class); + else + theCommand = new Gson().fromJson(anItem.getItem().getAsString(), FHEMCommand.class); } catch(Exception e) { log.warn("Cannot parse command to FHEM <<<" + theUrl + ">>>", e); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); return responseString; } String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("://") + 3); 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 3357e12..4c5a091 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java @@ -165,7 +165,7 @@ public class HalHome implements Home { log.warn("Error on calling hal to change device state: " + anUrl); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); } } } @@ -175,7 +175,7 @@ public class HalHome implements Home { 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); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); } return responseString; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java index 13bea4f..0ed07ce 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java @@ -187,7 +187,7 @@ public class HarmonyHome implements Home { log.warn("Should not get here, no harmony configured"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no harmony configured\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { if (anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_ACTIVITY[DeviceMapTypes.typeIndex])) { RunActivity anActivity = null; @@ -202,7 +202,7 @@ public class HarmonyHome implements Home { log.warn("Should not get here, no harmony hub available"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no harmony hub available\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { if (!myHarmony.startActivity(anActivity)) { if (resetHub(myHarmony)) { @@ -212,7 +212,7 @@ public class HarmonyHome implements Home { + ", please restart..."); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Could not communicate with harmony\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } } } @@ -265,7 +265,7 @@ public class HarmonyHome implements Home { + ", please restart..."); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Could not communicate with harmony\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java b/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java index e7208e7..292b32e 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java @@ -131,7 +131,7 @@ public class HassHome implements Home { log.warn("Should not get here, no HomeAssistant clients configured"); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no HomeAssistants configured\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { HassCommand hassCommand = null; @@ -146,7 +146,7 @@ public class HassHome implements Home { log.warn("Should not get here, no HomeAssistants available"); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no HiomeAssistant clients available\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { log.debug("calling HomeAssistant: " + hassCommand.getHassName() + " - " + hassCommand.getEntityId() + " - " + hassCommand.getState() + " - " + hassCommand.getBri()); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizardHome.java b/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizardHome.java index 641c11c..d13b9a8 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizardHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizardHome.java @@ -49,7 +49,7 @@ public class HomeWizardHome implements Home { log.warn("Should not get here, no HomeWizard smart plug available"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no HomeWizard smart plug available\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.HOMEWIZARD_DEVICE[DeviceMapTypes.typeIndex])) { @@ -62,7 +62,7 @@ public class HomeWizardHome implements Home { log.warn("Should not get here, no HomeWizard smart plug configured"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no HomeWizard smart plug configured\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { try { homeWizzardHandler.execApply(jsonToPost); @@ -70,7 +70,7 @@ public class HomeWizardHome implements Home { log.warn("Error posting request to HomeWizard smart plug"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId - + "\",\"description\": \"Error posting request to HomeWizard smart plug\", \"parameter\": \"/lights/" + lightId + "state\"}}]"; + + "\",\"description\": \"Error posting request to HomeWizard smart plug\", \"parameter\": \"/lights/" + lightId + "/state\"}}]"; } } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java index 4353ee1..0a70ee1 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java @@ -86,7 +86,7 @@ public class HTTPHome implements Home { log.warn("Error on calling url to change device state: " + anUrl); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); } if(isDevMode) @@ -95,7 +95,7 @@ public class HTTPHome implements Home { log.warn("HTTP Call to be presented as http(s)://(:)/payload, format of request unknown: " + theUrl); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); } return responseString; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hue/HueInfo.java b/src/main/java/com/bwssystems/HABridge/plugins/hue/HueInfo.java index 7c858d2..5ed3562 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hue/HueInfo.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hue/HueInfo.java @@ -159,7 +159,7 @@ public class HueInfo { log.warn("Error on calling Hue passthru to change device state: " + deviceId.getHueName()); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Error on calling HUE to change device state\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else if (responseString.contains("[{\"error\":")) { // if(responseString.contains("unauthorized user")) { // } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java index d2c4255..77dd83f 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java @@ -144,7 +144,7 @@ public class LifxHome implements Home { log.warn("Should not get here, no LifxDevice clients configured"); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no LifxDevices configured\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { LifxEntry lifxCommand = null; @@ -157,7 +157,7 @@ public class LifxHome implements Home { log.warn("Should not get here, no LifxDevices available"); theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no Lifx clients available\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { log.debug("calling LifxDevice: " + lifxCommand.getName()); if(theDevice.getType().equals(LifxDevice.LIGHT_TYPE)) { diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java index a351be6..0510adf 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java @@ -50,12 +50,13 @@ public class MozIotHome implements Home { if(theUrl != null && !theUrl.isEmpty()) { MozIotCommand theCommand = null; try { + theUrl = theUrl.replaceAll("^\"|\"$", ""); theCommand = new Gson().fromJson(theUrl, MozIotCommand.class); } catch(Exception e) { log.warn("Cannot parse command to Mozilla IOT <<<" + theUrl + ">>>", e); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); return responseString; } String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("://") + 3); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java index b6de7b5..cc93328 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java @@ -94,10 +94,17 @@ public class MozIotInstance { else aUrl = "http://"; + headers = new NameValue[2]; + headers[0] = new NameValue(); + headers[0].setName("Content-Type"); + headers[0].setValue("application/json"); + headers[1] = new NameValue(); + headers[1].setName("Accept"); + headers[1].setValue("application/json"); aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/login"; String commandData = "{\"email\": \"" + mozIotIP.getUsername() + "\", \"password\":\"" + mozIotIP.getPassword() + "\"}"; - String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, null); + String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, headers); if (theData != null) { log.info("GET Mozilla login - data: " + theData); try { @@ -108,6 +115,8 @@ public class MozIotInstance { } else { log.warn("Could not login " + mozIotIP.getName() + " error: <<<" + theData + ">>>"); } + + headers = null; } public NamedIP getMozIotIP() { diff --git a/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java b/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java index d9ae673..46fba41 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java @@ -128,7 +128,7 @@ public class MQTTHome implements Home { log.warn("Should not get here, no mqtt brokers configured"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no mqtt brokers configured\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } return responseString; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABHome.java b/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABHome.java index 2022bf6..be645f3 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABHome.java @@ -51,12 +51,15 @@ public class OpenHABHome implements Home { if(theUrl != null && !theUrl.isEmpty()) { OpenHABCommand theCommand = null; try { - theCommand = new Gson().fromJson(theUrl, OpenHABCommand.class); + if(anItem.getItem().isJsonObject()) + theCommand = new Gson().fromJson(anItem.getItem(), OpenHABCommand.class); + else + theCommand = new Gson().fromJson(anItem.getItem().getAsString(), OpenHABCommand.class); } catch(Exception e) { log.warn("Cannot parse command to OpenHAB <<<" + theUrl + ">>>", e); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + + lightId + "/state", null, null).getTheErrors(), HueError[].class); return responseString; } String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("://") + 3); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java index 8fee882..1ca4130 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java @@ -72,7 +72,7 @@ public class SomfyHome implements Home { log.warn("Should not get here, no somfy hub available"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no somfy hub available\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex])) { @@ -84,14 +84,14 @@ public class SomfyHome implements Home { log.warn("Should not get here, no Somfy configured"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + "\",\"description\": \"Should not get here, no somfy configured\", \"parameter\": \"/lights/" - + lightId + "state\"}}]"; + + lightId + "/state\"}}]"; } else { try { somfyHandler.execApply(jsonToPost); } catch (Exception e) { log.warn("Error posting request to Somfy"); responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId - + "\",\"description\": \"Error posting request to SomfyTahoma\", \"parameter\": \"/lights/" + lightId + "state\"}}]"; + + "\",\"description\": \"Error posting request to SomfyTahoma\", \"parameter\": \"/lights/" + lightId + "/state\"}}]"; } } diff --git a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java index c2039b9..3e637be 100644 --- a/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java +++ b/src/main/java/com/bwssystems/HABridge/upnp/UpnpListener.java @@ -249,6 +249,20 @@ public class UpnpListener { + " with discovery responseTemplateOriginal is <<<" + discoveryResponse + ">>>"); sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); } else { + discoveryResponse = String.format(responseTemplateOriginal, Configuration.UPNP_MULTICAST_ADDRESS, + Configuration.UPNP_DISCOVERY_PORT, httpLocationAddress, httpServerPort, bridgeId, bridgeSNUUID); + if (traceupnp) { + log.info("Traceupnp: send upnp discovery template Original with response address: " + httpLocationAddress + ":" + + httpServerPort + " to address: " + requester + ":" + sourcePort); + } else + log.debug("sendUpnpResponse to address: " + requester + ":" + sourcePort + + " with discovery responseTemplateOriginal is <<<" + discoveryResponse + ">>>"); + sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); + try { + Thread.sleep(theUpnpSendDelay); + } catch (InterruptedException e) { + // noop + } discoveryResponse = String.format(responseTemplate1, Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT, httpLocationAddress, httpServerPort, bridgeId, bridgeSNUUID); if (traceupnp) { From f266945b7e7d53c97a04ab9deada0e8ba35ce29e Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Fri, 31 May 2019 15:19:24 -0500 Subject: [PATCH 22/52] working on ssl calls --- .../HABridge/plugins/http/HTTPHandler.java | 58 ++++++++++------ .../HABridge/plugins/http/HttpClientPool.java | 67 ++++++++++++++++++- .../plugins/moziot/MozIotInstance.java | 2 + 3 files changed, 105 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java index b41bf51..00b0acc 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java @@ -5,6 +5,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; +import javax.net.ssl.SSLContext; + import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -23,37 +25,46 @@ import com.bwssystems.HABridge.api.NameValue; public class HTTPHandler { private static final Logger log = LoggerFactory.getLogger(HTTPHandler.class); private String callType; - + public HTTPHandler() { super(); callType = null; } - public HTTPHandler(String type) { super(); callType = type; } - // This function executes the url from the device repository against the // target as http or https as defined public String doHttpRequest(String url, String httpVerb, String contentType, String body, NameValue[] headers) { - log.debug("doHttpRequest with url <<<" + url + ">>>, verb: " + httpVerb + ", contentType: " + contentType + ", body <<<" + body + ">>>" ); - if(headers != null && headers.length > 0) - for(int i = 0; i < headers.length; i++) - log.debug("header index " + i + " name: <<<" + headers[i].getName() + ">>>, value: <<<" + headers[i].getValue() + ">>>"); HttpUriRequest request = null; String theContent = null; URI theURI = null; + boolean usingSSL = false; ContentType parsedContentType = null; StringEntity requestBody = null; + log.debug("doHttpRequest with url <<<" + url + ">>>, verb: " + httpVerb + ", contentType: " + contentType + + ", body <<<" + body + ">>>"); + if (headers != null && headers.length > 0) { + for (int i = 0; i < headers.length; i++) { + log.debug("header index " + i + " name: <<<" + headers[i].getName() + ">>>, value: <<<" + + headers[i].getValue() + ">>>"); + } + } + if (contentType != null && !contentType.trim().isEmpty()) { parsedContentType = ContentType.parse(contentType); if (body != null && body.length() > 0) requestBody = new StringEntity(body, parsedContentType); } + + if (url.startsWith("https:")) { + usingSSL = true; + } + try { theURI = new URI(url); } catch (URISyntaxException e1) { @@ -90,7 +101,11 @@ public class HTTPHandler { CloseableHttpResponse response = null; for (int retryCount = 0; retryCount < 2; retryCount++) { try { - response = HttpClientPool.getClient().execute(request); + if (usingSSL) { + response = HttpClientPool.getSSLClient().execute(request); + } else { + response = HttpClientPool.getClient().execute(request); + } log.debug((httpVerb == null ? "GET" : httpVerb) + " execute (" + retryCount + ") on URL responded: " + response.getStatusLine().getStatusCode()); if (response != null && response.getEntity() != null) { @@ -106,22 +121,27 @@ public class HTTPHandler { // ignore // content } catch (Exception e) { - log.debug("Error ocurred in handling response entity after successful call, still responding success. " - + e.getMessage(), e); + log.debug( + "Error ocurred in handling response entity after successful call, still responding success. " + + e.getMessage(), + e); } } - if (response != null && response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300) { - if(theContent == null) + if (response != null && response.getStatusLine().getStatusCode() >= 200 + && response.getStatusLine().getStatusCode() < 300) { + if (theContent == null) theContent = ""; log.debug("Successfull response - The http response is <<<" + theContent + ">>>"); retryCount = 2; - } else if (DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex].equals(callType) && response.getStatusLine().getStatusCode() == 302) { - if(theContent == null) + } else if (DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex].equals(callType) + && response.getStatusLine().getStatusCode() == 302) { + if (theContent == null) theContent = ""; log.debug("Successfull response - The http response is <<<" + theContent + ">>>"); retryCount = 2; } else if (response != null) { - log.warn("HTTP response code was not an expected successful response of between 200 - 299, the code was: " + log.warn( + "HTTP response code was not an expected successful response of between 200 - 299, the code was: " + response.getStatusLine() + " with the content of <<<" + theContent + ">>>"); if (response.getStatusLine().getStatusCode() == 504) { log.warn("HTTP response code was 504, retrying..."); @@ -130,15 +150,15 @@ public class HTTPHandler { } else retryCount = 2; } - + } catch (ClientProtocolException e) { log.warn("Client Protocol Exception received, retyring...."); - }catch (IOException e) { + } catch (IOException e) { log.warn("Error calling out to HA gateway: IOException in log: " + e.getMessage()); retryCount = 2; } - if(retryCount < 2) { + if (retryCount < 2) { theContent = null; try { Thread.sleep(1000); @@ -149,11 +169,11 @@ public class HTTPHandler { } return theContent; } + public void setCallType(String callType) { this.callType = callType; } - public void closeHandler() { } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HttpClientPool.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HttpClientPool.java index 022d29d..b1790f2 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HttpClientPool.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HttpClientPool.java @@ -4,10 +4,22 @@ import java.io.IOException; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLContext; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustStrategy; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,9 +43,52 @@ public final class HttpClientPool { // Increase default max connection per route to 20 cm.setDefaultMaxPerRoute(20); // Build the client. - threadSafeClient = HttpClients.custom() - .setConnectionManager(cm) - .build(); + threadSafeClient = HttpClients.custom().setConnectionManager(cm).build(); + // Start up an eviction thread. + monitor = new IdleConnectionMonitorThread(cm); + // Don't stop quitting. + monitor.setDaemon(true); + monitor.start(); + } + + public CloseableHttpClient get() { + return threadSafeClient; + } + + } + + // Single-element enum to implement Singleton. + private static enum SingletonSSL { + // Just one of me so constructor will be called once. + SSLClient; + // The thread-safe client. + private final CloseableHttpClient threadSafeClient; + // The pool monitor. + private final IdleConnectionMonitorThread monitor; + private TrustStrategy acceptingTrustStrategy = null; + private SSLContext sslContext = null; + private SSLConnectionSocketFactory sslsf = null; + private Registry socketFactoryRegistry = null; + private NoopHostnameVerifier hostnameVerifier = null; + + // The constructor creates it - thus late + private SingletonSSL() { + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + // Increase max total connection to 200 + cm.setMaxTotal(200); + // Increase default max connection per route to 20 + cm.setDefaultMaxPerRoute(20); + try { + acceptingTrustStrategy = (cert, authType) -> true; + hostnameVerifier = new NoopHostnameVerifier(); + sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); + sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); + } catch (Exception e) { + HttpClientPool.log.warn("SingletonSSL failed on SSL init"); + } + // Build the client. + threadSafeClient = HttpClients.custom().setConnectionManager(cm).setSSLSocketFactory(sslsf) + .setSSLHostnameVerifier(hostnameVerifier).build(); // Start up an eviction thread. monitor = new IdleConnectionMonitorThread(cm); // Don't stop quitting. @@ -52,6 +107,11 @@ public final class HttpClientPool { return Singleton.Client.get(); } + public static CloseableHttpClient getSSLClient() { + // The thread safe client is held by the singleton. + return SingletonSSL.SSLClient.get(); + } + // Watches for stale connections and evicts them. private static class IdleConnectionMonitorThread extends Thread { // The manager to watch. @@ -123,6 +183,7 @@ public final class HttpClientPool { public static void shutdown() throws InterruptedException, IOException { // Shutdown the monitor. Singleton.Client.monitor.shutdown(); + SingletonSSL.SSLClient.monitor.shutdown(); } } \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java index cc93328..117fca5 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java @@ -102,8 +102,10 @@ public class MozIotInstance { headers[1].setName("Accept"); headers[1].setValue("application/json"); aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/login"; + log.info("gateway login URL: " + aUrl); String commandData = "{\"email\": \"" + mozIotIP.getUsername() + "\", \"password\":\"" + mozIotIP.getPassword() + "\"}"; + log.info("The login body: " + commandData); String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, headers); if (theData != null) { log.info("GET Mozilla login - data: " + theData); From 3e76e6298ab5cace67821ffdab4f0aaf014376c4 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Mon, 3 Jun 2019 16:06:03 -0500 Subject: [PATCH 23/52] tested moziot and working --- pom.xml | 2 +- .../bwssystems/HABridge/hue/HueMulator.java | 2 +- .../HABridge/plugins/http/HTTPHandler.java | 4 +- .../HABridge/plugins/http/HttpClientPool.java | 36 +- .../plugins/moziot/MozIotCommand.java | 13 +- .../plugins/moziot/MozIotCommandDetail.java | 54 + .../HABridge/plugins/moziot/MozIotDevice.java | 29 + .../HABridge/plugins/moziot/MozIotHome.java | 178 +- .../plugins/moziot/MozIotInstance.java | 32 +- src/main/resources/public/scripts/app.js | 4724 +++++++++-------- .../resources/public/views/moziotdevice.html | 167 +- .../resources/public/views/openhabdevice.html | 2 +- 12 files changed, 2783 insertions(+), 2460 deletions(-) create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommandDetail.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotDevice.java diff --git a/pom.xml b/pom.xml index f63ebbf..0db4b1e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 5.2.next_a + 5.2.next_b jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 5350a96..00953ad 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -1431,7 +1431,7 @@ public class HueMulator { anHSL.setSat(sat); else anHSL.setSat(state.getSat()); - log.info("hue/sat request - " + anHSL); + log.debug("hue/sat request - " + anHSL); colorData = new ColorData(ColorData.ColorMode.HS, anHSL); } else if (hueInc != null || satInc != null) { anHSL = new HueSatBri(); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java index 00b0acc..f52e26c 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java @@ -5,8 +5,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; -import javax.net.ssl.SSLContext; - import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -154,7 +152,7 @@ public class HTTPHandler { } catch (ClientProtocolException e) { log.warn("Client Protocol Exception received, retyring...."); } catch (IOException e) { - log.warn("Error calling out to HA gateway: IOException in log: " + e.getMessage()); + log.warn("Error calling out to HA gateway: IOException in log: " + e.getMessage(), e); retryCount = 2; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HttpClientPool.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HttpClientPool.java index b1790f2..0f80dfd 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HttpClientPool.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HttpClientPool.java @@ -62,9 +62,9 @@ public final class HttpClientPool { // Just one of me so constructor will be called once. SSLClient; // The thread-safe client. - private final CloseableHttpClient threadSafeClient; + private CloseableHttpClient threadSafeClient; // The pool monitor. - private final IdleConnectionMonitorThread monitor; + private IdleConnectionMonitorThread monitor = null; private TrustStrategy acceptingTrustStrategy = null; private SSLContext sslContext = null; private SSLConnectionSocketFactory sslsf = null; @@ -73,27 +73,33 @@ public final class HttpClientPool { // The constructor creates it - thus late private SingletonSSL() { - PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); - // Increase max total connection to 200 - cm.setMaxTotal(200); - // Increase default max connection per route to 20 - cm.setDefaultMaxPerRoute(20); try { acceptingTrustStrategy = (cert, authType) -> true; hostnameVerifier = new NoopHostnameVerifier(); sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); + HttpClientPool.log.info("Instantiated SSL components."); + final Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", new PlainConnectionSocketFactory()) + .register("https", sslsf) + .build(); + PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + // Increase max total connection to 200 + cm.setMaxTotal(200); + // Increase default max connection per route to 20 + cm.setDefaultMaxPerRoute(20); + + // Build the client. + threadSafeClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).build(); + // Start up an eviction thread. + monitor = new IdleConnectionMonitorThread(cm); + // Don't stop quitting. + monitor.setDaemon(true); + monitor.start(); } catch (Exception e) { HttpClientPool.log.warn("SingletonSSL failed on SSL init"); + threadSafeClient = null; } - // Build the client. - threadSafeClient = HttpClients.custom().setConnectionManager(cm).setSSLSocketFactory(sslsf) - .setSSLHostnameVerifier(hostnameVerifier).build(); - // Start up an eviction thread. - monitor = new IdleConnectionMonitorThread(cm); - // Don't stop quitting. - monitor.setDaemon(true); - monitor.start(); } public CloseableHttpClient get() { diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommand.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommand.java index acb78fe..1c86ce0 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommand.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommand.java @@ -1,18 +1,25 @@ package com.bwssystems.HABridge.plugins.moziot; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + public class MozIotCommand { + @SerializedName("url") + @Expose private String url; - private String command; + @SerializedName("command") + @Expose + private MozIotCommandDetail command; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } - public String getCommand() { + public MozIotCommandDetail getCommand() { return command; } - public void setCommand(String command) { + public void setCommand(MozIotCommandDetail command) { this.command = command; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommandDetail.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommandDetail.java new file mode 100644 index 0000000..ca04074 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotCommandDetail.java @@ -0,0 +1,54 @@ +package com.bwssystems.HABridge.plugins.moziot; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class MozIotCommandDetail { + @SerializedName("on") + @Expose + private boolean on; + @SerializedName("level") + @Expose + private String level; + @SerializedName("color") + @Expose + private String color; + + public boolean isOn() { + return on; + } + + public void setOn(boolean on) { + this.on = on; + } + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String getBody() { + String theBody = ""; + + if(level != null && level != "") { + theBody = "{\"level\":" + level + "}"; + } + else if(color != null && color != "") { + theBody = "{\"color\":\"" + color + "\"}"; + } else { + theBody = "{\"on\":" + on + "}"; + } + return theBody; + } +} \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotDevice.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotDevice.java new file mode 100644 index 0000000..2196d56 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotDevice.java @@ -0,0 +1,29 @@ +package com.bwssystems.HABridge.plugins.moziot; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class MozIotDevice { + @SerializedName("gatewayName") + @Expose + private String gatewayName; + @SerializedName("deviceDetail") + @Expose + private MozillaThing deviceDetail; + + public String getGatewayName() { + return gatewayName; + } + + public void setGatewayName(String gatewayName) { + this.gatewayName = gatewayName; + } + + public MozillaThing getDeviceDetail() { + return deviceDetail; + } + + public void setDeviceDetail(MozillaThing deviceDetail) { + this.deviceDetail = deviceDetail; + } +} \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java index 0510adf..082e8a0 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java @@ -26,13 +26,13 @@ import com.bwssystems.HABridge.plugins.http.HTTPHandler; import com.bwssystems.HABridge.plugins.http.HTTPHome; import com.google.gson.Gson; -public class MozIotHome implements Home { - private static final Logger log = LoggerFactory.getLogger(MozIotHome.class); +public class MozIotHome implements Home { + private static final Logger log = LoggerFactory.getLogger(MozIotHome.class); private Map moziotMap; private Boolean validMoziot; - private HTTPHandler httpClient; + private HTTPHandler httpClient; private boolean closed; - + public MozIotHome(BridgeSettings bridgeSettings) { super(); closed = true; @@ -47,71 +47,68 @@ public class MozIotHome implements Home { String theUrl = anItem.getItem().getAsString(); String responseString = null; - if(theUrl != null && !theUrl.isEmpty()) { + if (theUrl != null && !theUrl.isEmpty()) { + String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrl, intensity, targetBri, targetBriInc, + false); + if (colorData != null) { + anUrl = ColorDecode.replaceColorData(anUrl, colorData, + BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true); + } + anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device); + anUrl = TimeDecode.replaceTimeValue(anUrl); + + anUrl = BrightnessDecode.calculateReplaceIntensityValue(anUrl, intensity, targetBri, targetBriInc, false); + if (colorData != null) { + anUrl = ColorDecode.replaceColorData(anUrl, colorData, + BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false); + } + anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device); + anUrl = TimeDecode.replaceTimeValue(anUrl); + MozIotCommand theCommand = null; try { theUrl = theUrl.replaceAll("^\"|\"$", ""); - theCommand = new Gson().fromJson(theUrl, MozIotCommand.class); - } catch(Exception e) { - log.warn("Cannot parse command to Mozilla IOT <<<" + theUrl + ">>>", e); + theCommand = new Gson().fromJson(anUrl, MozIotCommand.class); + } catch (Exception e) { + log.warn("Cannot parse command to Mozilla IOT <<<" + theUrl + ">>>", e); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, - "Error on calling url to change device state", "/lights/" - + lightId + "/state", null, null).getTheErrors(), HueError[].class); + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, null) + .getTheErrors(), HueError[].class); return responseString; } - String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("://") + 3); - String hostPortion = intermediate.substring(0, intermediate.indexOf('/')); - String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1); - String hostAddr = null; - if (hostPortion.contains(":")) { - hostAddr = hostPortion.substring(0, intermediate.indexOf(':')); - } else - hostAddr = hostPortion; - MozIotInstance theHandler = findHandlerByAddress(hostAddr); - if(theHandler != null) { - String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, - intensity, targetBri, targetBriInc, false); - if (colorData != null) { - anUrl = ColorDecode.replaceColorData(anUrl, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false); - } - anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device); - anUrl = TimeDecode.replaceTimeValue(anUrl); - - String aCommand = null; - if(theCommand.getCommand() != null && !theCommand.getCommand().isEmpty()) { - aCommand = BrightnessDecode.calculateReplaceIntensityValue(theCommand.getCommand(), - intensity, targetBri, targetBriInc, false); - if (colorData != null) { - aCommand = ColorDecode.replaceColorData(aCommand, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false); - } - aCommand = DeviceDataDecode.replaceDeviceData(aCommand, device); - aCommand = TimeDecode.replaceTimeValue(aCommand); - } - try { - boolean success = theHandler.callCommand(anUrl, aCommand, httpClient); - if(!success) { - log.warn("Comand had error to Mozilla IOT"); + + String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("/things/") + 8); + String devicePortion = intermediate.substring(0, intermediate.indexOf('/')); + String theUrlCommand = intermediate.substring(intermediate.indexOf('/') + 1); + MozIotInstance theHandler = moziotMap.get(device.getTargetDevice()); + if (theHandler != null) { + try { + boolean success = theHandler.callCommand(devicePortion, theUrlCommand, theCommand.getCommand(), httpClient); + if (!success) { + log.warn("Comand had error to Mozilla IOT"); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, - "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); - } - } catch (Exception e) { - log.warn("Cannot send comand to Mozilla IOT", e); + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, + null).getTheErrors(), HueError[].class); + } + } catch (Exception e) { + log.warn("Cannot send comand to Mozilla IOT", e); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, - "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); - } + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, null) + .getTheErrors(), HueError[].class); + } } else { log.warn("Mozilla IOT Call could not complete, no address found: " + theUrl); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, - "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, null) + .getTheErrors(), HueError[].class); } } else { - log.warn("Mozilla IOT Call to be presented as http(s)://(:)/payload, format of request unknown: " + theUrl); + log.warn( + "Mozilla IOT Call to be presented as http(s)://(:)/payload, format of request unknown: " + + theUrl); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, - "Error on calling url to change device state", "/lights/" - + lightId + "state", null, null).getTheErrors(), HueError[].class); + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, null) + .getTheErrors(), HueError[].class); } return responseString; } @@ -119,16 +116,16 @@ public class MozIotHome implements Home { @Override public Object getItems(String type) { - if(!validMoziot) + if (!validMoziot) return null; log.debug("consolidating devices for Mozilla IOT"); List theResponse = null; Iterator keys = moziotMap.keySet().iterator(); - List deviceList = new ArrayList(); - while(keys.hasNext()) { + List deviceList = new ArrayList(); + while (keys.hasNext()) { String key = keys.next(); theResponse = moziotMap.get(key).getDevices(httpClient); - if(theResponse != null) + if (theResponse != null) addMozIotDevices(deviceList, theResponse, key); else { log.warn("Cannot get devices for Mozilla IOT with name: " + key + ", skipping this Mozilla IOT."); @@ -137,11 +134,15 @@ public class MozIotHome implements Home { } return deviceList; } - - private Boolean addMozIotDevices(List theDeviceList, List theSourceList, String theKey) { - Iterator devices = theSourceList.iterator(); - while(devices.hasNext()) { - MozillaThing theDevice = devices.next(); + + private Boolean addMozIotDevices(List theDeviceList, List theSourceList, + String theKey) { + Iterator things = theSourceList.iterator(); + while (things.hasNext()) { + MozillaThing theThing = things.next(); + MozIotDevice theDevice = new MozIotDevice(); + theDevice.setDeviceDetail(theThing); + theDevice.setGatewayName(theKey); theDeviceList.add(theDevice); } return true; @@ -152,57 +153,42 @@ public class MozIotHome implements Home { moziotMap = null; validMoziot = bridgeSettings.getBridgeSettingsDescriptor().isValidMozIot(); log.info("Mozilla IOT Home created." + (validMoziot ? "" : " No Mozilla IOTs configured.")); - if(validMoziot) { - moziotMap = new HashMap(); - httpClient = HTTPHome.getHandler(); - Iterator theList = bridgeSettings.getBridgeSettingsDescriptor().getMoziotaddress().getDevices().iterator(); - while(theList.hasNext() && validMoziot) { + if (validMoziot) { + moziotMap = new HashMap(); + httpClient = HTTPHome.getHandler(); + Iterator theList = bridgeSettings.getBridgeSettingsDescriptor().getMoziotaddress().getDevices() + .iterator(); + while (theList.hasNext() && validMoziot) { NamedIP aMoziot = theList.next(); - try { - moziotMap.put(aMoziot.getName(), new MozIotInstance(aMoziot, httpClient)); + try { + moziotMap.put(aMoziot.getName(), new MozIotInstance(aMoziot, httpClient)); } catch (Exception e) { - log.error("Cannot get Mozilla IOT (" + aMoziot.getName() + ") setup, Exiting with message: " + e.getMessage(), e); - validMoziot = false; + log.error("Cannot get Mozilla IOT (" + aMoziot.getName() + ") setup, Exiting with message: " + + e.getMessage(), e); + validMoziot = false; } } - } - return this; - } - - private MozIotInstance findHandlerByAddress(String hostAddress) { - MozIotInstance aHandler = null; - boolean found = false; - Iterator keys = moziotMap.keySet().iterator(); - while(keys.hasNext()) { - String key = keys.next(); - aHandler = moziotMap.get(key); - if(aHandler != null && aHandler.getMozIotIP().getIp().equals(hostAddress)) { - found = true; - break; - } } - if(!found) - aHandler = null; - return aHandler; + return this; } @Override public void closeHome() { log.debug("Closing Home."); - if(!closed && validMoziot) { + if (!closed && validMoziot) { log.debug("Home is already closed...."); return; } - if(httpClient != null) + if (httpClient != null) httpClient.closeHandler(); moziotMap = null; - closed = true; + closed = true; } - + @Override public void refresh() { - // noop + // noop } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java index 117fca5..bd336b6 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotInstance.java @@ -26,8 +26,8 @@ public class MozIotInstance { gatewayLogin(httpClient); } - public Boolean callCommand(String aCommand, String commandData, HTTPHandler httpClient) { - log.debug("calling Mozilla IOT: " + mozIotIP.getIp() + ":" + mozIotIP.getPort() + aCommand); + public Boolean callCommand(String deviceId, String aCommand, MozIotCommandDetail commandData, HTTPHandler httpClient) { + log.debug("calling Mozilla IOT: {}:{}{}{}", mozIotIP.getIp(), mozIotIP.getPort(), aCommand, commandData.getBody()); String aUrl = null; if (mozIotIP.getSecure() != null && mozIotIP.getSecure()) @@ -36,9 +36,9 @@ public class MozIotInstance { aUrl = "http://"; headers = getAuthHeader(); - aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/" + aCommand; - String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", commandData, headers); - log.debug("call Command return is: <" + theData + ">"); + aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/things/" + deviceId + "/" + aCommand; + String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", commandData.getBody(), headers); + log.debug("call Command return is: <<<{}>>>", theData); if (theData.contains("error") || theData.contains("ERROR") || theData.contains("Error")) return false; return true; @@ -70,7 +70,7 @@ public class MozIotInstance { } } } catch (Exception e) { - log.warn("Cannot get an devices for Mozilla IOT " + mozIotIP.getName() + " Gson Parse Error."); + log.warn("Cannot get an devices for Mozilla IOT {} Gson Parse Error.", mozIotIP.getName()); } } return deviceList; @@ -78,11 +78,17 @@ public class MozIotInstance { private NameValue[] getAuthHeader() { if (headers == null) { - headers = new NameValue[1]; + headers = new NameValue[3]; headers[0] = new NameValue(); headers[0].setName("Authorization"); headers[0].setValue("Bearer " + moziotToken.getJwt()); - } + headers[1] = new NameValue(); + headers[1].setName("Content-Type"); + headers[1].setValue("application/json"); + headers[2] = new NameValue(); + headers[2].setName("Accept"); + headers[2].setValue("application/json"); + } return headers; } @@ -102,20 +108,20 @@ public class MozIotInstance { headers[1].setName("Accept"); headers[1].setValue("application/json"); aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/login"; - log.info("gateway login URL: " + aUrl); + log.debug("gateway login URL: {}", aUrl); String commandData = "{\"email\": \"" + mozIotIP.getUsername() + "\", \"password\":\"" + mozIotIP.getPassword() + "\"}"; - log.info("The login body: " + commandData); + log.debug("The login body: {}", commandData); String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, headers); if (theData != null) { - log.info("GET Mozilla login - data: " + theData); + log.debug("GET Mozilla login - data: {}", theData); try { moziotToken = new Gson().fromJson(theData, JWT.class); } catch (Exception e) { - log.warn("Cannot get login for Mozilla IOT " + mozIotIP.getName() + " Gson Parse Error."); + log.warn("Cannot get login for Mozilla IOT {} Gson Parse Error.", mozIotIP.getName()); } } else { - log.warn("Could not login " + mozIotIP.getName() + " error: <<<" + theData + ">>>"); + log.warn("Could not login {} error: <<<{}>>>", mozIotIP.getName(), theData); } headers = null; diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index b9823f0..de16a17 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -1,106 +1,106 @@ -var app = angular.module ('habridge', ['ngRoute', 'ngToast', 'rzModule', 'ngDialog', 'base64', 'scrollable-table', 'ngResource', 'ngStorage', 'colorpicker.module']); +var app = angular.module('habridge', ['ngRoute', 'ngToast', 'rzModule', 'ngDialog', 'base64', 'scrollable-table', 'ngResource', 'ngStorage', 'colorpicker.module']); -app.config (function ($locationProvider, $routeProvider) { - $locationProvider.hashPrefix('!'); +app.config(function ($locationProvider, $routeProvider) { + $locationProvider.hashPrefix('!'); - $routeProvider.when ('/', { + $routeProvider.when('/', { templateUrl: 'views/configuration.html', controller: 'ViewingController', - requiresAuthentication: true - }).when ('/system', { + requiresAuthentication: true + }).when('/system', { templateUrl: 'views/system.html', - controller: 'SystemController', + controller: 'SystemController', requiresAuthentication: true - }).when ('/logs', { + }).when('/logs', { templateUrl: 'views/logs.html', - controller: 'LogsController', + controller: 'LogsController', requiresAuthentication: true - }).when ('/editdevice', { + }).when('/editdevice', { templateUrl: 'views/editdevice.html', - controller: 'EditController', - requiresAuthentication: true - }).when ('/veradevices', { + controller: 'EditController', + requiresAuthentication: true + }).when('/veradevices', { templateUrl: 'views/veradevice.html', - controller: 'VeraController', - requiresAuthentication: true - }).when ('/verascenes', { + controller: 'VeraController', + requiresAuthentication: true + }).when('/verascenes', { templateUrl: 'views/verascene.html', - controller: 'VeraController', + controller: 'VeraController', requiresAuthentication: true - }).when ('/fibarodevices', { + }).when('/fibarodevices', { templateUrl: 'views/fibarodevice.html', - controller: 'FibaroController', - requiresAuthentication: true - }).when ('/fibaroscenes', { + controller: 'FibaroController', + requiresAuthentication: true + }).when('/fibaroscenes', { templateUrl: 'views/fibaroscene.html', - controller: 'FibaroController', + controller: 'FibaroController', requiresAuthentication: true - }).when ('/harmonydevices', { + }).when('/harmonydevices', { templateUrl: 'views/harmonydevice.html', - controller: 'HarmonyController', - requiresAuthentication: true - }).when ('/harmonyactivities', { - templateUrl: 'views/harmonyactivity.html', - controller: 'HarmonyController', - requiresAuthentication: true - }).when ('/nest', { - templateUrl: 'views/nestactions.html', - controller: 'NestController', - requiresAuthentication: true - }).when ('/huedevices', { - templateUrl: 'views/huedevice.html', - controller: 'HueController', - requiresAuthentication: true - }).when ('/haldevices', { - templateUrl: 'views/haldevice.html', - controller: 'HalController', - requiresAuthentication: true - }).when ('/mqttmessages', { - templateUrl: 'views/mqttpublish.html', - controller: 'MQTTController', - requiresAuthentication: true - }).when ('/hassdevices', { - templateUrl: 'views/hassdevice.html', - controller: 'HassController', + controller: 'HarmonyController', requiresAuthentication: true - }).when ('/homewizarddevices', { - templateUrl: 'views/homewizarddevice.html', - controller: 'HomeWizardController', - requiresAuthentication: true - }).when ('/domoticzdevices', { + }).when('/harmonyactivities', { + templateUrl: 'views/harmonyactivity.html', + controller: 'HarmonyController', + requiresAuthentication: true + }).when('/nest', { + templateUrl: 'views/nestactions.html', + controller: 'NestController', + requiresAuthentication: true + }).when('/huedevices', { + templateUrl: 'views/huedevice.html', + controller: 'HueController', + requiresAuthentication: true + }).when('/haldevices', { + templateUrl: 'views/haldevice.html', + controller: 'HalController', + requiresAuthentication: true + }).when('/mqttmessages', { + templateUrl: 'views/mqttpublish.html', + controller: 'MQTTController', + requiresAuthentication: true + }).when('/hassdevices', { + templateUrl: 'views/hassdevice.html', + controller: 'HassController', + requiresAuthentication: true + }).when('/homewizarddevices', { + templateUrl: 'views/homewizarddevice.html', + controller: 'HomeWizardController', + requiresAuthentication: true + }).when('/domoticzdevices', { templateUrl: 'views/domoticzdevice.html', - controller: 'DomoticzController', + controller: 'DomoticzController', requiresAuthentication: true }).when('/somfydevices', { - templateUrl: 'views/somfydevice.html', - controller: 'SomfyController', - requiresAuthentication: true - }).when ('/lifxdevices', { + templateUrl: 'views/somfydevice.html', + controller: 'SomfyController', + requiresAuthentication: true + }).when('/lifxdevices', { templateUrl: 'views/lifxdevice.html', - controller: 'LifxController', - requiresAuthentication: true - }).when ('/openhabdevices', { + controller: 'LifxController', + requiresAuthentication: true + }).when('/openhabdevices', { templateUrl: 'views/openhabdevice.html', controller: 'OpenHABController', requiresAuthentication: true - }).when ('/moziotdevices', { + }).when('/moziotdevices', { templateUrl: 'views/moziotdevice.html', controller: 'MozIotController', requiresAuthentication: true - }).when ('/fhemdevices', { + }).when('/fhemdevices', { templateUrl: 'views/fhemdevice.html', controller: 'FhemController', requiresAuthentication: true - }).when ('/broadlinkdevices', { + }).when('/broadlinkdevices', { templateUrl: 'views/broadlinkdevice.html', controller: 'BroadlinkController', requiresAuthentication: true - }).when ('/login', { + }).when('/login', { templateUrl: 'views/login.html', - controller: 'LoginController' - }).otherwise ({ + controller: 'LoginController' + }).otherwise({ templateUrl: 'views/configuration.html', - controller: 'ViewingController', + controller: 'ViewingController', requiresAuthentication: true }); }); @@ -108,70 +108,106 @@ app.config (function ($locationProvider, $routeProvider) { app.run(function ($rootScope, $location, Auth, bridgeService) { bridgeService.getHABridgeVersion(); - $rootScope.$on('securitySetupReceived', function(event, data) { - Auth.init(); - if(Auth.isLoggedIn()) { - bridgeService.loadBridgeSettings(); - bridgeService.getSecurityInfo(); - bridgeService.viewMapTypes(); - $location.path("/"); - } else { - event.preventDefault(); - $location.path("/login"); - } - }); - - $rootScope.$on('securityError', function(event, data) { - Auth.logout(); - event.preventDefault(); - $location.path("/login"); - }); - - $rootScope.$on('securityReinit', function(event, data) { - event.preventDefault(); - bridgeService.state.testuser = ""; - Auth.logout(); + $rootScope.$on('securitySetupReceived', function (event, data) { + Auth.init(); + if (Auth.isLoggedIn()) { + bridgeService.loadBridgeSettings(); + bridgeService.getSecurityInfo(); + bridgeService.viewMapTypes(); + $location.path("/"); + } else { + event.preventDefault(); + $location.path("/login"); + } + }); + + $rootScope.$on('securityError', function (event, data) { + Auth.logout(); + event.preventDefault(); + $location.path("/login"); + }); + + $rootScope.$on('securityReinit', function (event, data) { + event.preventDefault(); + bridgeService.state.testuser = ""; + Auth.logout(); $location.path("/"); - }); - - $rootScope.$on('$routeChangeStart', function (event, next) { - if (!Auth.checkPermissionForView(next)){ - event.preventDefault(); - $location.path("/login"); - } else { - $location.path(next.originalPath); - - } - }); + }); + + $rootScope.$on('$routeChangeStart', function (event, next) { + if (!Auth.checkPermissionForView(next)) { + event.preventDefault(); + $location.path("/login"); + } else { + $location.path(next.originalPath); + + } + }); }); -String.prototype.replaceAll = function (search, replace) -{ - //if replace is not sent, return original string otherwise it will - //replace search string with 'undefined'. - if (replace === undefined) { - return this.toString(); - } +String.prototype.replaceAll = function (search, replace) { + //if replace is not sent, return original string otherwise it will + //replace search string with 'undefined'. + if (replace === undefined) { + return this.toString(); + } - return this.replace(new RegExp('[' + search + ']', 'g'), replace); + return this.replace(new RegExp('[' + search + ']', 'g'), replace); }; -app.service ('bridgeService', function ($rootScope, $http, $base64, $location, ngToast) { +app.service('bridgeService', function ($rootScope, $http, $base64, $location, ngToast) { var self = this; - this.state = {base: "./api/devices", bridgelocation: ".", systemsbase: "./system", huebase: "./api", configs: [], backups: [], devices: [], device: {}, - mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, - isInControl: false, showVera: false, showFibaro: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, - showHomeWizard: false, showDomoticz: false, showSomfy: false, showLifx: false, showOpenHAB: false, showMozIot: false, showFHEM: false, showBroadlink: false, habridgeversion: {}, - viewDevId: "", queueDevId: "", securityInfo: {}, filterDevicesByIpAddress: null, - filterDevicesOnlyFiltered: false, filterDeviceType: null}; + this.state = { + base: "./api/devices", + bridgelocation: ".", + systemsbase: "./system", + huebase: "./api", + configs: [], + backups: [], + devices: [], + device: {}, + mapandid: [], + type: "", + settings: [], + myToastMsg: [], + logMsgs: [], + loggerInfo: [], + mapTypes: [], + olddevicename: "", + logShowAll: false, + isInControl: false, + showVera: false, + showFibaro: false, + showHarmony: false, + showNest: false, + showHue: false, + showHal: false, + showMqtt: false, + showHass: false, + showHomeWizard: false, + showDomoticz: false, + showSomfy: false, + showLifx: false, + showOpenHAB: false, + showMozIot: false, + showFHEM: false, + showBroadlink: false, + habridgeversion: {}, + viewDevId: "", + queueDevId: "", + securityInfo: {}, + filterDevicesByIpAddress: null, + filterDevicesOnlyFiltered: false, + filterDeviceType: null + }; - this.displayWarn = function(errorTitle, error) { + this.displayWarn = function (errorTitle, error) { var toastContent = errorTitle; - if (error !== null && typeof(error) !== 'undefined') { + if (error !== null && typeof (error) !== 'undefined') { if (error.data !== null) - toastContent = toastContent + " " + error.data.message + " with status: " + error.statusText + " - " + error.status; + toastContent = toastContent + " " + error.data.message + " with status: " + error.statusText + " - " + error.status; else toastContent = error; } @@ -179,74 +215,79 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n className: "warning", dismissButton: true, dismissOnTimeout: false, - content: toastContent}); + content: toastContent + }); }; - - this.displayError = function(errorTitle, error) { + + this.displayError = function (errorTitle, error) { var toastContent = errorTitle; - if (error !== null && typeof(error) !== 'undefined') - toastContent = toastContent + " " + error.data.message + " with status: " + error.statusText + " - " + error.status; + if (error !== null && typeof (error) !== 'undefined') + toastContent = toastContent + " " + error.data.message + " with status: " + error.statusText + " - " + error.status; ngToast.create({ className: "danger", dismissButton: true, dismissOnTimeout: false, - content: toastContent}); + content: toastContent + }); }; - + this.displayErrorMessage = function (errorTitle, errorMessage) { ngToast.create({ className: "danger", dismissButton: true, dismissOnTimeout: false, - content: errorTitle + errorMessage}); + content: errorTitle + errorMessage + }); }; - + this.displaySuccess = function (theTitle) { ngToast.create({ className: "success", - content: theTitle}); + content: theTitle + }); }; - + this.displayTimer = function (theTitle, timeMillis) { ngToast.create({ className: "success", timeout: timeMillis, dismissOnClick: false, - content: theTitle + " in " + timeMillis/1000 + " seconds"}); + content: theTitle + " in " + timeMillis / 1000 + " seconds" + }); }; - + this.viewDevices = function () { return $http.get(this.state.base).then( - function (response) { - self.state.devices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayError("Cannot get devices from habridge: ", error); - } + function (response) { + self.state.devices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayError("Cannot get devices from habridge: ", error); + } ); }; this.renumberDevices = function () { return $http.post(this.state.base + "/exec/renumber").then( - function (response) { - self.viewDevices(); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayError("Cannot renumber devices from habridge: ", error); - } + function (response) { + self.viewDevices(); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayError("Cannot renumber devices from habridge: ", error); + } ); }; - this.compareUniqueId = function(r1, r2) { - if (r1.id === r2.id) - return 0; - return parseInt(r1.id) > parseInt(r2.id) ? 1 : -1; + this.compareUniqueId = function (r1, r2) { + if (r1.id === r2.id) + return 0; + return parseInt(r1.id) > parseInt(r2.id) ? 1 : -1; }; this.clearDevice = function () { @@ -256,198 +297,198 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n this.getHABridgeVersion = function () { return $http.get(this.state.systemsbase + "/habridge/version").then( - function (response) { - self.state.habridgeversion = { - version: response.data.version, - isSecure: response.data.isSecure - }; - $rootScope.$broadcast('securitySetupReceived', 'done'); - }, - function (error) { - self.displayWarn("Cannot get version: ", error); - } + function (response) { + self.state.habridgeversion = { + version: response.data.version, + isSecure: response.data.isSecure + }; + $rootScope.$broadcast('securitySetupReceived', 'done'); + }, + function (error) { + self.displayWarn("Cannot get version: ", error); + } ); }; this.getTestUser = function () { - if(self.state.testuser === undefined || self.state.testuser === "") { + if (self.state.testuser === undefined || self.state.testuser === "") { var linkParams = {}; linkParams = { - seconds: 3, - silent: true - }; + seconds: 3, + silent: true + }; return $http.put(this.state.systemsbase + "/presslinkbutton", linkParams).then( - function (response) { - self.getAUser(); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Cannot get testuser: ", error); - } + function (response) { + self.getAUser(); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Cannot get testuser: ", error); + } ); } }; this.getAUser = function () { return $http.post(this.state.huebase, "{\"devicetype\":\"test_ha_bridge\"}").then( - function (response) { - self.state.testuser = response.data[0].success.username; - self.getWhitelist(); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Cannot get a user: ", error); - } + function (response) { + self.state.testuser = response.data[0].success.username; + self.getWhitelist(); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Cannot get a user: ", error); + } ); }; this.getSecurityInfo = function () { return $http.get(this.state.systemsbase + "/securityinfo").then( - function (response) { - self.state.securityInfo = response.data; - self.getTestUser(); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Cannot get security info: ", error); - } + function (response) { + self.state.securityInfo = response.data; + self.getTestUser(); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Cannot get security info: ", error); + } ); }; - + this.changeSecuritySettings = function (useLinkButton, secureHueApi, execGarden) { var newSecurityInfo = {}; newSecurityInfo = { - useLinkButton: useLinkButton, - secureHueApi: secureHueApi, - execGarden: execGarden - }; - return $http.post(this.state.systemsbase + "/changesecurityinfo", newSecurityInfo ).then( - function (response) { - self.state.securityInfo = response.data; - self.displaySuccess("Updated security settings."); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + useLinkButton: useLinkButton, + secureHueApi: secureHueApi, + execGarden: execGarden + }; + return $http.post(this.state.systemsbase + "/changesecurityinfo", newSecurityInfo).then( + function (response) { + self.state.securityInfo = response.data; + self.displaySuccess("Updated security settings."); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Update security settings Error: ", error); - } + } ); }; this.isSecure = function () { - if(self.state.habridgeversion === undefined) + if (self.state.habridgeversion === undefined) return true; - if(self.state.habridgeversion.isSecure === undefined) + if (self.state.habridgeversion.isSecure === undefined) return true; - + return self.state.habridgeversion.isSecure; }; this.changePassword = function (aPassword, aPassword2) { var newUserInfo = {}; newUserInfo = { - username: self.state.loggedInUser, - password: aPassword, - password2: aPassword2 - }; + username: self.state.loggedInUser, + password: aPassword, + password2: aPassword2 + }; var theEncodedPayload = $base64.encode(angular.toJson(newUserInfo)); - return $http.post(this.state.systemsbase + "/setpassword", theEncodedPayload ).then( - function (response) { - self.displaySuccess("Password updated"); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + return $http.post(this.state.systemsbase + "/setpassword", theEncodedPayload).then( + function (response) { + self.displaySuccess("Password updated"); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Update password Error: ", error); - } + } ); }; this.addUser = function (username, aPassword, aPassword2) { var newUserInfo = {}; newUserInfo = { - username: username, - password: aPassword, - password2: aPassword2 - }; + username: username, + password: aPassword, + password2: aPassword2 + }; var theEncodedPayload = $base64.encode(angular.toJson(newUserInfo)); - return $http.put(this.state.systemsbase + "/adduser", theEncodedPayload ).then( - function (response) { - self.displaySuccess("User added"); - if(!self.isSecure()) { - self.getHABridgeVersion(); - } - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("User add Error: ", error); + return $http.put(this.state.systemsbase + "/adduser", theEncodedPayload).then( + function (response) { + self.displaySuccess("User added"); + if (!self.isSecure()) { + self.getHABridgeVersion(); } + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("User add Error: ", error); + } ); }; this.delUser = function (username) { var newUserInfo = {}; newUserInfo = { - username: username - }; + username: username + }; var theEncodedPayload = $base64.encode(angular.toJson(newUserInfo)); - return $http.put(this.state.systemsbase + "/deluser", theEncodedPayload ).then( - function (response) { - self.displaySuccess("User deleted"); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + return $http.put(this.state.systemsbase + "/deluser", theEncodedPayload).then( + function (response) { + self.displaySuccess("User deleted"); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("User add Error: ", error); - } + } ); }; this.pushLinkButton = function () { return $http.put(this.state.systemsbase + "/presslinkbutton").then( - function (response) { - self.displayTimer("Link your device", 30000); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.displayTimer("Link your device", 30000); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Cannot get security info: ", error); - } + } ); }; this.getWhitelist = function () { return $http.get(this.state.systemsbase + "/whitelist").then( - function (response) { - self.state.whitelist = response.data; - }, - function (error) { - self.displayWarn("Cannot get swhitelist: ", error); - } + function (response) { + self.state.whitelist = response.data; + }, + function (error) { + self.displayWarn("Cannot get swhitelist: ", error); + } ); }; - + this.setWhitelist = function (whitelist) { - return $http.post(this.state.systemsbase + "/setwhitelist", whitelist ).then( - function (response) { - self.state.whitelist = response.data; - self.displaySuccess("Updated whitelist."); - }, - function (error) { - self.displayWarn("Update whitelist Error: ", error); - } + return $http.post(this.state.systemsbase + "/setwhitelist", whitelist).then( + function (response) { + self.state.whitelist = response.data; + self.displaySuccess("Updated whitelist."); + }, + function (error) { + self.displayWarn("Update whitelist Error: ", error); + } ); }; @@ -456,61 +497,61 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n }; this.deviceContainsType = function (device, aType) { - if(device.mapType !== undefined && device.mapType !== null && device.mapType.indexOf(aType) >= 0) - return true; - - if(device.deviceType !== undefined && device.deviceType !== null && device.deviceType.indexOf(aType) >= 0) - return true; - - if(device.onUrl !== undefined && device.onUrl !== null && device.onUrl.indexOf(aType) >= 0) - return true; - - if(device.dimUrl !== undefined && device.dimUrl !== null && device.dimUrl.indexOf(aType) >= 0) - return true; - - if(device.offUrl !== undefined && device.offUrl !== null && device.offUrl.indexOf(aType) >= 0) + if (device.mapType !== undefined && device.mapType !== null && device.mapType.indexOf(aType) >= 0) return true; - if(device.colorUrl !== undefined && device.colorUrl !== null && device.colorUrl.indexOf(aType) >= 0) + if (device.deviceType !== undefined && device.deviceType !== null && device.deviceType.indexOf(aType) >= 0) return true; - - + + if (device.onUrl !== undefined && device.onUrl !== null && device.onUrl.indexOf(aType) >= 0) + return true; + + if (device.dimUrl !== undefined && device.dimUrl !== null && device.dimUrl.indexOf(aType) >= 0) + return true; + + if (device.offUrl !== undefined && device.offUrl !== null && device.offUrl.indexOf(aType) >= 0) + return true; + + if (device.colorUrl !== undefined && device.colorUrl !== null && device.colorUrl.indexOf(aType) >= 0) + return true; + + return false; }; - this.compareHarmonyNumber = function(r1, r2) { + this.compareHarmonyNumber = function (r1, r2) { if (r1.device !== undefined) { - if (r1.device.id === r2.device.id) - return 0; - return r1.device.id > r2.device.id ? 1 : -1; + if (r1.device.id === r2.device.id) + return 0; + return r1.device.id > r2.device.id ? 1 : -1; } if (r1.activity !== undefined) { - if (r1.activity.id === r2.activity.id) - return 0; - return r1.activity.id > r2.activity.id ? 1 : -1; + if (r1.activity.id === r2.activity.id) + return 0; + return r1.activity.id > r2.activity.id ? 1 : -1; } return 0; }; - this.compareHarmonyLabel = function(r1, r2) { + this.compareHarmonyLabel = function (r1, r2) { if (r1.device !== undefined) { - if (r1.device.label === r2.device.label) - return 0; - return r1.device.label > r2.device.label ? 1 : -1; + if (r1.device.label === r2.device.label) + return 0; + return r1.device.label > r2.device.label ? 1 : -1; } if (r1.activity !== undefined) { - if (r1.activity.label === r2.activity.label) - return 0; - return r1.activity.label > r2.activity.label ? 1 : -1; + if (r1.activity.label === r2.activity.label) + return 0; + return r1.activity.label > r2.activity.label ? 1 : -1; } return 0; }; - this.compareHarmonyHub = function(r1, r2) { + this.compareHarmonyHub = function (r1, r2) { if (r1.hub !== undefined) { - if (r1.hub === r2.hub) - return 0; - return r1.hub > r2.hub ? 1 : -1; + if (r1.hub === r2.hub) + return 0; + return r1.hub > r2.hub ? 1 : -1; } return 0; }; @@ -519,7 +560,7 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n this.state.showVera = self.state.settings.veraconfigured; return; }; - + this.updateShowFibaro = function () { this.state.showFibaro = self.state.settings.fibaroconfigured; return; @@ -556,19 +597,19 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n }; this.updateShowHass = function () { - this.state.showHass = self.state.settings.hassconfigured; - return; - }; - + this.state.showHass = self.state.settings.hassconfigured; + return; + }; + this.updateShowDomoticz = function () { this.state.showDomoticz = self.state.settings.domoticzconfigured; return; }; - this.updateShowSomfy = function () { - this.state.showSomfy = self.state.settings.somfyconfigured; - return; - }; + this.updateShowSomfy = function () { + this.state.showSomfy = self.state.settings.somfyconfigured; + return; + }; this.updateShowLifx = function () { this.state.showLifx = self.state.settings.lifxconfigured; @@ -597,183 +638,183 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n this.loadBridgeSettings = function () { return $http.get(this.state.systemsbase + "/settings").then( - function (response) { - self.state.settings = response.data; - self.updateShowVera(); - self.updateShowFibaro(); - self.updateShowHarmony(); - self.updateShowNest(); - self.updateShowHue(); - self.updateShowHal(); - self.updateShowMqtt(); - self.updateShowHass(); - self.updateShowHomeWizard(); - self.updateShowDomoticz(); - self.updateShowSomfy(); - self.updateShowLifx(); - self.updateShowOpenHAB(); - self.updateShowMozIot(); - self.updateShowFhem(); - self.updateShowBroadlink(); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.settings = response.data; + self.updateShowVera(); + self.updateShowFibaro(); + self.updateShowHarmony(); + self.updateShowNest(); + self.updateShowHue(); + self.updateShowHal(); + self.updateShowMqtt(); + self.updateShowHass(); + self.updateShowHomeWizard(); + self.updateShowDomoticz(); + self.updateShowSomfy(); + self.updateShowLifx(); + self.updateShowOpenHAB(); + self.updateShowMozIot(); + self.updateShowFhem(); + self.updateShowBroadlink(); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Load Bridge Settings Error: ", error); - } + } ); }; this.viewBackups = function () { return $http.get(this.state.base + "/backup/available").then( - function (response) { - self.state.backups = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.backups = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Backups Error: ", error); - } + } ); }; this.viewConfigs = function () { return $http.get(this.state.systemsbase + "/backup/available").then( - function (response) { - self.state.configs = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.configs = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Configs Error: ", error); - } + } ); }; this.viewLogs = function () { return $http.get(this.state.systemsbase + "/logmsgs").then( - function (response) { - self.state.logMsgs = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.logMsgs = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get log messages Error: ", error); - } + } ); }; this.viewLoggerInfo = function () { return $http.get(this.state.systemsbase + "/logmgmt/loggers/" + self.state.logShowAll).then( - function (response) { - self.state.loggerInfo = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.loggerInfo = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get logger info Error: ", error); - } + } ); }; this.viewNestItems = function () { - if(!this.state.showNest) + if (!this.state.showNest) return; return $http.get(this.state.base + "/nest/items").then( - function (response) { - self.state.nestitems = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.nestitems = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Nest Items Error: ", error); - } + } ); }; this.viewHueDevices = function () { - if(!this.state.showHue) + if (!this.state.showHue) return; return $http.get(this.state.base + "/hue/devices").then( - function (response) { - self.state.huedevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.huedevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Hue Items Error: ", error); - } + } ); }; this.viewVeraDevices = function () { - if(!this.state.showVera) + if (!this.state.showVera) return; return $http.get(this.state.base + "/vera/devices").then( - function (response) { - self.state.veradevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.veradevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Vera Devices Error: ", error); - } + } ); }; this.viewVeraScenes = function () { - if(!this.state.showVera) + if (!this.state.showVera) return; return $http.get(this.state.base + "/vera/scenes").then( - function (response) { - self.state.verascenes = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.verascenes = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Vera Scenes Error: ", error); - } + } ); }; - + this.viewFibaroDevices = function () { - if(!this.state.showFibaro) + if (!this.state.showFibaro) return; return $http.get(this.state.base + "/fibaro/devices").then( - function (response) { - self.state.fibarodevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.fibarodevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Fibaro Devices Error: ", error); - } + } ); }; this.viewFibaroScenes = function () { - if(!this.state.showFibaro) + if (!this.state.showFibaro) return; return $http.get(this.state.base + "/fibaro/scenes").then( - function (response) { - self.state.fibaroscenes = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.fibaroscenes = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Fibaro Scenes Error: ", error); - } + } ); }; @@ -781,15 +822,15 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (!this.state.showHarmony) return; return $http.get(this.state.base + "/harmony/activities").then( - function (response) { - self.state.harmonyactivities = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.harmonyactivities = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Harmony Activities Error: ", error); - } + } ); }; @@ -797,15 +838,15 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (!this.state.showHarmony) return; return $http.get(this.state.base + "/harmony/devices").then( - function (response) { - self.state.harmonydevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.harmonydevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Harmony Devices Error: ", error); - } + } ); }; @@ -813,15 +854,15 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (!this.state.showHal) return; return $http.get(this.state.base + "/hal/devices").then( - function (response) { - self.state.haldevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.haldevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Hal Devices Error: ", error); - } + } ); }; @@ -829,15 +870,15 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (!this.state.showMqtt) return; return $http.get(this.state.base + "/mqtt/devices").then( - function (response) { - self.state.mqttbrokers = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.mqttbrokers = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get MQTT Devices Error: ", error); - } + } ); }; @@ -845,80 +886,80 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (!this.state.showHass) return; return $http.get(this.state.base + "/hass/devices").then( - function (response) { - self.state.hassdevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.hassdevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Hass Devices Error: ", error); - } + } + ); + }; + + this.viewHomeWizardDevices = function () { + if (!this.state.showHomeWizard) + return; + return $http.get(this.state.base + "/homewizard/devices").then( + function (response) { + self.state.homewizarddevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Get HomeWizard Devices Error: ", error); + } ); }; - this.viewHomeWizardDevices = function () { - if (!this.state.showHomeWizard) - return; - return $http.get(this.state.base + "/homewizard/devices").then( - function (response) { - self.state.homewizarddevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Get HomeWizard Devices Error: ", error); - } - ); - }; - this.viewDomoticzDevices = function () { if (!this.state.showDomoticz) return; return $http.get(this.state.base + "/domoticz/devices").then( - function (response) { - self.state.domoticzdevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.domoticzdevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Domoticz Devices Error: ", error); - } + } ); }; this.viewSomfyDevices = function () { - if(!this.state.showSomfy) - return; - return $http.get(this.state.base + "/somfy/devices").then( - function (response) { - self.state.somfydevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Get Somfy Devices Error: ", error); - } - ); - }; + if (!this.state.showSomfy) + return; + return $http.get(this.state.base + "/somfy/devices").then( + function (response) { + self.state.somfydevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Get Somfy Devices Error: ", error); + } + ); + }; this.viewLifxDevices = function () { if (!this.state.showLifx) return; return $http.get(this.state.base + "/lifx/devices").then( - function (response) { - self.state.lifxdevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else + function (response) { + self.state.lifxdevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else self.displayWarn("Get Lifx Devices Error: ", error); - } + } ); }; @@ -926,15 +967,15 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (!this.state.showOpenHAB) return; return $http.get(this.state.base + "/openhab/devices").then( - function (response) { - self.state.openhabdevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Get OpenHAB Devices Error: ", error); - } + function (response) { + self.state.openhabdevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Get OpenHAB Devices Error: ", error); + } ); }; @@ -942,15 +983,15 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (!this.state.showMozIot) return; return $http.get(this.state.base + "/moziot/devices").then( - function (response) { - self.state.moziotdevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Get Mozilla IOT Devices Error: ", error); - } + function (response) { + self.state.moziotdevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Get Mozilla IOT Devices Error: ", error); + } ); }; @@ -958,15 +999,15 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (!this.state.showFHEM) return; return $http.get(this.state.base + "/fhem/devices").then( - function (response) { - self.state.fhemdevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Get FHEM Devices Error: ", error); - } + function (response) { + self.state.fhemdevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Get FHEM Devices Error: ", error); + } ); }; @@ -974,41 +1015,41 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (!this.state.showBroadlink) return; return $http.get(this.state.base + "/broadlink/devices").then( - function (response) { - self.state.broadlinkdevices = response.data; - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Get broadlink Devices Error: ", error); - } + function (response) { + self.state.broadlinkdevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Get broadlink Devices Error: ", error); + } ); }; this.refreshDevices = function (typeIndex) { return $http.get(this.state.base + "/refresh/" + typeIndex).then( - function (response) { - self.displaySuccess("Refresh devices request complete"); - }, - function (error) { - self.displayWarn("Refresh devices request Error: ", error); - } + function (response) { + self.displaySuccess("Refresh devices request complete"); + }, + function (error) { + self.displayWarn("Refresh devices request Error: ", error); + } ); }; this.formatCallItem = function (currentItem) { - if(currentItem.indexOf("item") < 0) { + if (currentItem.indexOf("item") < 0) { if (currentItem.startsWith("[") || currentItem.startsWith("{")) currentItem = "[{\"item\":" + currentItem + "}]"; else currentItem = "[{\"item\":\"" + currentItem + "\"}]"; - } else if(currentItem.startsWith("{")) + } else if (currentItem.startsWith("{")) currentItem = "[" + currentItem + "]"; return currentItem; }; - + this.getCallObjects = function (deviceString) { if (deviceString === undefined || deviceString === "") return null; @@ -1017,88 +1058,88 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n var newDevices = angular.fromJson(deviceString); var i, s, len = newDevices.length; - for (i=0; i 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); - green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); - blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); - - //Apply wide gamut conversion D65 - var X = red * 0.664511 + green * 0.154324 + blue * 0.162028; - var Y = red * 0.283881 + green * 0.668433 + blue * 0.047685; - var Z = red * 0.000088 + green * 0.072310 + blue * 0.986039; - - var fx = X / (X + Y + Z); - var fy = Y / (X + Y + Z); - if (isNaN(fx)) { - fx = 0.0; - } - if (isNaN(fy)) { - fy = 0.0; - } - - return [fx.toPrecision(4),fy.toPrecision(4)]; - }; + //Gamma corrective + red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92); + green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92); + blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); + + //Apply wide gamut conversion D65 + var X = red * 0.664511 + green * 0.154324 + blue * 0.162028; + var Y = red * 0.283881 + green * 0.668433 + blue * 0.047685; + var Z = red * 0.000088 + green * 0.072310 + blue * 0.986039; + + var fx = X / (X + Y + Z); + var fy = Y / (X + Y + Z); + if (isNaN(fx)) { + fx = 0.0; + } + if (isNaN(fy)) { + fy = 0.0; + } + + return [fx.toPrecision(4), fy.toPrecision(4)]; + }; this.testUrl = function (device, type, value, valueType) { var msgDescription = "unknown"; @@ -1405,50 +1445,49 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n addComma = true; } if (valueType === "dim" && value) { - if(addComma) + if (addComma) testBody = testBody + ","; testBody = testBody + "\"bri\":" + value; addComma = true; } if (valueType === "color" && value) { - if(addComma) + if (addComma) testBody = testBody + ","; - testBody = testBody + "\"xy\": [" + value[0] +"," + value[1] + "]"; + testBody = testBody + "\"xy\": [" + value[0] + "," + value[1] + "]"; } testBody = testBody + "}"; if (testBody === "{}") { self.displayWarn("No value available for test call...", null); return; } - + $http.put(testUrl, testBody).then( - function (response) { - if (typeof(response.data[0].success) !== 'undefined') { - msgDescription = "success " + angular.toJson(response.data); - } - if (typeof(response.data[0].error) !== 'undefined') { - if(response.data[0].error.description.indexOf("unauthorized") > -1) { - self.displayWarn("Authorization error, please retry...", null); - } - else { - msgDescription = "error " + angular.toJson(response.data[0].error); - self.displayErrorMessage("Request Error, Please look in your habridge log: ", msgDescription); - } - return; - } - - self.displaySuccess("Request Executed: " + msgDescription); - }, - function (error) { - if (error.status === 401) - $rootScope.$broadcast('securityReinit', 'done'); - else - self.displayWarn("Request Error, Pleae look in your habridge log: ", error); + function (response) { + if (typeof (response.data[0].success) !== 'undefined') { + msgDescription = "success " + angular.toJson(response.data); } + if (typeof (response.data[0].error) !== 'undefined') { + if (response.data[0].error.description.indexOf("unauthorized") > -1) { + self.displayWarn("Authorization error, please retry...", null); + } else { + msgDescription = "error " + angular.toJson(response.data[0].error); + self.displayErrorMessage("Request Error, Please look in your habridge log: ", msgDescription); + } + return; + } + + self.displaySuccess("Request Executed: " + msgDescription); + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Request Error, Pleae look in your habridge log: ", error); + } ); - return; + return; }; - + this.formatUrlItem = function (currentItem) { var formattedItem = ""; if (currentItem !== "") { @@ -1478,7 +1517,7 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (self.state.device !== undefined && self.state.device !== null && self.state.device.mapType !== undefined && self.state.device.mapType !== null && self.state.device.mapType !== "") { self.state.device.mapId = self.state.device.mapId + "-" + anId; if (dimpayload !== undefined && dimpayload !== null && dimpayload !== "") { - self.state.device.dimUrl = self.formatUrlItem(currentDim); + self.state.device.dimUrl = self.formatUrlItem(currentDim); } if (onpayload !== undefined && onpayload !== null && onpayload !== "") { @@ -1507,7 +1546,7 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (colorpayload !== undefined && colorpayload !== null && colorpayload !== "") self.state.device.colorUrl = "[{\"item\":"; } - + if (isObject) { if (dimpayload !== undefined && dimpayload !== null && dimpayload !== "") self.state.device.dimUrl = self.state.device.dimUrl + dimpayload; @@ -1517,7 +1556,7 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n self.state.device.offUrl = self.state.device.offUrl + offpayload; if (colorpayload !== undefined && colorpayload !== null && colorpayload !== "") self.state.device.colorUrl = self.state.device.colorUrl + colorpayload; - + } else { if (dimpayload !== undefined && dimpayload !== null && dimpayload !== "") self.state.device.dimUrl = self.state.device.dimUrl + "\"" + dimpayload + "\""; @@ -1528,7 +1567,7 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n if (colorpayload !== undefined && colorpayload !== null && colorpayload !== "") self.state.device.colorUrl = self.state.device.colorUrl + "\"" + colorpayload + "\""; } - + if (count !== undefined && count !== null && count !== "") { if (dimpayload !== undefined && dimpayload !== null && dimpayload !== "") self.state.device.dimUrl = self.state.device.dimUrl + ",\"count\":\"" + count; @@ -1560,350 +1599,447 @@ app.service ('bridgeService', function ($rootScope, $http, $base64, $location, n }; }); -app.controller ('SystemController', function ($scope, $location, bridgeService, ngDialog) { - bridgeService.viewConfigs(); - bridgeService.loadBridgeSettings(); - $scope.bridge = bridgeService.state; - $scope.optionalbackupname = ""; - $scope.bridge.isInControl = false; - $scope.visible = false; - $scope.imgUrl = "glyphicon glyphicon-plus"; +app.controller('SystemController', function ($scope, $location, bridgeService, ngDialog) { + bridgeService.viewConfigs(); + bridgeService.loadBridgeSettings(); + $scope.bridge = bridgeService.state; + $scope.optionalbackupname = ""; + $scope.bridge.isInControl = false; + $scope.visible = false; + $scope.imgUrl = "glyphicon glyphicon-plus"; $scope.newhassport = "8123"; $scope.newdomoticzport = "8080"; $scope.newopenhabport = "8080"; $scope.newfhemport = "8080"; - $scope.addVeratoSettings = function (newveraname, newveraip) { - if($scope.bridge.settings.veraaddress === undefined || $scope.bridge.settings.veraaddress === null) { - $scope.bridge.settings.veraaddress = { devices: [] }; + $scope.addVeratoSettings = function (newveraname, newveraip) { + if ($scope.bridge.settings.veraaddress === undefined || $scope.bridge.settings.veraaddress === null) { + $scope.bridge.settings.veraaddress = { + devices: [] + }; } - var newVera = {name: newveraname, ip: newveraip }; - $scope.bridge.settings.veraaddress.devices.push(newVera); - $scope.newveraname = null; - $scope.newveraip = null; - }; - $scope.removeVeratoSettings = function (veraname, veraip) { - for(var i = $scope.bridge.settings.veraaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.veraaddress.devices[i].name === veraname && $scope.bridge.settings.veraaddress.devices[i].ip === veraip) { - $scope.bridge.settings.veraaddress.devices.splice(i, 1); - } - } - }; - $scope.addFibarotoSettings = function (newfibaroname, newfibaroip, newfibaroport, newfibarousername, newfibaropassword, filters) { - if($scope.bridge.settings.fibaroaddress === undefined || $scope.bridge.settings.fibaroaddress === null) { - $scope.bridge.settings.fibaroaddress = { devices: [] }; + var newVera = { + name: newveraname, + ip: newveraip + }; + $scope.bridge.settings.veraaddress.devices.push(newVera); + $scope.newveraname = null; + $scope.newveraip = null; + }; + $scope.removeVeratoSettings = function (veraname, veraip) { + for (var i = $scope.bridge.settings.veraaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.veraaddress.devices[i].name === veraname && $scope.bridge.settings.veraaddress.devices[i].ip === veraip) { + $scope.bridge.settings.veraaddress.devices.splice(i, 1); + } } - var stringFilter = angular.toJson(filters); - var newFibaro = {name: newfibaroname, ip: newfibaroip, port: newfibaroport, username: newfibarousername, password: newfibaropassword, extensions: filters}; - $scope.bridge.settings.fibaroaddress.devices.push(newFibaro); - $scope.newfibaroname = null; - $scope.newfibaroip = null; - $scope.newfibaroport = null; - $scope.newfibarousername = null; - $scope.newfibaropassword = null; - }; - $scope.removeFibarotoSettings = function (fibaroname, fibaroip, fibaroport) { - for(var i = $scope.bridge.settings.fibaroaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.fibaroaddress.devices[i].name === fibaroname && $scope.bridge.settings.fibaroaddress.devices[i].ip === fibaroip && $scope.bridge.settings.fibaroaddress.devices[i].port === fibaroport) { - $scope.bridge.settings.fibaroaddress.devices.splice(i, 1); - } - } - }; - $scope.addHarmonytoSettings = function (newharmonyname, newharmonyip, newharmonywebhook) { - if($scope.bridge.settings.harmonyaddress === undefined || $scope.bridge.settings.harmonyaddress === null) { - $scope.bridge.settings.harmonyaddress = { devices: [] }; + }; + $scope.addFibarotoSettings = function (newfibaroname, newfibaroip, newfibaroport, newfibarousername, newfibaropassword, filters) { + if ($scope.bridge.settings.fibaroaddress === undefined || $scope.bridge.settings.fibaroaddress === null) { + $scope.bridge.settings.fibaroaddress = { + devices: [] + }; } - var newharmony = {name: newharmonyname, ip: newharmonyip, webhook: newharmonywebhook}; - $scope.bridge.settings.harmonyaddress.devices.push(newharmony); - $scope.newharmonyname = null; - $scope.newharmonyip = null; - }; - $scope.removeHarmonytoSettings = function (harmonyname, harmonyip) { - for(var i = $scope.bridge.settings.harmonyaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.harmonyaddress.devices[i].name === harmonyname && $scope.bridge.settings.harmonyaddress.devices[i].ip === harmonyip) { - $scope.bridge.settings.harmonyaddress.devices.splice(i, 1); - } - } - }; - $scope.addHuetoSettings = function (newhuename, newhueip) { - if($scope.bridge.settings.hueaddress === undefined || $scope.bridge.settings.hueaddress === null) { - $scope.bridge.settings.hueaddress = { devices: [] }; + var stringFilter = angular.toJson(filters); + var newFibaro = { + name: newfibaroname, + ip: newfibaroip, + port: newfibaroport, + username: newfibarousername, + password: newfibaropassword, + extensions: filters + }; + $scope.bridge.settings.fibaroaddress.devices.push(newFibaro); + $scope.newfibaroname = null; + $scope.newfibaroip = null; + $scope.newfibaroport = null; + $scope.newfibarousername = null; + $scope.newfibaropassword = null; + }; + $scope.removeFibarotoSettings = function (fibaroname, fibaroip, fibaroport) { + for (var i = $scope.bridge.settings.fibaroaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.fibaroaddress.devices[i].name === fibaroname && $scope.bridge.settings.fibaroaddress.devices[i].ip === fibaroip && $scope.bridge.settings.fibaroaddress.devices[i].port === fibaroport) { + $scope.bridge.settings.fibaroaddress.devices.splice(i, 1); + } } - var newhue = {name: newhuename, ip: newhueip }; - $scope.bridge.settings.hueaddress.devices.push(newhue); - $scope.newhuename = null; - $scope.newhueip = null; - }; - $scope.removeHuetoSettings = function (huename, hueip) { - for(var i = $scope.bridge.settings.hueaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.hueaddress.devices[i].name === huename && $scope.bridge.settings.hueaddress.devices[i].ip === hueip) { - $scope.bridge.settings.hueaddress.devices.splice(i, 1); - } - } - }; - $scope.addHaltoSettings = function (newhalname, newhalip, newhalsecure, newhaltoken) { - if($scope.bridge.settings.haladdress === undefined || $scope.bridge.settings.haladdress === null) { - $scope.bridge.settings.haladdress = { devices: [] }; + }; + $scope.addHarmonytoSettings = function (newharmonyname, newharmonyip, newharmonywebhook) { + if ($scope.bridge.settings.harmonyaddress === undefined || $scope.bridge.settings.harmonyaddress === null) { + $scope.bridge.settings.harmonyaddress = { + devices: [] + }; } - var newhal = {name: newhalname, ip: newhalip, secure: newhalsecure, password: newhaltoken }; - $scope.bridge.settings.haladdress.devices.push(newhal); - $scope.newhalname = null; - $scope.newhalip = null; - }; - $scope.removeHaltoSettings = function (halname, halip) { - for(var i = $scope.bridge.settings.haladdress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.haladdress.devices[i].name === halname && $scope.bridge.settings.haladdress.devices[i].ip === halip) { - $scope.bridge.settings.haladdress.devices.splice(i, 1); - } - } - }; - $scope.addMQTTtoSettings = function (newmqttname, newmqttip, newmqttusername, newmqttpassword) { - if($scope.bridge.settings.mqttaddress === undefined || $scope.bridge.settings.mqttaddress === null) { - $scope.bridge.settings.mqttaddress = { devices: [] }; + var newharmony = { + name: newharmonyname, + ip: newharmonyip, + webhook: newharmonywebhook + }; + $scope.bridge.settings.harmonyaddress.devices.push(newharmony); + $scope.newharmonyname = null; + $scope.newharmonyip = null; + }; + $scope.removeHarmonytoSettings = function (harmonyname, harmonyip) { + for (var i = $scope.bridge.settings.harmonyaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.harmonyaddress.devices[i].name === harmonyname && $scope.bridge.settings.harmonyaddress.devices[i].ip === harmonyip) { + $scope.bridge.settings.harmonyaddress.devices.splice(i, 1); + } } - var newmqtt = {name: newmqttname, ip: newmqttip, username: newmqttusername, password: newmqttpassword }; - $scope.bridge.settings.mqttaddress.devices.push(newmqtt); - $scope.newmqttname = null; - $scope.newmqttip = null; - $scope.newmqttusername = null; - $scope.newmqttpassword = null; - }; - $scope.removeMQTTtoSettings = function (mqttname, mqttip) { - for(var i = $scope.bridge.settings.mqttaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.mqttaddress.devices[i].name === mqttname && $scope.bridge.settings.mqttaddress.devices[i].ip === mqttip) { - $scope.bridge.settings.mqttaddress.devices.splice(i, 1); - } - } - }; - $scope.addHasstoSettings = function (newhassname, newhassip, newhassport, newhasspassword, newhasssecure) { - if($scope.bridge.settings.hassaddress === undefined || $scope.bridge.settings.hassaddress === null) { - $scope.bridge.settings.hassaddress = { devices: [] }; + }; + $scope.addHuetoSettings = function (newhuename, newhueip) { + if ($scope.bridge.settings.hueaddress === undefined || $scope.bridge.settings.hueaddress === null) { + $scope.bridge.settings.hueaddress = { + devices: [] + }; } - var newhass = {name: newhassname, ip: newhassip, port: newhassport, password: newhasspassword, secure: newhasssecure }; - $scope.bridge.settings.hassaddress.devices.push(newhass); - $scope.newhassname = null; - $scope.newhassip = null; - $scope.newhassport = null; - $scope.newhasspassword = null; - $scope.newhassport = "8123"; - }; - $scope.removeHasstoSettings = function (hassname, hassip) { - for(var i = $scope.bridge.settings.hassaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.hassaddress.devices[i].name === hassname && $scope.bridge.settings.hassaddress.devices[i].ip === hassip) { - $scope.bridge.settings.hassaddress.devices.splice(i, 1); - } - } - }; - $scope.addHomeWizardtoSettings = function (newhomewizardname, newhomewizardip, newhomewizardusername, newhomewizardpassword) { - if($scope.bridge.settings.homewizardaddress === undefined || $scope.bridge.settings.homewizardaddress === null) { - $scope.bridge.settings.homewizardaddress = { devices: [] }; - } - var newhomewizard = { name: newhomewizardname, ip: newhomewizardip, username: newhomewizardusername, password: newhomewizardpassword }; - $scope.bridge.settings.homewizardaddress.devices.push(newhomewizard); - $scope.newhomewizardname = null; - $scope.newhomewizardip = null; - $scope.newhomewizardusername = null; - $scope.newhomewizardpassword = null; - }; - $scope.removeHomeWizardtoSettings = function (homewizardname, homewizardip) { - for(var i = $scope.bridge.settings.homewizardaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.homewizardaddress.devices[i].name === homewizardname && $scope.bridge.settings.homewizardaddress.devices[i].ip === homewizardip) { - $scope.bridge.settings.homewizardaddress.devices.splice(i, 1); - } - } - }; - $scope.addDomoticztoSettings = function (newdomoticzname, newdomoticzip, newdomoticzport, newdomoticzusername, newdomoticzpassword, newdomoticzsecure) { - if($scope.bridge.settings.domoticzaddress === undefined || $scope.bridge.settings.domoticzaddress === null) { - $scope.bridge.settings.domoticzaddress = { devices: [] }; + var newhue = { + name: newhuename, + ip: newhueip + }; + $scope.bridge.settings.hueaddress.devices.push(newhue); + $scope.newhuename = null; + $scope.newhueip = null; + }; + $scope.removeHuetoSettings = function (huename, hueip) { + for (var i = $scope.bridge.settings.hueaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.hueaddress.devices[i].name === huename && $scope.bridge.settings.hueaddress.devices[i].ip === hueip) { + $scope.bridge.settings.hueaddress.devices.splice(i, 1); + } } - var newdomoticz = {name: newdomoticzname, ip: newdomoticzip, port: newdomoticzport, username: newdomoticzusername, password: newdomoticzpassword, secure: newdomoticzsecure }; - $scope.bridge.settings.domoticzaddress.devices.push(newdomoticz); - $scope.newdomoticzname = null; - $scope.newdomoticzip = null; - $scope.newdomoticzport = "8080"; - $scope.newdomoticzpassword = null; - }; - $scope.removeDomoticztoSettings = function (domoticzname, domoticzip) { - for(var i = $scope.bridge.settings.domoticzaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.domoticzaddress.devices[i].name === domoticzname && $scope.bridge.settings.domoticzaddress.devices[i].ip === domoticzip) { - $scope.bridge.settings.domoticzaddress.devices.splice(i, 1); - } - } - }; - $scope.addSomfytoSettings = function (newsomfyname, newsomfyip, newsomfyusername, newsomfypassword) { - if($scope.bridge.settings.somfyaddress == null) { - $scope.bridge.settings.somfyaddress = { devices: [] }; - } - var newSomfy = {name: newsomfyname, ip: newsomfyip, username: newsomfyusername, password: newsomfypassword }; - $scope.bridge.settings.somfyaddress.devices.push(newSomfy); - $scope.newsomfyname = null; - $scope.newsomfyip = null; - $scope.newsomfyusername = null; - $scope.newsomfypassword = null; - }; - $scope.removeSomfytoSettings = function (somfyname, somfyip) { - for(var i = $scope.bridge.settings.somfyaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.somfyaddress.devices[i].name === somfyname && $scope.bridge.settings.somfyaddress.devices[i].ip === somfyip) { - $scope.bridge.settings.somfyaddress.devices.splice(i, 1); - } - } - }; - $scope.addOpenHABtoSettings = function (newopenhabname, newopenhabip, newopenhabport, newopenhabusername, newopenhabpassword, newopenhabsecure) { - if($scope.bridge.settings.openhabaddress === undefined || $scope.bridge.settings.openhabaddress === null) { - $scope.bridge.settings.openhabaddress = { devices: [] }; + }; + $scope.addHaltoSettings = function (newhalname, newhalip, newhalsecure, newhaltoken) { + if ($scope.bridge.settings.haladdress === undefined || $scope.bridge.settings.haladdress === null) { + $scope.bridge.settings.haladdress = { + devices: [] + }; } - var newopenhab = {name: newopenhabname, ip: newopenhabip, port: newopenhabport, username: newopenhabusername, password: newopenhabpassword, secure: newopenhabsecure }; - $scope.bridge.settings.openhabaddress.devices.push(newopenhab); - $scope.newopenhabname = null; - $scope.newopenhabip = null; - $scope.newopenhabport = "8080"; - $scope.newopenhabusername = null; - $scope.newopenhabpassword = null; - }; - $scope.removeOpenHABtoSettings = function (openhabname, openhabip) { - for(var i = $scope.bridge.settings.openhabaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.openhabaddress.devices[i].name === openhabname && $scope.bridge.settings.openhabaddress.devices[i].ip === openhabip) { - $scope.bridge.settings.openhabaddress.devices.splice(i, 1); - } - } - }; + var newhal = { + name: newhalname, + ip: newhalip, + secure: newhalsecure, + password: newhaltoken + }; + $scope.bridge.settings.haladdress.devices.push(newhal); + $scope.newhalname = null; + $scope.newhalip = null; + }; + $scope.removeHaltoSettings = function (halname, halip) { + for (var i = $scope.bridge.settings.haladdress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.haladdress.devices[i].name === halname && $scope.bridge.settings.haladdress.devices[i].ip === halip) { + $scope.bridge.settings.haladdress.devices.splice(i, 1); + } + } + }; + $scope.addMQTTtoSettings = function (newmqttname, newmqttip, newmqttusername, newmqttpassword) { + if ($scope.bridge.settings.mqttaddress === undefined || $scope.bridge.settings.mqttaddress === null) { + $scope.bridge.settings.mqttaddress = { + devices: [] + }; + } + var newmqtt = { + name: newmqttname, + ip: newmqttip, + username: newmqttusername, + password: newmqttpassword + }; + $scope.bridge.settings.mqttaddress.devices.push(newmqtt); + $scope.newmqttname = null; + $scope.newmqttip = null; + $scope.newmqttusername = null; + $scope.newmqttpassword = null; + }; + $scope.removeMQTTtoSettings = function (mqttname, mqttip) { + for (var i = $scope.bridge.settings.mqttaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.mqttaddress.devices[i].name === mqttname && $scope.bridge.settings.mqttaddress.devices[i].ip === mqttip) { + $scope.bridge.settings.mqttaddress.devices.splice(i, 1); + } + } + }; + $scope.addHasstoSettings = function (newhassname, newhassip, newhassport, newhasspassword, newhasssecure) { + if ($scope.bridge.settings.hassaddress === undefined || $scope.bridge.settings.hassaddress === null) { + $scope.bridge.settings.hassaddress = { + devices: [] + }; + } + var newhass = { + name: newhassname, + ip: newhassip, + port: newhassport, + password: newhasspassword, + secure: newhasssecure + }; + $scope.bridge.settings.hassaddress.devices.push(newhass); + $scope.newhassname = null; + $scope.newhassip = null; + $scope.newhassport = null; + $scope.newhasspassword = null; + $scope.newhassport = "8123"; + }; + $scope.removeHasstoSettings = function (hassname, hassip) { + for (var i = $scope.bridge.settings.hassaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.hassaddress.devices[i].name === hassname && $scope.bridge.settings.hassaddress.devices[i].ip === hassip) { + $scope.bridge.settings.hassaddress.devices.splice(i, 1); + } + } + }; + $scope.addHomeWizardtoSettings = function (newhomewizardname, newhomewizardip, newhomewizardusername, newhomewizardpassword) { + if ($scope.bridge.settings.homewizardaddress === undefined || $scope.bridge.settings.homewizardaddress === null) { + $scope.bridge.settings.homewizardaddress = { + devices: [] + }; + } + var newhomewizard = { + name: newhomewizardname, + ip: newhomewizardip, + username: newhomewizardusername, + password: newhomewizardpassword + }; + $scope.bridge.settings.homewizardaddress.devices.push(newhomewizard); + $scope.newhomewizardname = null; + $scope.newhomewizardip = null; + $scope.newhomewizardusername = null; + $scope.newhomewizardpassword = null; + }; + $scope.removeHomeWizardtoSettings = function (homewizardname, homewizardip) { + for (var i = $scope.bridge.settings.homewizardaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.homewizardaddress.devices[i].name === homewizardname && $scope.bridge.settings.homewizardaddress.devices[i].ip === homewizardip) { + $scope.bridge.settings.homewizardaddress.devices.splice(i, 1); + } + } + }; + $scope.addDomoticztoSettings = function (newdomoticzname, newdomoticzip, newdomoticzport, newdomoticzusername, newdomoticzpassword, newdomoticzsecure) { + if ($scope.bridge.settings.domoticzaddress === undefined || $scope.bridge.settings.domoticzaddress === null) { + $scope.bridge.settings.domoticzaddress = { + devices: [] + }; + } + var newdomoticz = { + name: newdomoticzname, + ip: newdomoticzip, + port: newdomoticzport, + username: newdomoticzusername, + password: newdomoticzpassword, + secure: newdomoticzsecure + }; + $scope.bridge.settings.domoticzaddress.devices.push(newdomoticz); + $scope.newdomoticzname = null; + $scope.newdomoticzip = null; + $scope.newdomoticzport = "8080"; + $scope.newdomoticzpassword = null; + }; + $scope.removeDomoticztoSettings = function (domoticzname, domoticzip) { + for (var i = $scope.bridge.settings.domoticzaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.domoticzaddress.devices[i].name === domoticzname && $scope.bridge.settings.domoticzaddress.devices[i].ip === domoticzip) { + $scope.bridge.settings.domoticzaddress.devices.splice(i, 1); + } + } + }; + $scope.addSomfytoSettings = function (newsomfyname, newsomfyip, newsomfyusername, newsomfypassword) { + if ($scope.bridge.settings.somfyaddress == null) { + $scope.bridge.settings.somfyaddress = { + devices: [] + }; + } + var newSomfy = { + name: newsomfyname, + ip: newsomfyip, + username: newsomfyusername, + password: newsomfypassword + }; + $scope.bridge.settings.somfyaddress.devices.push(newSomfy); + $scope.newsomfyname = null; + $scope.newsomfyip = null; + $scope.newsomfyusername = null; + $scope.newsomfypassword = null; + }; + $scope.removeSomfytoSettings = function (somfyname, somfyip) { + for (var i = $scope.bridge.settings.somfyaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.somfyaddress.devices[i].name === somfyname && $scope.bridge.settings.somfyaddress.devices[i].ip === somfyip) { + $scope.bridge.settings.somfyaddress.devices.splice(i, 1); + } + } + }; + $scope.addOpenHABtoSettings = function (newopenhabname, newopenhabip, newopenhabport, newopenhabusername, newopenhabpassword, newopenhabsecure) { + if ($scope.bridge.settings.openhabaddress === undefined || $scope.bridge.settings.openhabaddress === null) { + $scope.bridge.settings.openhabaddress = { + devices: [] + }; + } + var newopenhab = { + name: newopenhabname, + ip: newopenhabip, + port: newopenhabport, + username: newopenhabusername, + password: newopenhabpassword, + secure: newopenhabsecure + }; + $scope.bridge.settings.openhabaddress.devices.push(newopenhab); + $scope.newopenhabname = null; + $scope.newopenhabip = null; + $scope.newopenhabport = "8080"; + $scope.newopenhabusername = null; + $scope.newopenhabpassword = null; + }; + $scope.removeOpenHABtoSettings = function (openhabname, openhabip) { + for (var i = $scope.bridge.settings.openhabaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.openhabaddress.devices[i].name === openhabname && $scope.bridge.settings.openhabaddress.devices[i].ip === openhabip) { + $scope.bridge.settings.openhabaddress.devices.splice(i, 1); + } + } + }; - $scope.addMozIottoSettings = function (newmoziotname, newmoziotip, newmoziotport, newmoziotusername, newmoziotpassword, newmoziotsecure) { - if($scope.bridge.settings.moziotaddress === undefined || $scope.bridge.settings.moziotaddress === null) { - $scope.bridge.settings.moziotaddress = { devices: [] }; + $scope.addMozIottoSettings = function (newmoziotname, newmoziotip, newmoziotport, newmoziotusername, newmoziotpassword, newmoziotsecure) { + if ($scope.bridge.settings.moziotaddress === undefined || $scope.bridge.settings.moziotaddress === null) { + $scope.bridge.settings.moziotaddress = { + devices: [] + }; } - var newmoziot = {name: newmoziotname, ip: newmoziotip, port: newmoziotport, username: newmoziotusername, password: newmoziotpassword, secure: newmoziotsecure }; - $scope.bridge.settings.moziotaddress.devices.push(newmoziot); - $scope.newmoziotname = null; - $scope.newmoziotip = null; - $scope.newmoziotport = "4443"; - $scope.newmoziotusername = null; - $scope.newmoziotpassword = null; - }; - $scope.removeMozIottoSettings = function (moziotname, moziotip) { - for(var i = $scope.bridge.settings.moziotaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.moziotaddress.devices[i].name === moziotname && $scope.bridge.settings.moziotaddress.devices[i].ip === moziotip) { - $scope.bridge.settings.moziotaddress.devices.splice(i, 1); - } - } - }; - - $scope.addFhemtoSettings = function (newfhemname, newfhemip, newfhemport, newfhemusername, newfhempassword, newfhemwebhook, newfhemsecure) { - if($scope.bridge.settings.fhemaddress === undefined || $scope.bridge.settings.fhemaddress === null) { - $scope.bridge.settings.fhemaddress = { devices: [] }; + var newmoziot = { + name: newmoziotname, + ip: newmoziotip, + port: newmoziotport, + username: newmoziotusername, + password: newmoziotpassword, + secure: newmoziotsecure + }; + $scope.bridge.settings.moziotaddress.devices.push(newmoziot); + $scope.newmoziotname = null; + $scope.newmoziotip = null; + $scope.newmoziotport = "4443"; + $scope.newmoziotusername = null; + $scope.newmoziotpassword = null; + }; + $scope.removeMozIottoSettings = function (moziotname, moziotip) { + for (var i = $scope.bridge.settings.moziotaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.moziotaddress.devices[i].name === moziotname && $scope.bridge.settings.moziotaddress.devices[i].ip === moziotip) { + $scope.bridge.settings.moziotaddress.devices.splice(i, 1); + } } - var newfhem = {name: newfhemname, ip: newfhemip, port: newfhemport, username: newfhemusername, password: newfhempassword, secure: newfhemsecure, webhook: newfhemwebhook }; - $scope.bridge.settings.fhemaddress.devices.push(newfhem); - $scope.newfhemname = null; - $scope.newfhemip = null; - $scope.newfhemport = "8080"; - $scope.newfhemusername = null; - $scope.newfhempassword = null; - $scope.newfhemwebhook = null; - }; - $scope.removeFhemtoSettings = function (fhemname, fhemip) { - for(var i = $scope.bridge.settings.fhemaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.fhemaddress.devices[i].name === fhemname && $scope.bridge.settings.fhemaddress.devices[i].ip === fhemip) { - $scope.bridge.settings.fhemaddress.devices.splice(i, 1); - } - } - }; + }; - $scope.bridgeReinit = function () { - bridgeService.reinit(); - }; - $scope.bridgeStop = function () { - bridgeService.stop(); - }; - $scope.saveSettings = function() { - bridgeService.saveSettings(); - }; - $scope.goBridgeUrl = function (url) { - window.open(url, "_blank"); - }; - $scope.backupSettings = function (optionalbackupname) { - bridgeService.backupSettings(optionalbackupname); - }; - $scope.restoreSettings = function (backupname) { - bridgeService.restoreSettings(backupname); - }; - $scope.deleteSettingsBackup = function (backupname) { - bridgeService.deleteSettingsBackup(backupname); - }; - $scope.toggle = function () { - $scope.visible = !$scope.visible; - if($scope.visible) - $scope.imgUrl = "glyphicon glyphicon-minus"; - else - $scope.imgUrl = "glyphicon glyphicon-plus"; - }; - - $scope.changeSeuritySettings = function () { - bridgeService.getSecurityInfo(); + $scope.addFhemtoSettings = function (newfhemname, newfhemip, newfhemport, newfhemusername, newfhempassword, newfhemwebhook, newfhemsecure) { + if ($scope.bridge.settings.fhemaddress === undefined || $scope.bridge.settings.fhemaddress === null) { + $scope.bridge.settings.fhemaddress = { + devices: [] + }; + } + var newfhem = { + name: newfhemname, + ip: newfhemip, + port: newfhemport, + username: newfhemusername, + password: newfhempassword, + secure: newfhemsecure, + webhook: newfhemwebhook + }; + $scope.bridge.settings.fhemaddress.devices.push(newfhem); + $scope.newfhemname = null; + $scope.newfhemip = null; + $scope.newfhemport = "8080"; + $scope.newfhemusername = null; + $scope.newfhempassword = null; + $scope.newfhemwebhook = null; + }; + $scope.removeFhemtoSettings = function (fhemname, fhemip) { + for (var i = $scope.bridge.settings.fhemaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.fhemaddress.devices[i].name === fhemname && $scope.bridge.settings.fhemaddress.devices[i].ip === fhemip) { + $scope.bridge.settings.fhemaddress.devices.splice(i, 1); + } + } + }; + + $scope.bridgeReinit = function () { + bridgeService.reinit(); + }; + $scope.bridgeStop = function () { + bridgeService.stop(); + }; + $scope.saveSettings = function () { + bridgeService.saveSettings(); + }; + $scope.goBridgeUrl = function (url) { + window.open(url, "_blank"); + }; + $scope.backupSettings = function (optionalbackupname) { + bridgeService.backupSettings(optionalbackupname); + }; + $scope.restoreSettings = function (backupname) { + bridgeService.restoreSettings(backupname); + }; + $scope.deleteSettingsBackup = function (backupname) { + bridgeService.deleteSettingsBackup(backupname); + }; + $scope.toggle = function () { + $scope.visible = !$scope.visible; + if ($scope.visible) + $scope.imgUrl = "glyphicon glyphicon-minus"; + else + $scope.imgUrl = "glyphicon glyphicon-plus"; + }; + + $scope.changeSeuritySettings = function () { + bridgeService.getSecurityInfo(); ngDialog.open({ template: 'views/securitydialog.html', controller: 'SecurityDialogCtrl', className: 'ngdialog-theme-default' }); - }; + }; }); -app.directive('autofocus', ['$timeout', function($timeout) { - return { - restrict: 'A', - link : function($scope, $element) { - $timeout(function() { - $element[0].focus(); - }); - } - }; - }]); +app.directive('autofocus', ['$timeout', function ($timeout) { + return { + restrict: 'A', + link: function ($scope, $element) { + $timeout(function () { + $element[0].focus(); + }); + } + }; +}]); app.directive('nuCheck', [function () { - return { - require: 'ngModel', - link: function (scope, elem, attrs, ctrl) { - var newUser = '#' + attrs.nuCheck; - elem.add(newUser).on('keyup', function () { - scope.$apply(function () { - if($(newUser).val().length > 0 ) { - scope.addingUser = true; - scope.username = $(newUser).val(); - if(scope.showPassword === false) - scope.showPassword = true; - } - else { - scope.addingUser = false; - if(scope.loggedInUser !== undefined) - scope.username = scope.loggedInUser; - scope.showPassword = scope.isSecure; - } - }); - }); - } - }; + return { + require: 'ngModel', + link: function (scope, elem, attrs, ctrl) { + var newUser = '#' + attrs.nuCheck; + elem.add(newUser).on('keyup', function () { + scope.$apply(function () { + if ($(newUser).val().length > 0) { + scope.addingUser = true; + scope.username = $(newUser).val(); + if (scope.showPassword === false) + scope.showPassword = true; + } else { + scope.addingUser = false; + if (scope.loggedInUser !== undefined) + scope.username = scope.loggedInUser; + scope.showPassword = scope.isSecure; + } + }); + }); + } + }; }]); app.directive('pwCheck', [function () { - return { - require: 'ngModel', - link: function (scope, elem, attrs, ctrl) { - var firstPassword = '#' + attrs.pwCheck; - elem.add(firstPassword).on('keyup', function () { - scope.$apply(function () { - var isMatched = false; - if(elem.val().length > 0 && $(firstPassword).val().length > 0) - isMatched = (elem.val() === $(firstPassword).val()); - ctrl.$setValidity('pwmatch', isMatched); - scope.matched = isMatched; - }); - }); - } - }; + return { + require: 'ngModel', + link: function (scope, elem, attrs, ctrl) { + var firstPassword = '#' + attrs.pwCheck; + elem.add(firstPassword).on('keyup', function () { + scope.$apply(function () { + var isMatched = false; + if (elem.val().length > 0 && $(firstPassword).val().length > 0) + isMatched = (elem.val() === $(firstPassword).val()); + ctrl.$setValidity('pwmatch', isMatched); + scope.matched = isMatched; + }); + }); + } + }; }]); app.controller('SecurityDialogCtrl', function ($scope, bridgeService, ngDialog) { $scope.loggedInUser = bridgeService.state.loggedInUser; - if(bridgeService.state.loggedInUser !== undefined) + if (bridgeService.state.loggedInUser !== undefined) $scope.username = bridgeService.state.loggedInUser; else $scope.username = ""; @@ -1919,38 +2055,38 @@ app.controller('SecurityDialogCtrl', function ($scope, bridgeService, ngDialog) $scope.setSecurityInfo = function () { bridgeService.changeSecuritySettings($scope.useLinkButton, $scope.secureHueApi, $scope.execGarden); }; - + $scope.changePassword = function (password, password2) { bridgeService.changePassword(password, password2); }; - + $scope.addUser = function (newUser, password, password2) { bridgeService.addUser(newUser, password, password2); $scope.addingUser = false; - if(bridgeService.staet.loggedInUser !== undefined) + if (bridgeService.staet.loggedInUser !== undefined) $scope.username = bridgeService.state.loggedInUser; else $scope.username = ""; $scope.showPassword = $scope.isSecure; }; - + $scope.delUser = function (newUser) { bridgeService.delUser(newUser); $scope.addingUser = false; - if(bridgeService.state.loggedInUser !== undefined) + if (bridgeService.state.loggedInUser !== undefined) $scope.username = bridgeService.state.loggedInUser; else $scope.username = ""; bridgeService.getHABridgeVersion(); $scope.showPassword = $scope.isSecure; }; - + $scope.dismissDialog = function () { ngDialog.close('ngdialog1'); }; - + $scope.setBlankPassword = function (theElementName) { - if($scope.firstTime) { + if ($scope.firstTime) { var theElement = "#" + theElementName; $(theElement).strength(); $scope.firstTime = false; @@ -1966,49 +2102,48 @@ app.controller('ManageLinksDialogCtrl', function ($scope, bridgeService, ngDialo bridgeService.setWhitelist($scope.whitelist); ngDialog.close('ngdialog1'); }; - + $scope.delEntry = function (anEntry) { - for(var key in $scope.whitelist) { - if ($scope.whitelist.hasOwnProperty(key)) { - var theEntry = $scope.whitelist[key]; - if(theEntry.name === anEntry) { - delete $scope.whitelist[key]; - } - } - } + for (var key in $scope.whitelist) { + if ($scope.whitelist.hasOwnProperty(key)) { + var theEntry = $scope.whitelist[key]; + if (theEntry.name === anEntry) { + delete $scope.whitelist[key]; + } + } + } }; - - $scope.refresh = function () { + + $scope.refresh = function () { bridgeService.getWhitelist(); $scope.whitelist = bridgeService.state.whitelist; }; - + $scope.delAll = function () { $scope.whitelist = null; }; - + $scope.dismissDialog = function () { ngDialog.close('ngdialog1'); }; }); app.controller('LogsController', function ($scope, $location, bridgeService) { - bridgeService.viewLogs(); - $scope.bridge = bridgeService.state; - $scope.levels = ["INFO_INT", "WARN_INT", "DEBUG_INT", "TRACE_INT"]; + bridgeService.viewLogs(); + $scope.bridge = bridgeService.state; + $scope.levels = ["INFO_INT", "WARN_INT", "DEBUG_INT", "TRACE_INT"]; $scope.updateComponents = []; $scope.visible = false; $scope.imgUrl = "glyphicon glyphicon-plus"; - $scope.updateLogs = function() { + $scope.updateLogs = function () { bridgeService.viewLogs(); }; $scope.toggle = function () { $scope.visible = !$scope.visible; - if($scope.visible) { + if ($scope.visible) { $scope.imgUrl = "glyphicon glyphicon-minus"; - bridgeService.viewLoggerInfo(); - } - else + bridgeService.viewLoggerInfo(); + } else $scope.imgUrl = "glyphicon glyphicon-plus"; }; $scope.addToUpdate = function (logInfo) { @@ -2024,11 +2159,11 @@ app.controller('LogsController', function ($scope, $location, bridgeService) { $scope.updateComponents.push(logInfo); } }; - + $scope.updateLoggers = function () { bridgeService.updateLogLevels($scope.updateComponents); }; - + $scope.reloadLoggers = function () { bridgeService.viewLoggerInfo(); }; @@ -2037,22 +2172,22 @@ app.controller('LogsController', function ($scope, $location, bridgeService) { app.directive('postrenderAction', postrenderAction); /* @ngInject */ function postrenderAction($timeout) { - // ### Directive Interface - // Defines base properties for the directive. - var directive = { - restrict: 'A', - priority: 101, - link: link - }; - return directive; + // ### Directive Interface + // Defines base properties for the directive. + var directive = { + restrict: 'A', + priority: 101, + link: link + }; + return directive; - // ### Link Function - // Provides functionality for the directive during the DOM building/data binding stage. - function link(scope, element, attrs) { - $timeout(function() { - scope.$evalAsync(attrs.postrenderAction); - }, 0); - } + // ### Link Function + // Provides functionality for the directive during the DOM building/data binding stage. + function link(scope, element, attrs) { + $timeout(function () { + scope.$evalAsync(attrs.postrenderAction); + }, 0); + } } app.controller('ViewingController', function ($scope, $location, bridgeService, ngDialog) { @@ -2069,8 +2204,8 @@ app.controller('ViewingController', function ($scope, $location, bridgeService, $scope.testUrl = function (device, type) { var dialogNeeded = false; if ((type === "on" && device.onUrl !== undefined && bridgeService.aContainsB(device.onUrl, "${intensity")) || - (type === "off" && device.offUrl !== undefined && bridgeService.aContainsB(device.offUrl, "${intensity")) || - (type === "dim" && device.dimUrl !== undefined)) { + (type === "off" && device.offUrl !== undefined && bridgeService.aContainsB(device.offUrl, "${intensity")) || + (type === "dim" && device.dimUrl !== undefined)) { $scope.bridge.device = device; $scope.bridge.type = type; ngDialog.open({ @@ -2078,10 +2213,9 @@ app.controller('ViewingController', function ($scope, $location, bridgeService, controller: 'ValueDialogCtrl', className: 'ngdialog-theme-default' }); - } - else if ((type === "on" && device.onUrl !== undefined && bridgeService.aContainsB(device.onUrl, "${color")) || - (type === "off" && device.offUrl !== undefined && bridgeService.aContainsB(device.offUrl, "${color")) || - (type === "color" && device.colorUrl !== undefined)) { + } else if ((type === "on" && device.onUrl !== undefined && bridgeService.aContainsB(device.onUrl, "${color")) || + (type === "off" && device.offUrl !== undefined && bridgeService.aContainsB(device.offUrl, "${color")) || + (type === "color" && device.colorUrl !== undefined)) { $scope.bridge.device = device; $scope.bridge.type = type; ngDialog.open({ @@ -2089,8 +2223,7 @@ app.controller('ViewingController', function ($scope, $location, bridgeService, controller: 'ColorDialogCtrl', className: 'ngdialog-theme-default' }); - } - else + } else bridgeService.testUrl(device, type, null, type); }; $scope.deleteDevice = function (device) { @@ -2105,13 +2238,13 @@ app.controller('ViewingController', function ($scope, $location, bridgeService, bridgeService.editDevice(device); $location.path('/editdevice'); }; - $scope.renumberDevices = function() { + $scope.renumberDevices = function () { bridgeService.renumberDevices(); }; - $scope.pushLinkButton = function() { + $scope.pushLinkButton = function () { bridgeService.pushLinkButton(); }; - $scope.manageLinksButton = function() { + $scope.manageLinksButton = function () { ngDialog.open({ template: 'views/managelinksdialog.html', controller: 'ManageLinksDialogCtrl', @@ -2129,54 +2262,53 @@ app.controller('ViewingController', function ($scope, $location, bridgeService, }; $scope.toggle = function () { $scope.visible = !$scope.visible; - if($scope.visible) + if ($scope.visible) $scope.imgUrl = "glyphicon glyphicon-minus"; else $scope.imgUrl = "glyphicon glyphicon-plus"; }; $scope.toggleBk = function () { $scope.visibleBk = !$scope.visibleBk; - if($scope.visibleBk) + if ($scope.visibleBk) $scope.imgBkUrl = "glyphicon glyphicon-minus"; else $scope.imgBkUrl = "glyphicon glyphicon-plus"; }; - $scope.goToRow = function() { + $scope.goToRow = function () { if (bridgeService.state.queueDevId !== null && bridgeService.state.queueDevId !== "") { - bridgeService.state.viewDevId = bridgeService.state.queueDevId; - $scope.$broadcast("rowSelected", bridgeService.state.viewDevId); - console.log("Go to Row selected Id <<" + bridgeService.state.viewDevId + ">>"); - bridgeService.state.queueDevId = null; - } - }; - }); + bridgeService.state.viewDevId = bridgeService.state.queueDevId; + $scope.$broadcast("rowSelected", bridgeService.state.viewDevId); + console.log("Go to Row selected Id <<" + bridgeService.state.viewDevId + ">>"); + bridgeService.state.queueDevId = null; + } + }; +}); app.controller('ValueDialogCtrl', function ($scope, bridgeService, ngDialog) { $scope.slider = { - value: 100, - options: { - floor: 1, - ceil: 100, - showSelectionBar: true - } - }; + value: 100, + options: { + floor: 1, + ceil: 100, + showSelectionBar: true + } + }; $scope.bridge = bridgeService.state; $scope.valueType = "percentage"; $scope.changeScale = function () { - if($scope.valueType === "raw") { - $scope.slider.options.ceil = 254; + if ($scope.valueType === "raw") { + $scope.slider.options.ceil = 254; $scope.slider.value = 254; - } - else { - $scope.slider.options.ceil = 100; - $scope.slider.value = 100; + } else { + $scope.slider.options.ceil = 100; + $scope.slider.value = 100; } }; $scope.setValue = function () { ngDialog.close('ngdialog1'); var theValue = 1; - if($scope.valueType === "percentage") + if ($scope.valueType === "percentage") theValue = Math.round(($scope.slider.value * 0.01) * 255); else theValue = $scope.slider.value; @@ -2188,13 +2320,13 @@ app.controller('ValueDialogCtrl', function ($scope, bridgeService, ngDialog) { app.controller('ColorDialogCtrl', function ($scope, bridgeService, ngDialog) { $scope.rgbPicker = { - color: 'rgb(255,255,255)' - }; + color: 'rgb(255,255,255)' + }; $scope.bridge = bridgeService.state; $scope.setValue = function () { ngDialog.close('ngdialog1'); - var next = $scope.rgbPicker.color.substr($scope.rgbPicker.color.indexOf('(') + 1); + var next = $scope.rgbPicker.color.substr($scope.rgbPicker.color.indexOf('(') + 1); var red = next.substr(0, next.indexOf(',')); next = next.substr(next.indexOf(',') + 1); var green = next.substr(0, next.indexOf(',')); @@ -2223,9 +2355,15 @@ app.controller('VeraController', function ($scope, $location, bridgeService, ngD $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; - $scope.vera = {base: "http://", port: "3480", id: ""}; + $scope.vera = { + base: "http://", + port: "3480", + id: "" + }; bridgeService.viewVeraDevices(); bridgeService.viewVeraScenes(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -2238,30 +2376,29 @@ app.controller('VeraController', function ($scope, $location, bridgeService, ngD }; $scope.buildDeviceUrls = function (veradevice, dim_control, buildonly) { - if(dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) { - dimpayload = "http://" + veradevice.veraaddress + ":" + $scope.vera.port + + if (dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) { + dimpayload = "http://" + veradevice.veraaddress + ":" + $scope.vera.port + "/data_request?id=action&output_format=json&DeviceNum=" + veradevice.id + "&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=" + dim_control; - } - else - dimpayload = "http://" + veradevice.veraaddress + ":" + $scope.vera.port + - "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=" + - veradevice.id; - onpayload = "http://" + veradevice.veraaddress + ":" + $scope.vera.port + - "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=" + - veradevice.id; - offpayload = "http://" + veradevice.veraaddress + ":" + $scope.vera.port + - "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=" + - veradevice.id; - - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, veradevice.id, veradevice.name, veradevice.veraname, "switch", "veraDevice", null, null); - $scope.device = bridgeService.state.device; - if (!buildonly) { - bridgeService.editNewDevice($scope.device); - $location.path('/editdevice'); - } + } else + dimpayload = "http://" + veradevice.veraaddress + ":" + $scope.vera.port + + "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=" + + veradevice.id; + onpayload = "http://" + veradevice.veraaddress + ":" + $scope.vera.port + + "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=" + + veradevice.id; + offpayload = "http://" + veradevice.veraaddress + ":" + $scope.vera.port + + "/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=" + + veradevice.id; + + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, veradevice.id, veradevice.name, veradevice.veraname, "switch", "veraDevice", null, null); + $scope.device = bridgeService.state.device; + if (!buildonly) { + bridgeService.editNewDevice($scope.device); + $location.path('/editdevice'); + } }; $scope.buildSceneUrls = function (verascene) { @@ -2278,46 +2415,48 @@ app.controller('VeraController', function ($scope, $location, bridgeService, ngD $location.path('/editdevice'); }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.veradevices.length; x++) { - if(bridgeService.state.veradevices[x].id === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.veradevices[x],dim_control,true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.veradevices.length; x++) { + if (bridgeService.state.veradevices[x].id === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.veradevices[x], dim_control, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewVeraDevices(); - bridgeService.viewVeraScenes(); - }, - function (error) { - bridgeService.displayWarn("Error adding Vera devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewVeraDevices(); + bridgeService.viewVeraScenes(); + }, + function (error) { + bridgeService.displayWarn("Error adding Vera devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -2327,7 +2466,7 @@ app.controller('VeraController', function ($scope, $location, bridgeService, ngD // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -2339,14 +2478,15 @@ app.controller('VeraController', function ($scope, $location, bridgeService, ngD }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.veradevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.veradevices[x]) < 0) + for (var x = 0; x < bridgeService.state.veradevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.veradevices[x]) < 0) $scope.bulk.devices.push(bridgeService.state.veradevices[x].id); } } @@ -2354,7 +2494,7 @@ app.controller('VeraController', function ($scope, $location, bridgeService, ngD $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -2368,7 +2508,7 @@ app.controller('VeraController', function ($scope, $location, bridgeService, ngD className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -2379,9 +2519,15 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; - $scope.fibaro = {base: "http://", port: "80", id: ""}; + $scope.fibaro = { + base: "http://", + port: "80", + id: "" + }; bridgeService.viewFibaroDevices(); bridgeService.viewFibaroScenes(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -2395,13 +2541,13 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n $scope.buildDeviceUrls = function (fibarodevice, dim_control, buildonly) { var dimpayload = null; - if(dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) + if (dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) dimpayload = "http://" + fibarodevice.fibaroaddress + ":" + fibarodevice.fibaroport + "/api/callAction?deviceID=" + fibarodevice.id + "&name=setValue&arg1=" + dim_control; - + 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, null, 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) { @@ -2423,45 +2569,47 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n $location.path('/editdevice'); }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.fibarodevices.length; x++) { - if(bridgeService.state.fibarodevices[x].id === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.fibarodevices[x],dim_control,true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.fibarodevices.length; x++) { + if (bridgeService.state.fibarodevices[x].id === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.fibarodevices[x], dim_control, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewfibaroDevices(); - bridgeService.viewfibaroScenes(); - }, - function (error) { - bridgeService.displayWarn("Error adding fibaro devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewfibaroDevices(); + bridgeService.viewfibaroScenes(); + }, + function (error) { + bridgeService.displayWarn("Error adding fibaro devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -2471,7 +2619,7 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -2483,14 +2631,15 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.fibarodevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.fibarodevices[x]) < 0) + for (var x = 0; x < bridgeService.state.fibarodevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.fibarodevices[x]) < 0) $scope.bulk.devices.push(bridgeService.state.fibarodevices[x].id); } } @@ -2498,7 +2647,7 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -2512,7 +2661,7 @@ app.controller('FibaroController', function ($scope, $location, bridgeService, n className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -2538,9 +2687,9 @@ app.controller('HarmonyController', function ($scope, $location, bridgeService, $scope.buildActivityUrls = function (harmonyactivity) { onpayload = "{\"name\":\"" + harmonyactivity.activity.id + "\",\"hub\":\"" + harmonyactivity.hub + "\"}"; - offpayload = "{\"name\":\"-1\",\"hub\":\"" + harmonyactivity.hub + "\"}"; + offpayload = "{\"name\":\"-1\",\"hub\":\"" + harmonyactivity.hub + "\"}"; - bridgeService.buildUrls(onpayload, null, offpayload, null, true, harmonyactivity.activity.id, harmonyactivity.activity.label, harmonyactivity.hub, "activity", "harmonyActivity", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, true, harmonyactivity.activity.id, harmonyactivity.activity.label, harmonyactivity.hub, "activity", "harmonyActivity", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -2550,16 +2699,16 @@ app.controller('HarmonyController', function ($scope, $location, bridgeService, var actionOn = angular.fromJson(onbutton); var actionOff = angular.fromJson(offbutton); var postCmd = "\"}"; - if(onpresstime !== undefined && onpresstime !== "0") - postCmd = "\",\"pressTime\":" + onpresstime + "}"; + if (onpresstime !== undefined && onpresstime !== "0") + postCmd = "\",\"pressTime\":" + onpresstime + "}"; onpayload = "{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOn.command + "\",\"hub\":\"" + harmonydevice.hub + postCmd; - if(offpresstime !== undefined && offpresstime !== "0") - postCmd = "\",\"pressTime\":" + offpresstime + "}"; + if (offpresstime !== undefined && offpresstime !== "0") + postCmd = "\",\"pressTime\":" + offpresstime + "}"; else postCmd = "\"}"; offpayload = "{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOff.command + "\",\"hub\":\"" + harmonydevice.hub + postCmd; - bridgeService.buildUrls(onpayload, null, offpayload, null, true, actionOn.command, harmonydevice.device.label, harmonydevice.hub, "button", "harmonyButton", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, true, actionOn.command, harmonydevice.device.label, harmonydevice.hub, "button", "harmonyButton", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -2567,7 +2716,7 @@ app.controller('HarmonyController', function ($scope, $location, bridgeService, $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -2581,7 +2730,7 @@ app.controller('HarmonyController', function ($scope, $location, bridgeService, className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -2603,7 +2752,7 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD $scope.buildNestHomeUrls = function (nestitem) { onpayload = "{\"name\":\"" + nestitem.id + "\",\"away\":false,\"control\":\"status\"}"; offpayload = "{\"name\":\"" + nestitem.id + "\",\"away\":true,\"control\":\"status\"}"; - bridgeService.buildUrls(onpayload, null, offpayload, null, true, nestitem.id, nestitem.name, nestitem.name, "home", "nestHomeAway", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, true, nestitem.id, nestitem.name, nestitem.name, "home", "nestHomeAway", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -2613,7 +2762,7 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD onpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"temp\",\"temp\":\"${intensity.percent}\"}"; dimpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"temp\",\"temp\":\"${intensity.percent}\"}"; offpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"off\"}"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, nestitem.id + "-SetTemp", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Temperature", nestitem.location, "thermo", "nestThermoSet", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, nestitem.id + "-SetTemp", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Temperature", nestitem.location, "thermo", "nestThermoSet", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -2623,7 +2772,7 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD onpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"heat\"}"; dimpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"temp\",\"temp\":\"${intensity.percent}\"}"; offpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"off\"}"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, nestitem.id + "-SetHeat", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Heat", nestitem.location, "thermo", "nestThermoSet", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, nestitem.id + "-SetHeat", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Heat", nestitem.location, "thermo", "nestThermoSet", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -2633,7 +2782,7 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD onpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"cool\"}"; dimpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"temp\",\"temp\":\"${intensity.percent}\"}"; offpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"off\"}"; - bridgeService.buildUrls(onpayload,dimpayload, offpayload, null, true, nestitem.id + "-SetCool", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Cool", nestitem.location, "thermo", "nestThermoSet", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, nestitem.id + "-SetCool", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Cool", nestitem.location, "thermo", "nestThermoSet", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -2642,7 +2791,7 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD $scope.buildNestRangeUrls = function (nestitem) { onpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"range\"}"; offpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"off\"}"; - bridgeService.buildUrls(onpayload, null, offpayload, null, true, nestitem.id + "-SetRange", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Range", nestitem.location, "thermo", "nestThermoSet", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, true, nestitem.id + "-SetRange", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Range", nestitem.location, "thermo", "nestThermoSet", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -2651,7 +2800,7 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD $scope.buildNestOffUrls = function (nestitem) { onpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"range\"}"; offpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"off\"}"; - bridgeService.buildUrls(onpayload, null, offpayload, null, true, nestitem.id + "-TurnOff", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Thermostat", nestitem.location, "thermo", "nestThermoSet", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, true, nestitem.id + "-TurnOff", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Thermostat", nestitem.location, "thermo", "nestThermoSet", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -2660,7 +2809,7 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD $scope.buildNestFanUrls = function (nestitem) { onpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"fan-on\"}"; offpayload = "{\"name\":\"" + nestitem.id + "\",\"control\":\"fan-auto\"}"; - bridgeService.buildUrls(onpayload, null, offpayload, null, true, nestitem.id + "-SetFan", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Fan", nestitem.location, "thermo", "nestThermoSet", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, true, nestitem.id + "-SetFan", nestitem.name.substr(0, nestitem.name.indexOf("(")) + " Fan", nestitem.location, "thermo", "nestThermoSet", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -2668,7 +2817,7 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -2682,7 +2831,7 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -2692,7 +2841,9 @@ app.controller('NestController', function ($scope, $location, bridgeService, ngD app.controller('HueController', function ($scope, $location, bridgeService, ngDialog) { $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; bridgeService.viewHueDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -2704,9 +2855,9 @@ app.controller('HueController', function ($scope, $location, bridgeService, ngDi }; $scope.buildDeviceUrls = function (huedevice, buildonly) { - onpayload = "{\"ipAddress\":\"" + huedevice.hueaddress + "\",\"deviceId\":\"" + huedevice.huedeviceid +"\",\"hueName\":\"" + huedevice.huename + "\"}"; - offpayload = "{\"ipAddress\":\"" + huedevice.hueaddress + "\",\"deviceId\":\"" + huedevice.huedeviceid +"\",\"hueName\":\"" + huedevice.huename + "\"}"; - bridgeService.buildUrls(onpayload, null, offpayload, null, true, huedevice.device.uniqueid, huedevice.device.name, huedevice.huename, "passthru", "hueDevice", null, null); + onpayload = "{\"ipAddress\":\"" + huedevice.hueaddress + "\",\"deviceId\":\"" + huedevice.huedeviceid + "\",\"hueName\":\"" + huedevice.huename + "\"}"; + offpayload = "{\"ipAddress\":\"" + huedevice.hueaddress + "\",\"deviceId\":\"" + huedevice.huedeviceid + "\",\"hueName\":\"" + huedevice.huename + "\"}"; + bridgeService.buildUrls(onpayload, null, offpayload, null, true, huedevice.device.uniqueid, huedevice.device.name, huedevice.huename, "passthru", "hueDevice", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -2714,46 +2865,48 @@ app.controller('HueController', function ($scope, $location, bridgeService, ngDi } }; - $scope.bulkAddDevices = function() { + $scope.bulkAddDevices = function () { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.huedevices.length; x++) { - if(bridgeService.state.huedevices[x].device.uniqueid === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.huedevices[x],true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.huedevices.length; x++) { + if (bridgeService.state.huedevices[x].device.uniqueid === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.huedevices[x], true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHueDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding Hue devices in bulk.", error); - } - ); + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHueDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding Hue devices in bulk.", error); + } + ); - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -2763,7 +2916,7 @@ app.controller('HueController', function ($scope, $location, bridgeService, ngDi // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -2775,14 +2928,15 @@ app.controller('HueController', function ($scope, $location, bridgeService, ngDi }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.huedevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.huedevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.huedevices[x].device.uniqueid, bridgeService.state.huedevices[x].huename, "hueDevice")) + for (var x = 0; x < bridgeService.state.huedevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.huedevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.huedevices[x].device.uniqueid, bridgeService.state.huedevices[x].huename, "hueDevice")) $scope.bulk.devices.push(bridgeService.state.huedevices[x].device.uniqueid); } } @@ -2790,7 +2944,7 @@ app.controller('HueController', function ($scope, $location, bridgeService, ngDi $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -2804,7 +2958,7 @@ app.controller('HueController', function ($scope, $location, bridgeService, ngDi className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -2815,7 +2969,9 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; bridgeService.viewHalDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -2832,30 +2988,27 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi var preOffCmd = ""; var nameCmd = ""; var aDeviceType; - if(haldevice.haldevicetype === "Group") { + if (haldevice.haldevicetype === "Group") { aDeviceType = "group"; preOnCmd = "/GroupService!GroupCmd=On"; preOffCmd = "/GroupService!GroupCmd=Off"; nameCmd = "!GroupName="; - } - else if(haldevice.haldevicetype === "Macro") { + } else if (haldevice.haldevicetype === "Macro") { aDeviceType = "macro"; preOnCmd = "/MacroService!MacroCmd=Set!MacroName="; preOffCmd = preOnCmd; - } - else if(haldevice.haldevicetype === "Scene") { + } else if (haldevice.haldevicetype === "Scene") { aDeviceType = "scene"; preOnCmd = "/SceneService!SceneCmd=Set!SceneName="; preOffCmd = preOnCmd; - } - else { + } else { aDeviceType = "switch"; preOnCmd = "/DeviceService!DeviceCmd=SetDevice!DeviceValue=On"; preDimCmd = "/DeviceService!DeviceCmd=SetDevice!DeviceValue=Dim!DevicePercent="; preOffCmd = "/DeviceService!DeviceCmd=SetDevice!DeviceValue=Off"; nameCmd = "!DeviceName="; } - if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) && aDeviceType === "switch") + if ((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) && aDeviceType === "switch") dimpayload = "http://" + haldevice.haladdress.ip + preDimCmd + dim_control + @@ -2867,14 +3020,14 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi nameCmd + haldevice.haldevicename.replaceAll(" ", "%20"); onpayload = "http://" + haldevice.haladdress.ip + - preOnCmd + - nameCmd + - haldevice.haldevicename.replaceAll(" ", "%20"); - offpayload = "http://" + haldevice.haladdress.ip + - preOffCmd + - nameCmd + - haldevice.haldevicename.replaceAll(" ", "%20"); - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name, haldevice.haldevicename, haldevice.haladdress.name, aDeviceType, "halDevice", null, null); + preOnCmd + + nameCmd + + haldevice.haldevicename.replaceAll(" ", "%20"); + offpayload = "http://" + haldevice.haladdress.ip + + preOffCmd + + nameCmd + + haldevice.haldevicename.replaceAll(" ", "%20"); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name, haldevice.haldevicename, haldevice.haladdress.name, aDeviceType, "halDevice", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -2888,7 +3041,7 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi onpayload = "http://" + haldevice.haladdress.ip + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOn.DeviceName.replaceAll(" ", "%20"); offpayload = "http://" + haldevice.haladdress.ip + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOff.DeviceName.replaceAll(" ", "%20"); - bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-" + actionOn.DeviceName, haldevice.haldevicename, haldevice.haladdress.name, "button", "halButton", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-" + actionOn.DeviceName, haldevice.haldevicename, haldevice.haladdress.name, "button", "halButton", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -2899,7 +3052,7 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi $scope.buildHALHomeUrls = function (haldevice, buildonly) { onpayload = "http://" + haldevice.haladdress.ip + "/ModeService!ModeCmd=Set!ModeName=Home"; offpayload = "http://" + haldevice.haladdress.ip + "/ModeService!ModeCmd=Set!ModeName=Away"; - bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-HomeAway", haldevice.haldevicename, haldevice.haladdress.name, "home", "halHome", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-HomeAway", haldevice.haldevicename, haldevice.haladdress.name, "home", "halHome", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -2909,18 +3062,18 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi $scope.buildHALHeatUrls = function (haldevice, buildonly) { onpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Heat"; + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Heat"; dimpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Heat!HeatSpValue=${intensity.percent}"; + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Heat!HeatSpValue=${intensity.percent}"; offpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Off"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-SetHeat", haldevice.haldevicename + " Heat", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Off"; + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-SetHeat", haldevice.haldevicename + " Heat", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -2930,18 +3083,18 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi $scope.buildHALCoolUrls = function (haldevice, buildonly) { onpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Cool"; + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Cool"; dimpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Cool!CoolSpValue=${intensity.percent}"; + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Cool!CoolSpValue=${intensity.percent}"; offpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Off"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-SetCool", haldevice.haldevicename + " Cool", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Off"; + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-SetCool", haldevice.haldevicename + " Cool", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -2951,14 +3104,14 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi $scope.buildHALAutoUrls = function (haldevice, buildonly) { onpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Auto"; + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Auto"; offpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Off"; - bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-SetAuto", haldevice.haldevicename + " Auto", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Off"; + bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-SetAuto", haldevice.haldevicename + " Auto", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -2968,14 +3121,14 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi $scope.buildHALOffUrls = function (haldevice, buildonly) { onpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Auto"; + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Auto"; offpayload = "http://" + haldevice.haladdress.ip + - "/HVACService!HVACCmd=Set!HVACName=" + - haldevice.haldevicename.replaceAll(" ", "%20") + - "!HVACMode=Off"; - bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-TurnOff", haldevice.haldevicename + " Thermostat", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); + "/HVACService!HVACCmd=Set!HVACName=" + + haldevice.haldevicename.replaceAll(" ", "%20") + + "!HVACMode=Off"; + bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-TurnOff", haldevice.haldevicename + " Thermostat", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -2992,7 +3145,7 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi "/HVACService!HVACCmd=Set!HVACName=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!FanMode=Auto"; - bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-SetFan", haldevice.haldevicename + " Fan", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, false, haldevice.haldevicename + "-" + haldevice.haladdress.name + "-SetFan", haldevice.haldevicename + " Fan", haldevice.haladdress.name, "thermo", "halThermoSet", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -3000,50 +3153,52 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi } }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.haldevices.length; x++) { - if(bridgeService.state.haldevices[x].haldevicename === $scope.bulk.devices[i]) { - if(bridgeService.state.haldevices[x].haldevicetype === "HVAC") + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.haldevices.length; x++) { + if (bridgeService.state.haldevices[x].haldevicename === $scope.bulk.devices[i]) { + if (bridgeService.state.haldevices[x].haldevicetype === "HVAC") $scope.buildHALAutoUrls(bridgeService.state.haldevices[x], true); - else if(bridgeService.state.haldevices[x].haldevicetype === "HOME") + else if (bridgeService.state.haldevices[x].haldevicetype === "HOME") $scope.buildHALHomeUrls(bridgeService.state.haldevices[x], true); else - $scope.buildDeviceUrls(bridgeService.state.haldevices[x],dim_control, true); + $scope.buildDeviceUrls(bridgeService.state.haldevices[x], dim_control, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHalDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding HAL devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHalDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding HAL devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -3053,7 +3208,7 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -3065,14 +3220,15 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.haldevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.haldevices[x]) < 0) + for (var x = 0; x < bridgeService.state.haldevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.haldevices[x]) < 0) $scope.bulk.devices.push(bridgeService.state.haldevices[x].haldevicename); } } @@ -3080,7 +3236,7 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3094,7 +3250,7 @@ app.controller('HalController', function ($scope, $location, bridgeService, ngDi className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -3116,14 +3272,14 @@ app.controller('MQTTController', function ($scope, $location, bridgeService, ngD }; $scope.buildMQTTPublish = function (mqttbroker, mqtttopic, mqttmessage, mqttqos, mqttretain) { - if(mqttretain === 'undefined') + if (mqttretain === 'undefined') mqttretain = false; - if(mqttqos === 'undefined') + if (mqttqos === 'undefined') mqttqos = 1; onpayload = "{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\",\"qos\":\"" + mqttqos + "\",\"retain\":\"" + mqttretain + "\"}"; offpayload = "{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\",\"qos\":\"" + mqttqos + "\",\"retain\":\"" + mqttretain + "\"}"; - bridgeService.buildUrls(onpayload, null, offpayload, null, true, mqttbroker.clientId + "-" + mqtttopic, mqttbroker.clientId + mqtttopic, mqttbroker.clientId, "mqtt", "mqttMessage", null, null); + bridgeService.buildUrls(onpayload, null, offpayload, null, true, mqttbroker.clientId + "-" + mqtttopic, mqttbroker.clientId + mqtttopic, mqttbroker.clientId, "mqtt", "mqttMessage", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); @@ -3131,7 +3287,7 @@ app.controller('MQTTController', function ($scope, $location, bridgeService, ngD $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3145,7 +3301,7 @@ app.controller('MQTTController', function ($scope, $location, bridgeService, ngD className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -3156,7 +3312,9 @@ app.controller('HassController', function ($scope, $location, bridgeService, ngD $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; bridgeService.viewHassDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3169,13 +3327,13 @@ app.controller('HassController', function ($scope, $location, bridgeService, ngD $scope.buildDeviceUrls = function (hassdevice, dim_control, buildonly) { onpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}"; - if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) + if ((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"}"; else dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}"; offpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"off\"}"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, hassdevice.hassname + "-" + hassdevice.deviceState.entity_id, hassdevice.deviceState.entity_id, hassdevice.hassname, hassdevice.domain, "hassDevice", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, hassdevice.hassname + "-" + hassdevice.deviceState.entity_id, hassdevice.deviceState.entity_id, hassdevice.hassname, hassdevice.domain, "hassDevice", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -3183,45 +3341,47 @@ app.controller('HassController', function ($scope, $location, bridgeService, ngD } }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.hassdevices.length; x++) { - if(bridgeService.state.hassdevices[x].deviceState.entity_id === $scope.bulk.devices[i] && bridgeService.state.hassdevices[x].domain !== "sensor" && bridgeService.state.hassdevices[x].domain !== "sun") { - $scope.buildDeviceUrls(bridgeService.state.hassdevices[x],dim_control,true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.hassdevices.length; x++) { + if (bridgeService.state.hassdevices[x].deviceState.entity_id === $scope.bulk.devices[i] && bridgeService.state.hassdevices[x].domain !== "sensor" && bridgeService.state.hassdevices[x].domain !== "sun") { + $scope.buildDeviceUrls(bridgeService.state.hassdevices[x], dim_control, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHassDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding Hass devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHassDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding Hass devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -3231,7 +3391,7 @@ app.controller('HassController', function ($scope, $location, bridgeService, ngD // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -3243,14 +3403,15 @@ app.controller('HassController', function ($scope, $location, bridgeService, ngD }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.hassdevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.hassdevices[x].deviceState.entity_id) < 0 && bridgeService.state.hassdevices[x].domain !== "sensor" && bridgeService.state.hassdevices[x].domain !== "sun") + for (var x = 0; x < bridgeService.state.hassdevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.hassdevices[x].deviceState.entity_id) < 0 && bridgeService.state.hassdevices[x].domain !== "sensor" && bridgeService.state.hassdevices[x].domain !== "sun") $scope.bulk.devices.push(bridgeService.state.hassdevices[x].deviceState.entity_id); } } @@ -3258,7 +3419,7 @@ app.controller('HassController', function ($scope, $location, bridgeService, ngD $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3272,7 +3433,7 @@ app.controller('HassController', function ($scope, $location, bridgeService, ngD className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -3280,136 +3441,143 @@ app.controller('HassController', function ($scope, $location, bridgeService, ngD }); app.controller('HomeWizardController', function ($scope, $location, bridgeService, ngDialog) { - $scope.bridge = bridgeService.state; - $scope.device = bridgeService.state.device; - $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; - $scope.selectAll = false; - bridgeService.viewHomeWizardDevices(); - $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; - $scope.buttonsVisible = false; + $scope.bridge = bridgeService.state; + $scope.device = bridgeService.state.device; + $scope.device_dim_control = ""; + $scope.bulk = { + devices: [] + }; + $scope.selectAll = false; + bridgeService.viewHomeWizardDevices(); + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + $scope.buttonsVisible = false; - $scope.clearDevice = function () { - bridgeService.clearDevice(); - $scope.device = bridgeService.state.device; - }; + $scope.clearDevice = function () { + bridgeService.clearDevice(); + $scope.device = bridgeService.state.device; + }; - $scope.buildDeviceUrls = function (homewizarddevice, buildonly) { - - dimpayload = "{\"deviceid\":\"" + homewizarddevice.id + "\",\"action\":\"on\"}"; - onpayload = "{\"deviceid\":\"" + homewizarddevice.id + "\",\"action\":\"on\"}"; - offpayload = "{\"deviceid\":\"" + homewizarddevice.id + "\",\"action\":\"off\"}"; - - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, homewizarddevice.id ,homewizarddevice.name, homewizarddevice.gateway, null, "homewizardDevice", null, null); - $scope.device = bridgeService.state.device; - - if (!buildonly) { - bridgeService.editNewDevice($scope.device); - $location.path('/editdevice'); - } - }; + $scope.buildDeviceUrls = function (homewizarddevice, buildonly) { - $scope.bulkAddDevices = function() { - var devicesList = []; - $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.homewizarddevices.length; x++) { - if(bridgeService.state.homewizarddevices[x].id === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.homewizarddevices[x],true); - devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff - }; - $scope.clearDevice(); - } - } - } - bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHalDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding HomeWizard devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; - $scope.selectAll = false; - }; + dimpayload = "{\"deviceid\":\"" + homewizarddevice.id + "\",\"action\":\"on\"}"; + onpayload = "{\"deviceid\":\"" + homewizarddevice.id + "\",\"action\":\"on\"}"; + offpayload = "{\"deviceid\":\"" + homewizarddevice.id + "\",\"action\":\"off\"}"; - $scope.toggleSelection = function toggleSelection(deviceId) { - var idx = $scope.bulk.devices.indexOf(deviceId); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, homewizarddevice.id, homewizarddevice.name, homewizarddevice.gateway, null, "homewizardDevice", null, null); + $scope.device = bridgeService.state.device; - // is currently selected - if (idx > -1) { - $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) - $scope.selectAll = false; - } + if (!buildonly) { + bridgeService.editNewDevice($scope.device); + $location.path('/editdevice'); + } + }; - // is newly selected - else { - $scope.bulk.devices.push(deviceId); - $scope.selectAll = true; - } - }; + $scope.bulkAddDevices = function () { + var devicesList = []; + $scope.clearDevice(); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.homewizarddevices.length; x++) { + if (bridgeService.state.homewizarddevices[x].id === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.homewizarddevices[x], true); + devicesList[i] = { + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff + }; + $scope.clearDevice(); + } + } + } + bridgeService.bulkAddDevice(devicesList).then( + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHalDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding HomeWizard devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; + $scope.selectAll = false; + }; - $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { - $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { - $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.homewizarddevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.homewizarddevices[x]) < 0) - $scope.bulk.devices.push(bridgeService.state.homewizarddevices[x].devicename); - } - } - }; + $scope.toggleSelection = function toggleSelection(deviceId) { + var idx = $scope.bulk.devices.indexOf(deviceId); - $scope.toggleButtons = function () { - $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) - $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; - else - $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; - }; + // is currently selected + if (idx > -1) { + $scope.bulk.devices.splice(idx, 1); + if ($scope.bulk.devices.length === 0 && $scope.selectAll) + $scope.selectAll = false; + } - $scope.deleteDevice = function (device) { - $scope.bridge.device = device; - ngDialog.open({ - template: 'deleteDialog', - controller: 'DeleteDialogCtrl', - className: 'ngdialog-theme-default' - }); - }; - - $scope.editDevice = function (device) { - bridgeService.editDevice(device); - $location.path('/editdevice'); - }; + // is newly selected + else { + $scope.bulk.devices.push(deviceId); + $scope.selectAll = true; + } + }; + + $scope.toggleSelectAll = function toggleSelectAll() { + if ($scope.selectAll) { + $scope.selectAll = false; + $scope.bulk = { + devices: [] + }; + } else { + $scope.selectAll = true; + for (var x = 0; x < bridgeService.state.homewizarddevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.homewizarddevices[x]) < 0) + $scope.bulk.devices.push(bridgeService.state.homewizarddevices[x].devicename); + } + } + }; + + $scope.toggleButtons = function () { + $scope.buttonsVisible = !$scope.buttonsVisible; + if ($scope.buttonsVisible) + $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; + else + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + }; + + $scope.deleteDevice = function (device) { + $scope.bridge.device = device; + ngDialog.open({ + template: 'deleteDialog', + controller: 'DeleteDialogCtrl', + className: 'ngdialog-theme-default' + }); + }; + + $scope.editDevice = function (device) { + bridgeService.editDevice(device); + $location.path('/editdevice'); + }; }); app.controller('DomoticzController', function ($scope, $location, bridgeService, ngDialog) { $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; bridgeService.viewDomoticzDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3428,20 +3596,19 @@ app.controller('DomoticzController', function ($scope, $location, bridgeService, var nameCmd = ""; var aDeviceType; var postCmd = ""; - if(domoticzdevice.devicetype === "Scene" || domoticzdevice.devicetype === "Group") { + if (domoticzdevice.devicetype === "Scene" || domoticzdevice.devicetype === "Group") { aDeviceType = "scene"; preCmd = "/json.htm?type=command¶m=switchscene&idx="; postOnCmd = "&switchcmd=On"; postOffCmd = "&switchcmd=Off"; - } - else { + } else { aDeviceType = "switch"; preCmd = "/json.htm?type=command¶m=switchlight&idx="; postOnCmd = "&switchcmd=On"; postDimCmd = "&switchcmd=Set%20Level&level="; postOffCmd = "&switchcmd=Off"; } - if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) && aDeviceType === "switch") + if ((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) && aDeviceType === "switch") dimpayload = "http://" + domoticzdevice.domoticzaddress + preCmd + domoticzdevice.idx + @@ -3450,14 +3617,14 @@ app.controller('DomoticzController', function ($scope, $location, bridgeService, else dimpayload = null; onpayload = "http://" + domoticzdevice.domoticzaddress + - preCmd + - domoticzdevice.idx + - postOnCmd; + preCmd + + domoticzdevice.idx + + postOnCmd; offpayload = "http://" + domoticzdevice.domoticzaddress + - preCmd + - domoticzdevice.idx + - postOffCmd; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, domoticzdevice.devicename + "-" + domoticzdevice.domoticzname, domoticzdevice.devicename, domoticzdevice.domoticzname, aDeviceType, "domoticzDevice", null, null); + preCmd + + domoticzdevice.idx + + postOffCmd; + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, false, domoticzdevice.devicename + "-" + domoticzdevice.domoticzname, domoticzdevice.devicename, domoticzdevice.domoticzname, aDeviceType, "domoticzDevice", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -3465,45 +3632,47 @@ app.controller('DomoticzController', function ($scope, $location, bridgeService, } }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.domoticzdevices.length; x++) { - if(bridgeService.state.domoticzdevices[x].devicename === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.domoticzdevices[x],dim_control,true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.domoticzdevices.length; x++) { + if (bridgeService.state.domoticzdevices[x].devicename === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.domoticzdevices[x], dim_control, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHalDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding Domoticz devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHalDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding Domoticz devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -3513,7 +3682,7 @@ app.controller('DomoticzController', function ($scope, $location, bridgeService, // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -3525,14 +3694,15 @@ app.controller('DomoticzController', function ($scope, $location, bridgeService, }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.domoticzdevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.domoticzdevices[x]) < 0) + for (var x = 0; x < bridgeService.state.domoticzdevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.domoticzdevices[x]) < 0) $scope.bulk.devices.push(bridgeService.state.domoticzdevices[x].devicename); } } @@ -3540,7 +3710,7 @@ app.controller('DomoticzController', function ($scope, $location, bridgeService, $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3554,7 +3724,7 @@ app.controller('DomoticzController', function ($scope, $location, bridgeService, className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -3565,7 +3735,9 @@ app.controller('LifxController', function ($scope, $location, bridgeService, ngD $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; bridgeService.viewLifxDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3585,7 +3757,7 @@ app.controller('LifxController', function ($scope, $location, bridgeService, ngD dimpayload = angular.toJson(lifxdevice); onpayload = angular.toJson(lifxdevice); offpayload = angular.toJson(lifxdevice); - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, lifxdevice.name, lifxdevice.name, lifxdevice.name, null, "lifxDevice", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, lifxdevice.name, lifxdevice.name, lifxdevice.name, null, "lifxDevice", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -3593,45 +3765,47 @@ app.controller('LifxController', function ($scope, $location, bridgeService, ngD } }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.lifxdevices.length; x++) { - if(bridgeService.state.lifxdevices[x].devicename === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.lifxdevices[x],dim_control,true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.lifxdevices.length; x++) { + if (bridgeService.state.lifxdevices[x].devicename === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.lifxdevices[x], dim_control, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHalDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding LIFX devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHalDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding LIFX devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -3641,7 +3815,7 @@ app.controller('LifxController', function ($scope, $location, bridgeService, ngD // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -3653,14 +3827,15 @@ app.controller('LifxController', function ($scope, $location, bridgeService, ngD }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.lifxdevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.lifxdevices[x]) < 0) + for (var x = 0; x < bridgeService.state.lifxdevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.lifxdevices[x]) < 0) $scope.bulk.devices.push(bridgeService.state.lifxdevices[x].devicename); } } @@ -3668,7 +3843,7 @@ app.controller('LifxController', function ($scope, $location, bridgeService, ngD $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3682,7 +3857,7 @@ app.controller('LifxController', function ($scope, $location, bridgeService, ngD className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -3693,9 +3868,15 @@ app.controller('SomfyController', function ($scope, $location, bridgeService, ng $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; - $scope.somfy = {base: "http://", port: "3480", id: ""}; + $scope.somfy = { + base: "http://", + port: "3480", + id: "" + }; bridgeService.viewDevices(); //Needs this if you're navigating to the 'somfy' page directly without going to the home page first.. bridgeService.viewSomfyDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3708,59 +3889,61 @@ app.controller('SomfyController', function ($scope, $location, bridgeService, ng }; $scope.buildDeviceUrls = function (somfydevice, dim_control, buildonly) { - //TODO - support partial window opening - add back 'dim_control' second param in here, and in somfydevice.html - dimpayload = null; - onpayload = "{\"label\":\"Label that is ignored probably\",\"actions\":[{\"deviceURL\":\""+ somfydevice.deviceUrl+"\",\"commands\":[{\"name\":\"open\",\"parameters\":[]}]}]}"; - offpayload = "{\"label\":\"Label that is ignored probably\",\"actions\":[{\"deviceURL\":\""+ somfydevice.deviceUrl+"\",\"commands\":[{\"name\":\"close\",\"parameters\":[]}]}]}"; + //TODO - support partial window opening - add back 'dim_control' second param in here, and in somfydevice.html + dimpayload = null; + onpayload = "{\"label\":\"Label that is ignored probably\",\"actions\":[{\"deviceURL\":\"" + somfydevice.deviceUrl + "\",\"commands\":[{\"name\":\"open\",\"parameters\":[]}]}]}"; + offpayload = "{\"label\":\"Label that is ignored probably\",\"actions\":[{\"deviceURL\":\"" + somfydevice.deviceUrl + "\",\"commands\":[{\"name\":\"close\",\"parameters\":[]}]}]}"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, somfydevice.id, somfydevice.name, somfydevice.somfyname, "switch", "somfyDevice", null, null); - $scope.device = bridgeService.state.device; - if (!buildonly) { - bridgeService.editNewDevice($scope.device); - $location.path('/editdevice'); - } + bridgeService.buildUrls(onpayload, dimpayload, offpayload, null, true, somfydevice.id, somfydevice.name, somfydevice.somfyname, "switch", "somfyDevice", null, null); + $scope.device = bridgeService.state.device; + if (!buildonly) { + bridgeService.editNewDevice($scope.device); + $location.path('/editdevice'); + } }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.somfydevices.length; x++) { - if(bridgeService.state.somfydevices[x].id === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.somfydevices[x],dim_control, true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.somfydevices.length; x++) { + if (bridgeService.state.somfydevices[x].id === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.somfydevices[x], dim_control, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewSomfyDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding Somfy devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewSomfyDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding Somfy devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -3770,7 +3953,7 @@ app.controller('SomfyController', function ($scope, $location, bridgeService, ng // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -3782,14 +3965,15 @@ app.controller('SomfyController', function ($scope, $location, bridgeService, ng }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.somfydevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.somfydevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.somfydevices[x].id, bridgeService.state.somfydevices[x].somfyname, "somfyDevice")) + for (var x = 0; x < bridgeService.state.somfydevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.somfydevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.somfydevices[x].id, bridgeService.state.somfydevices[x].somfyname, "somfyDevice")) $scope.bulk.devices.push(bridgeService.state.somfydevices[x].id); } } @@ -3797,7 +3981,7 @@ app.controller('SomfyController', function ($scope, $location, bridgeService, ng $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3822,12 +4006,14 @@ app.controller('OpenHABController', function ($scope, $location, bridgeService, $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; bridgeService.viewOpenHABDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; $scope.buttonsVisible = false; - + $scope.clearDevice = function () { bridgeService.clearDevice(); $scope.device = bridgeService.state.device; @@ -3835,46 +4021,44 @@ app.controller('OpenHABController', function ($scope, $location, bridgeService, $scope.buildDeviceUrls = function (openhabdevice, dim_control, onaction, ondata, dimaction, dimdata, offaction, offdata, coloraction, colordata, buildonly) { var preCmd = "/rest/items/" + openhabdevice.item.name; - if(openhabdevice.item.type !== 'String') { - if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) { + if (openhabdevice.item.type !== 'String') { + if ((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) { dimpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"" + dim_control + "\"}"; - } - else + } else dimpayload = null; onpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"ON\"}"; offpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"OFF\"}"; colorpayload = null; - } - else { - if(onaction === 'other') + } else { + if (onaction === 'other') onpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"" + ondata + "\"}"; - else if(onaction !== undefined && onaction !== null && onaction !== '') + else if (onaction !== undefined && onaction !== null && onaction !== '') onpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"" + onaction + "\"}"; else onpayload = null; - - if(dimaction === 'other') + + if (dimaction === 'other') dimpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"" + dimdata + "\"}"; - else if(dimaction !== undefined && dimaction !== null && dimaction !== '') + else if (dimaction !== undefined && dimaction !== null && dimaction !== '') dimpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"" + dimaction + "\"}"; else dimpayload = null; - if(offaction === 'other') + if (offaction === 'other') offpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"" + offdata + "\"}"; - else if(offaction !== undefined && offaction !== null && offaction !== '') + else if (offaction !== undefined && offaction !== null && offaction !== '') offpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"" + offaction + "\"}"; else offpayload = null; - if(coloraction === 'other') + if (coloraction === 'other') colorpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"" + colordata + "\"}"; - else if(coloraction !== undefined && coloraction !== null && coloraction !== '') + else if (coloraction !== undefined && coloraction !== null && coloraction !== '') colorpayload = "{\"url\":\"http://" + openhabdevice.address + preCmd + "\",\"command\":\"" + coloraction + "\"}"; else colorpayload = null; } - bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, openhabdevice.item.name + "-" + openhabdevice.name, openhabdevice.item.name, openhabdevice.name, openhabdevice.item.type, "openhabDevice", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, openhabdevice.item.name + "-" + openhabdevice.name, openhabdevice.item.name, openhabdevice.name, openhabdevice.item.type, "openhabDevice", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -3882,45 +4066,47 @@ app.controller('OpenHABController', function ($scope, $location, bridgeService, } }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.openhabdevices.length; x++) { - if(bridgeService.state.openhabdevices[x].devicename === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.openhabdevices[x],dim_control, null, null, null, null, null, null, null, null, true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.openhabdevices.length; x++) { + if (bridgeService.state.openhabdevices[x].devicename === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.openhabdevices[x], dim_control, null, null, null, null, null, null, null, null, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHalDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding openhab devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHalDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding openhab devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -3930,7 +4116,7 @@ app.controller('OpenHABController', function ($scope, $location, bridgeService, // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -3942,14 +4128,15 @@ app.controller('OpenHABController', function ($scope, $location, bridgeService, }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.openhabdevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.openhabdevices[x]) < 0) + for (var x = 0; x < bridgeService.state.openhabdevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.openhabdevices[x]) < 0) $scope.bulk.devices.push(bridgeService.state.openhabdevices[x].devicename); } } @@ -3957,7 +4144,7 @@ app.controller('OpenHABController', function ($scope, $location, bridgeService, $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -3971,7 +4158,7 @@ app.controller('OpenHABController', function ($scope, $location, bridgeService, className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -3982,35 +4169,38 @@ app.controller('MozIotController', function ($scope, $location, bridgeService, n $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; bridgeService.viewMozIotDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; $scope.buttonsVisible = false; - + $scope.clearDevice = function () { bridgeService.clearDevice(); $scope.device = bridgeService.state.device; }; - $scope.buildDeviceUrls = function (moziotdevice, dim_control, colordata, buildonly) { - var preCmd = moziotdevice.href + "/"; + $scope.buildDeviceUrls = function (moziotdevice, dim_control, coloraction, colordata, buildonly) { + var preCmd = moziotdevice.deviceDetail.href + "/properties/"; onpayload = null; offpayload = null; dimpayload = null; colorpayload = null; - if(moziotdevice.properties.on !== undefined) { + if (moziotdevice.deviceDetail.properties.on !== undefined) { onpayload = "{\"url\":\"" + preCmd + "on\",\"command\":{\"on\":true}}"; offpayload = "{\"url\":\"" + preCmd + "on\",\"command\":{\"on\":false}}"; } - if(moziotdevice.properties.level !== undefined) { - dimpayload = "{\"url\":\"" + preCmd + "level\",\"command\":{\"level\":" + dim_control + "}}"; - } - if(moziotdevice.properties.color !== undefined) { - colorpayload = "{\"url\":\"" + preCmd + "color\",\"command\":\"{\"color\":" + colordata + "}}"; + if (dim_control !== undefined && dim_control !== "") { + dimpayload = "{\"url\":\"" + preCmd + "level\",\"command\":{\"level\":\"" + dim_control + "\"}}"; } + if (coloraction === 'other') + colorpayload = "{\"url\":\"" + preCmd + "color\",\"command\":{\"color\":\"" + colordata + "\"}}"; + else if (coloraction !== undefined && coloraction !== null && coloraction !== '') + colorpayload = "{\"url\":\"" + preCmd + "color\",\"command\":{\"color\":\"" + coloraction + "\"}}"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, moziotdevice.name + "-" + moziotdevice.type, moziotdevice.name, moziotdevice.name, moziotdevice.type, "moziotDevice", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, moziotdevice.deviceDetail.name + "-" + moziotdevice.deviceDetail.type, moziotdevice.deviceDetail.name, moziotdevice.gatewayName, "Switch", "moziotDevice", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -4018,45 +4208,47 @@ app.controller('MozIotController', function ($scope, $location, bridgeService, n } }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.moziotdevices.length; x++) { - if(bridgeService.state.moziotdevices[x].devicename === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.moziotdevices[x],dim_control, null, true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.moziotdevices.length; x++) { + if (bridgeService.state.moziotdevices[x].devicename === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.moziotdevices[x], dim_control, null, null, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHalDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding Mozilla IOT devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHalDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding Mozilla IOT devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -4066,7 +4258,7 @@ app.controller('MozIotController', function ($scope, $location, bridgeService, n // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -4078,14 +4270,15 @@ app.controller('MozIotController', function ($scope, $location, bridgeService, n }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.moziotdevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.moziotdevices[x]) < 0) + for (var x = 0; x < bridgeService.state.moziotdevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.moziotdevices[x]) < 0) $scope.bulk.devices.push(bridgeService.state.moziotdevices[x].devicename); } } @@ -4093,7 +4286,7 @@ app.controller('MozIotController', function ($scope, $location, bridgeService, n $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -4107,7 +4300,7 @@ app.controller('MozIotController', function ($scope, $location, bridgeService, n className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -4118,12 +4311,14 @@ app.controller('FhemController', function ($scope, $location, bridgeService, ngD $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; bridgeService.viewFhemDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; $scope.buttonsVisible = false; - + $scope.clearDevice = function () { bridgeService.clearDevice(); $scope.device = bridgeService.state.device; @@ -4131,30 +4326,25 @@ app.controller('FhemController', function ($scope, $location, bridgeService, ngD $scope.buildDeviceUrls = function (fhemdevice, dim_control, buildonly) { var preCmd = "/fhem?cmd=set%20" + fhemdevice.item.Name + "%20"; - if(fhemdevice.item.PossibleSets.toLowerCase().indexOf("dim") >= 0) { - if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) { + if (fhemdevice.item.PossibleSets.toLowerCase().indexOf("dim") >= 0) { + if ((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) { dimpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"dim%20" + dim_control + "\"}"; - } - else + } else dimpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"dim%20${intensity.percent}\"}"; - } - else if(fhemdevice.item.PossibleSets.toLowerCase().indexOf("pct") >= 0) { - if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) { + } else if (fhemdevice.item.PossibleSets.toLowerCase().indexOf("pct") >= 0) { + if ((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0)) { dimpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"pct%20" + dim_control + "\"}"; - } - else + } else dimpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"pct%20${intensity.percent}\"}"; - } - else + } else dimpayload = null; - if(fhemdevice.item.PossibleSets.toLowerCase().indexOf("rgb") >= 0) { + if (fhemdevice.item.PossibleSets.toLowerCase().indexOf("rgb") >= 0) { colorpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"RGB%20${color.rgbx}\"}"; - } - else + } else colorpayload = null; onpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"on\"}"; offpayload = "{\"url\":\"http://" + fhemdevice.address + preCmd + "\",\"command\":\"off\"}"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, fhemdevice.item.Name + "-" + fhemdevice.name, fhemdevice.item.Name, fhemdevice.name, fhemdevice.item.type, "fhemDevice", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, fhemdevice.item.Name + "-" + fhemdevice.name, fhemdevice.item.Name, fhemdevice.name, fhemdevice.item.type, "fhemDevice", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -4162,45 +4352,47 @@ app.controller('FhemController', function ($scope, $location, bridgeService, ngD } }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.fhemdevices.length; x++) { - if(bridgeService.state.fhemdevices[x].item.Name === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.fhemdevices[x],dim_control,true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.fhemdevices.length; x++) { + if (bridgeService.state.fhemdevices[x].item.Name === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.fhemdevices[x], dim_control, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHalDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding fhem devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHalDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding fhem devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -4210,7 +4402,7 @@ app.controller('FhemController', function ($scope, $location, bridgeService, ngD // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -4222,14 +4414,15 @@ app.controller('FhemController', function ($scope, $location, bridgeService, ngD }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.fhemdevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.fhemdevices[x]) < 0) + for (var x = 0; x < bridgeService.state.fhemdevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.fhemdevices[x]) < 0) $scope.bulk.devices.push(bridgeService.state.fhemdevices[x].item.Name); } } @@ -4237,7 +4430,7 @@ app.controller('FhemController', function ($scope, $location, bridgeService, ngD $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -4251,7 +4444,7 @@ app.controller('FhemController', function ($scope, $location, bridgeService, ngD className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -4262,12 +4455,14 @@ app.controller('BroadlinkController', function ($scope, $location, bridgeService $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; $scope.device_dim_control = ""; - $scope.bulk = { devices: [] }; + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; bridgeService.viewBroadlinkDevices(); $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; $scope.buttonsVisible = false; - + $scope.clearDevice = function () { bridgeService.clearDevice(); $scope.device = bridgeService.state.device; @@ -4280,36 +4475,35 @@ app.controller('BroadlinkController', function ($scope, $location, bridgeService $scope.buildDeviceUrls = function (broadlinkdevice, dim_control, ondata, dimdata, offdata, colordata, buildonly) { var preCmd = "{\"id\":\"" + broadlinkdevice.id + "\",\"name\":\"" + broadlinkdevice.name + "\",\"type\":\"" + broadlinkdevice.type + "\",\"ipAddr\":\"" + broadlinkdevice.ipAddr + "\",\"macAddr\":\"" + broadlinkdevice.macAddr + "\",\"command\":\""; - if(broadlinkdevice.baseType === '0000' || broadlinkdevice.baseType === '2711') { + if (broadlinkdevice.baseType === '0000' || broadlinkdevice.baseType === '2711') { dimpayload = null; colorpayload = null; onpayload = preCmd + "on\"}"; offpayload = preCmd + "off\"}"; - } - else if(broadlinkdevice.baseType === '4EB5') { + } else if (broadlinkdevice.baseType === '4EB5') { dimpayload = null; colorpayload = null; onpayload = preCmd + "on\",\"data\":\"" + ondata + "\"}"; offpayload = preCmd + "off\",\"data\":\"" + offdata + "\"}"; } else { - if( ondata !== undefined && ondata !== null && ondata !== "") - onpayload = preCmd + "ircommand\",\"data\":\"" + ondata + "\"}"; + if (ondata !== undefined && ondata !== null && ondata !== "") + onpayload = preCmd + "ircommand\",\"data\":\"" + ondata + "\"}"; else onpayload = null; - if( dimdata !== undefined && dimdata !== null && dimdata !== "") - dimpayload = preCmd + "ircommand\",\"data\":\"" + dimdata + "\"}"; + if (dimdata !== undefined && dimdata !== null && dimdata !== "") + dimpayload = preCmd + "ircommand\",\"data\":\"" + dimdata + "\"}"; else dimpayload = null; - if( offdata !== undefined && offdata !== null && offdata !== "") - offpayload = preCmd + "ircommand\",\"data\":\"" + offdata + "\"}"; + if (offdata !== undefined && offdata !== null && offdata !== "") + offpayload = preCmd + "ircommand\",\"data\":\"" + offdata + "\"}"; else offpayload = null; - if( colordata !== undefined && colordata !== null && colordata !== "") - colorpayload = preCmd + "ircommand\",\"data\":\"" + colordata + "\"}"; + if (colordata !== undefined && colordata !== null && colordata !== "") + colorpayload = preCmd + "ircommand\",\"data\":\"" + colordata + "\"}"; else colorpayload = null; } - bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, broadlinkdevice.id, broadlinkdevice.name, broadlinkdevice.id, broadlinkdevice.desc, "broadlinkDevice", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, broadlinkdevice.id, broadlinkdevice.name, broadlinkdevice.id, broadlinkdevice.desc, "broadlinkDevice", null, null); $scope.device = bridgeService.state.device; if (!buildonly) { bridgeService.editNewDevice($scope.device); @@ -4317,45 +4511,47 @@ app.controller('BroadlinkController', function ($scope, $location, bridgeService } }; - $scope.bulkAddDevices = function(dim_control) { + $scope.bulkAddDevices = function (dim_control) { var devicesList = []; $scope.clearDevice(); - for(var i = 0; i < $scope.bulk.devices.length; i++) { - for(var x = 0; x < bridgeService.state.broadlinkdevices.length; x++) { - if(bridgeService.state.broadlinkdevices[x].devicename === $scope.bulk.devices[i]) { - $scope.buildDeviceUrls(bridgeService.state.broadlinkdevices[x],dim_control,null,null,null,null,true); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.broadlinkdevices.length; x++) { + if (bridgeService.state.broadlinkdevices[x].devicename === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.broadlinkdevices[x], dim_control, null, null, null, null, true); devicesList[i] = { - name: $scope.device.name, - mapId: $scope.device.mapId, - mapType: $scope.device.mapType, - deviceType: $scope.device.deviceType, - targetDevice: $scope.device.targetDevice, - onUrl: $scope.device.onUrl, - dimUrl: $scope.device.dimUrl, - offUrl: $scope.device.offUrl, - colorUrl: $scope.device.colorUrl, - headers: $scope.device.headers, - httpVerb: $scope.device.httpVerb, - contentType: $scope.device.contentType, - contentBody: $scope.device.contentBody, - contentBodyDim: $scope.device.contentBodyDim, - contentBodyOff: $scope.device.contentBodyOff + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff }; $scope.clearDevice(); } } } bridgeService.bulkAddDevice(devicesList).then( - function () { - $scope.clearDevice(); - bridgeService.viewDevices(); - bridgeService.viewHalDevices(); - }, - function (error) { - bridgeService.displayWarn("Error adding openhab devices in bulk.", error); - } - ); - $scope.bulk = { devices: [] }; + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHalDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding openhab devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; $scope.selectAll = false; }; @@ -4365,7 +4561,7 @@ app.controller('BroadlinkController', function ($scope, $location, bridgeService // is currently selected if (idx > -1) { $scope.bulk.devices.splice(idx, 1); - if($scope.bulk.devices.length === 0 && $scope.selectAll) + if ($scope.bulk.devices.length === 0 && $scope.selectAll) $scope.selectAll = false; } @@ -4377,14 +4573,15 @@ app.controller('BroadlinkController', function ($scope, $location, bridgeService }; $scope.toggleSelectAll = function toggleSelectAll() { - if($scope.selectAll) { + if ($scope.selectAll) { $scope.selectAll = false; - $scope.bulk = { devices: [] }; - } - else { + $scope.bulk = { + devices: [] + }; + } else { $scope.selectAll = true; - for(var x = 0; x < bridgeService.state.broadlinkdevices.length; x++) { - if($scope.bulk.devices.indexOf(bridgeService.state.broadlinkdevices[x]) < 0) + for (var x = 0; x < bridgeService.state.broadlinkdevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.broadlinkdevices[x]) < 0) $scope.bulk.devices.push(bridgeService.state.broadlinkdevices[x].devicename); } } @@ -4392,7 +4589,7 @@ app.controller('BroadlinkController', function ($scope, $location, bridgeService $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -4406,7 +4603,7 @@ app.controller('BroadlinkController', function ($scope, $location, bridgeService className: 'ngdialog-theme-default' }); }; - + $scope.editDevice = function (device) { bridgeService.editDevice(device); $location.path('/editdevice'); @@ -4426,29 +4623,29 @@ app.controller('EditController', function ($scope, $location, bridgeService) { $scope.offUrl = null; $scope.colorUrl = null; if ($scope.device !== undefined && $scope.device.name !== undefined) { - if($scope.bridge.device.onUrl !== undefined) { + if ($scope.bridge.device.onUrl !== undefined) { $scope.onDevices = bridgeService.getCallObjects($scope.bridge.device.onUrl); $scope.onUrl = $scope.bridge.device.onUrl.split("},").join("},\n"); } - if($scope.bridge.device.dimUrl !== undefined) { + if ($scope.bridge.device.dimUrl !== undefined) { $scope.dimDevices = bridgeService.getCallObjects($scope.bridge.device.dimUrl); $scope.dimUrl = $scope.bridge.device.dimUrl.split("},").join("},\n"); } - if($scope.bridge.device.offUrl !== undefined) { + if ($scope.bridge.device.offUrl !== undefined) { $scope.offDevices = bridgeService.getCallObjects($scope.bridge.device.offUrl); $scope.offUrl = $scope.bridge.device.offUrl.split("},").join("},\n"); } - if($scope.bridge.device.colorUrl !== undefined) { + if ($scope.bridge.device.colorUrl !== undefined) { $scope.colorDevices = bridgeService.getCallObjects($scope.bridge.device.colorUrl); $scope.colorUrl = $scope.bridge.device.colorUrl.split("},").join("},\n"); } } - + $scope.newOnItem = {}; $scope.newDimItem = {}; $scope.newOffItem = {}; $scope.newColorItem = {}; - $scope.mapTypeSelected = bridgeService.getMapType($scope.device.mapType); + $scope.mapTypeSelected = bridgeService.getMapType($scope.device.mapType); $scope.device_dim_control = ""; $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; $scope.buttonsVisible = false; @@ -4473,12 +4670,12 @@ app.controller('EditController', function ($scope, $location, bridgeService) { }; $scope.editDevice = function (copy) { - if($scope.device.name === "" && $scope.device.onUrl === "") { + if ($scope.device.name === "" && $scope.device.onUrl === "") { $scope.clearDevice(); bridgeService.displayWarn("Error adding/editing device. Name has not been given.", null); return; } - if(($scope.device.name === $scope.bridge.olddevicename) && copy) { + if (($scope.device.name === $scope.bridge.olddevicename) && copy) { $scope.clearDevice(); bridgeService.displayWarn("Error adding device. Name has not been changed from original.", null); return; @@ -4486,19 +4683,19 @@ app.controller('EditController', function ($scope, $location, bridgeService) { if (copy) { $scope.device.id = null; $scope.device.uniqueid = null; - if($scope.bridge.olddevicename !== null && $scope.bridge.olddevicename !== "") + if ($scope.bridge.olddevicename !== null && $scope.bridge.olddevicename !== "") $scope.device.mapId = $scope.device.mapId + "-copy"; } - if($scope.mapTypeSelected !== undefined && $scope.mapTypeSelected !== null) + if ($scope.mapTypeSelected !== undefined && $scope.mapTypeSelected !== null) $scope.device.mapType = $scope.mapTypeSelected[0]; else $scope.device.mapType = null; - + if ($scope.showUrls) { - $scope.device.onUrl = ($scope.onUrl == undefined || $scope.onUrl == null || $scope.onUrl == "") ? null : $scope.onUrl.replace(/\r?\n|\r/g,""); - $scope.device.dimUrl = ($scope.dimUrl == undefined || $scope.dimUrl == null || $scope.dimUrl == "") ? null : $scope.dimUrl.replace(/\r?\n|\r/g,""); - $scope.device.offUrl = ($scope.offUrl == undefined || $scope.offUrl == null || $scope.offUrl == "") ? null : $scope.offUrl.replace(/\r?\n|\r/g,""); - $scope.device.colorUrl = ($scope.colorUrl == undefined || $scope.colorUrl == null || $scope.colorUrl == "") ? null : $scope.colorUrl.replace(/\r?\n|\r/g,""); + $scope.device.onUrl = ($scope.onUrl == undefined || $scope.onUrl == null || $scope.onUrl == "") ? null : $scope.onUrl.replace(/\r?\n|\r/g, ""); + $scope.device.dimUrl = ($scope.dimUrl == undefined || $scope.dimUrl == null || $scope.dimUrl == "") ? null : $scope.dimUrl.replace(/\r?\n|\r/g, ""); + $scope.device.offUrl = ($scope.offUrl == undefined || $scope.offUrl == null || $scope.offUrl == "") ? null : $scope.offUrl.replace(/\r?\n|\r/g, ""); + $scope.device.colorUrl = ($scope.colorUrl == undefined || $scope.colorUrl == null || $scope.colorUrl == "") ? null : $scope.colorUrl.replace(/\r?\n|\r/g, ""); } else { if ($scope.onDevices !== null) $scope.device.onUrl = angular.toJson(bridgeService.updateCallObjectsType($scope.onDevices)); @@ -4507,100 +4704,140 @@ app.controller('EditController', function ($scope, $location, bridgeService) { if ($scope.offDevices !== null) $scope.device.offUrl = angular.toJson(bridgeService.updateCallObjectsType($scope.offDevices)); if ($scope.colorDevices !== null) - $scope.device.colorUrl = angular.toJson(bridgeService.updateCallObjectsType($scope.colorDevices)); + $scope.device.colorUrl = angular.toJson(bridgeService.updateCallObjectsType($scope.colorDevices)); } - + bridgeService.addDevice($scope.device).then( - function () { - bridgeService.state.queueDevId = $scope.device.id; - console.log("Device updated for Q Id <<" + bridgeService.state.queueDevId + ">>"); - $scope.clearDevice(); - $location.path('/'); - }, - function (error) { - bridgeService.displayWarn("Error adding/updating device....", error); - } + function () { + bridgeService.state.queueDevId = $scope.device.id; + console.log("Device updated for Q Id <<" + bridgeService.state.queueDevId + ">>"); + $scope.clearDevice(); + $location.path('/'); + }, + function (error) { + bridgeService.displayWarn("Error adding/updating device....", error); + } ); }; - $scope.addItemOn = function (anItem) { - if (anItem.item === undefined || anItem.item === null || anItem.item === "") - return; - var newitem = { item: anItem.item, type: anItem.type, delay: anItem.delay, count: anItem.count, filterIPs: anItem.filterIPs, httpVerb: anItem.httpVerb, httpBody: anItem.httpBody, httpHeaders: anItem.httpHeaders, contentType: anItem.contentType }; - if ($scope.onDevices === null) - $scope.onDevices = []; - $scope.onDevices.push(newitem); - $scope.newOnItem = {}; - }; - $scope.removeItemOn = function (anItem) { - for(var i = $scope.onDevices.length - 1; i >= 0; i--) { - if($scope.onDevices[i] === anItem) { - $scope.onDevices.splice(i, 1); - } - } - $scope.newOnItem = {}; - }; + $scope.addItemOn = function (anItem) { + if (anItem.item === undefined || anItem.item === null || anItem.item === "") + return; + var newitem = { + item: anItem.item, + type: anItem.type, + delay: anItem.delay, + count: anItem.count, + filterIPs: anItem.filterIPs, + httpVerb: anItem.httpVerb, + httpBody: anItem.httpBody, + httpHeaders: anItem.httpHeaders, + contentType: anItem.contentType + }; + if ($scope.onDevices === null) + $scope.onDevices = []; + $scope.onDevices.push(newitem); + $scope.newOnItem = {}; + }; + $scope.removeItemOn = function (anItem) { + for (var i = $scope.onDevices.length - 1; i >= 0; i--) { + if ($scope.onDevices[i] === anItem) { + $scope.onDevices.splice(i, 1); + } + } + $scope.newOnItem = {}; + }; - $scope.addItemDim = function (anItem) { - if (anItem.item === undefined || anItem.item === null || anItem.item === "") - return; - var newitem = { item: anItem.item, type: anItem.type, delay: anItem.delay, count: anItem.count, filterIPs: anItem.filterIPs, httpVerb: anItem.httpVerb, httpBody: anItem.httpBody, httpHeaders: anItem.httpHeaders, contentType: anItem.contentType }; - if ($scope.dimDevices === null) - $scope.dimDevices = []; - $scope.dimDevices.push(newitem); - $scope.newDimItem = {}; - }; - $scope.removeItemDim = function (anItem) { - for(var i = $scope.dimDevices.length - 1; i >= 0; i--) { - if($scope.dimDevices[i] === anItem) { - $scope.dimDevices.splice(i, 1); - } - } - $scope.newDimItem = {}; - }; + $scope.addItemDim = function (anItem) { + if (anItem.item === undefined || anItem.item === null || anItem.item === "") + return; + var newitem = { + item: anItem.item, + type: anItem.type, + delay: anItem.delay, + count: anItem.count, + filterIPs: anItem.filterIPs, + httpVerb: anItem.httpVerb, + httpBody: anItem.httpBody, + httpHeaders: anItem.httpHeaders, + contentType: anItem.contentType + }; + if ($scope.dimDevices === null) + $scope.dimDevices = []; + $scope.dimDevices.push(newitem); + $scope.newDimItem = {}; + }; + $scope.removeItemDim = function (anItem) { + for (var i = $scope.dimDevices.length - 1; i >= 0; i--) { + if ($scope.dimDevices[i] === anItem) { + $scope.dimDevices.splice(i, 1); + } + } + $scope.newDimItem = {}; + }; - $scope.addItemOff = function (anItem) { - if (anItem.item === undefined || anItem.item === null || anItem.item === "") - return; - var newitem = { item: anItem.item, type: anItem.type, delay: anItem.delay, count: anItem.count, filterIPs: anItem.filterIPs, httpVerb: anItem.httpVerb, httpBody: anItem.httpBody, httpHeaders: anItem.httpHeaders, contentType: anItem.contentType }; - if ($scope.offDevices === null) - $scope.offDevices = []; - $scope.offDevices.push(newitem); - $scope.newOffItem = {}; - }; - $scope.removeItemOff = function (anItem) { - for(var i = $scope.offDevices.length - 1; i >= 0; i--) { - if($scope.offDevices[i] === anItem) { - $scope.offDevices.splice(i, 1); - } - } - $scope.newOffItem = {}; - }; + $scope.addItemOff = function (anItem) { + if (anItem.item === undefined || anItem.item === null || anItem.item === "") + return; + var newitem = { + item: anItem.item, + type: anItem.type, + delay: anItem.delay, + count: anItem.count, + filterIPs: anItem.filterIPs, + httpVerb: anItem.httpVerb, + httpBody: anItem.httpBody, + httpHeaders: anItem.httpHeaders, + contentType: anItem.contentType + }; + if ($scope.offDevices === null) + $scope.offDevices = []; + $scope.offDevices.push(newitem); + $scope.newOffItem = {}; + }; + $scope.removeItemOff = function (anItem) { + for (var i = $scope.offDevices.length - 1; i >= 0; i--) { + if ($scope.offDevices[i] === anItem) { + $scope.offDevices.splice(i, 1); + } + } + $scope.newOffItem = {}; + }; - $scope.addItemColor = function (anItem) { - if (anItem.item === undefined || anItem.item === null || anItem.item === "") - return; - var newitem = { item: anItem.item, type: anItem.type, delay: anItem.delay, count: anItem.count, filterIPs: anItem.filterIPs, httpVerb: anItem.httpVerb, httpBody: anItem.httpBody, httpHeaders: anItem.httpHeaders, contentType: anItem.contentType }; - if ($scope.colorDevices === null) - $scope.colorDevices = []; - $scope.colorDevices.push(newitem); - $scope.newColorItem = {}; - }; - $scope.removeItemColor = function (anItem) { - for(var i = $scope.colorDevices.length - 1; i >= 0; i--) { - if($scope.colorDevices[i] === anItem) { - $scope.colorDevices.splice(i, 1); - } - } - $scope.newColorItem = {}; - }; + $scope.addItemColor = function (anItem) { + if (anItem.item === undefined || anItem.item === null || anItem.item === "") + return; + var newitem = { + item: anItem.item, + type: anItem.type, + delay: anItem.delay, + count: anItem.count, + filterIPs: anItem.filterIPs, + httpVerb: anItem.httpVerb, + httpBody: anItem.httpBody, + httpHeaders: anItem.httpHeaders, + contentType: anItem.contentType + }; + if ($scope.colorDevices === null) + $scope.colorDevices = []; + $scope.colorDevices.push(newitem); + $scope.newColorItem = {}; + }; + $scope.removeItemColor = function (anItem) { + for (var i = $scope.colorDevices.length - 1; i >= 0; i--) { + if ($scope.colorDevices[i] === anItem) { + $scope.colorDevices.splice(i, 1); + } + } + $scope.newColorItem = {}; + }; $scope.toggleButtons = function () { $scope.buttonsVisible = !$scope.buttonsVisible; - if($scope.buttonsVisible) + if ($scope.buttonsVisible) $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; else $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; @@ -4609,15 +4846,15 @@ app.controller('EditController', function ($scope, $location, bridgeService) { $scope.changeEditmode = function () { // copy local changes over to other edit mode if ($scope.showUrls) { - $scope.onDevices = ($scope.onUrl == undefined || $scope.onUrl == null || $scope.onUrl == "") ? null : bridgeService.getCallObjects($scope.onUrl.replace(/\r?\n|\r/g,"")); - $scope.dimDevices = ($scope.dimUrl == undefined || $scope.dimUrl == null || $scope.dimUrl == "") ? null : bridgeService.getCallObjects($scope.dimUrl.replace(/\r?\n|\r/g,"")); - $scope.offDevices = ($scope.offUrl == undefined || $scope.offUrl == null || $scope.offUrl == "") ? null : bridgeService.getCallObjects($scope.offUrl.replace(/\r?\n|\r/g,"")); - $scope.colorDevices = ($scope.colorUrl == undefined || $scope.colorUrl == null || $scope.colorUrl == "") ? null : bridgeService.getCallObjects($scope.colorUrl.replace(/\r?\n|\r/g,"")); + $scope.onDevices = ($scope.onUrl == undefined || $scope.onUrl == null || $scope.onUrl == "") ? null : bridgeService.getCallObjects($scope.onUrl.replace(/\r?\n|\r/g, "")); + $scope.dimDevices = ($scope.dimUrl == undefined || $scope.dimUrl == null || $scope.dimUrl == "") ? null : bridgeService.getCallObjects($scope.dimUrl.replace(/\r?\n|\r/g, "")); + $scope.offDevices = ($scope.offUrl == undefined || $scope.offUrl == null || $scope.offUrl == "") ? null : bridgeService.getCallObjects($scope.offUrl.replace(/\r?\n|\r/g, "")); + $scope.colorDevices = ($scope.colorUrl == undefined || $scope.colorUrl == null || $scope.colorUrl == "") ? null : bridgeService.getCallObjects($scope.colorUrl.replace(/\r?\n|\r/g, "")); } else { $scope.onUrl = ($scope.onDevices !== null) ? angular.toJson(bridgeService.updateCallObjectsType($scope.onDevices)).split("},").join("},\n") : null; $scope.dimUrl = ($scope.dimDevices !== null) ? angular.toJson(bridgeService.updateCallObjectsType($scope.dimDevices)).split("},").join("},\n") : null; $scope.offUrl = ($scope.offDevices !== null) ? angular.toJson(bridgeService.updateCallObjectsType($scope.offDevices)).split("},").join("},\n") : null; - $scope.colorUrl = ($scope.colorDevices !== null) ? angular.toJson(bridgeService.updateCallObjectsType($scope.colorDevices)).split("},").join("},\n") : null; + $scope.colorUrl = ($scope.colorDevices !== null) ? angular.toJson(bridgeService.updateCallObjectsType($scope.colorDevices)).split("},").join("},\n") : null; } $scope.showUrls = !$scope.showUrls; }; @@ -4625,12 +4862,12 @@ app.controller('EditController', function ($scope, $location, bridgeService) { }); app.filter('configuredVeraDevices', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "veraDevice")){ + if (bridgeService.deviceContainsType(input[i], "veraDevice")) { out.push(input[i]); } } @@ -4639,12 +4876,12 @@ app.filter('configuredVeraDevices', function (bridgeService) { }); app.filter('configuredVeraScenes', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "veraScene")){ + if (bridgeService.deviceContainsType(input[i], "veraScene")) { out.push(input[i]); } } @@ -4653,12 +4890,12 @@ app.filter('configuredVeraScenes', function (bridgeService) { }); app.filter('configuredFibaroDevices', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "fibaroDevice")){ + if (bridgeService.deviceContainsType(input[i], "fibaroDevice")) { out.push(input[i]); } } @@ -4667,12 +4904,12 @@ app.filter('configuredFibaroDevices', function (bridgeService) { }); app.filter('configuredFibaroScenes', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "fibaroScene")){ + if (bridgeService.deviceContainsType(input[i], "fibaroScene")) { out.push(input[i]); } } @@ -4681,12 +4918,12 @@ app.filter('configuredFibaroScenes', function (bridgeService) { }); app.filter('configuredNestItems', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "nest")){ + if (bridgeService.deviceContainsType(input[i], "nest")) { out.push(input[i]); } } @@ -4695,12 +4932,12 @@ app.filter('configuredNestItems', function (bridgeService) { }); app.filter('configuredHueItems', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "hue")){ + if (bridgeService.deviceContainsType(input[i], "hue")) { out.push(input[i]); } } @@ -4709,12 +4946,12 @@ app.filter('configuredHueItems', function (bridgeService) { }); app.filter('configuredHalItems', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "hal")){ + if (bridgeService.deviceContainsType(input[i], "hal")) { out.push(input[i]); } } @@ -4723,12 +4960,12 @@ app.filter('configuredHalItems', function (bridgeService) { }); app.filter('configuredHarmonyActivities', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "harmonyActivity")){ + if (bridgeService.deviceContainsType(input[i], "harmonyActivity")) { out.push(input[i]); } } @@ -4739,7 +4976,7 @@ app.filter('configuredHarmonyActivities', function (bridgeService) { app.filter('configuredHarmonyButtons', function (bridgeService) { return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { if (bridgeService.deviceContainsType(input[i], "harmonyButton")) { @@ -4751,9 +4988,9 @@ app.filter('configuredHarmonyButtons', function (bridgeService) { }); app.filter('configuredMqttMsgs', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { if (bridgeService.deviceContainsType(input[i], "mqtt")) { @@ -4765,9 +5002,9 @@ app.filter('configuredMqttMsgs', function (bridgeService) { }); app.filter('configuredHassItems', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { if (bridgeService.deviceContainsType(input[i], "hass")) { @@ -4779,9 +5016,9 @@ app.filter('configuredHassItems', function (bridgeService) { }); app.filter('configuredDomoticzItems', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { if (bridgeService.deviceContainsType(input[i], "domoticz")) { @@ -4793,9 +5030,9 @@ app.filter('configuredDomoticzItems', function (bridgeService) { }); app.filter('configuredLifxItems', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { if (bridgeService.deviceContainsType(input[i], "lifx")) { @@ -4807,12 +5044,12 @@ app.filter('configuredLifxItems', function (bridgeService) { }); app.filter('configuredSomfyDevices', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "somfyDevice")){ + if (bridgeService.deviceContainsType(input[i], "somfyDevice")) { out.push(input[i]); } } @@ -4821,12 +5058,12 @@ app.filter('configuredSomfyDevices', function (bridgeService) { }); app.filter('configuredHomeWizardDevices', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.deviceContainsType(input[i], "homewizardDevice")){ + if (bridgeService.deviceContainsType(input[i], "homewizardDevice")) { out.push(input[i]); } } @@ -4835,9 +5072,9 @@ app.filter('configuredHomeWizardDevices', function (bridgeService) { }); app.filter('configuredOpenHABItems', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { if (bridgeService.deviceContainsType(input[i], "openhab")) { @@ -4849,9 +5086,9 @@ app.filter('configuredOpenHABItems', function (bridgeService) { }); app.filter('configuredFhemItems', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { if (bridgeService.deviceContainsType(input[i], "fhem")) { @@ -4863,9 +5100,9 @@ app.filter('configuredFhemItems', function (bridgeService) { }); app.filter('configuredBroadlinkItems', function (bridgeService) { - return function(input) { + return function (input) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { if (bridgeService.deviceContainsType(input[i], "broadlink")) { @@ -4877,9 +5114,9 @@ app.filter('configuredBroadlinkItems', function (bridgeService) { }); app.filter('filterDevicesByRequester', function () { - return function(input,search,mustContain,deviceType) { + return function (input, search, mustContain, deviceType) { var out = []; - if(input === undefined || input === null || input.length === undefined) + if (input === undefined || input === null || input.length === undefined) return out; var pattern = new RegExp(search); var patternType = new RegExp(deviceType); @@ -4891,15 +5128,15 @@ app.filter('filterDevicesByRequester', function () { if (!search || search.trim().length === 0) { // if search is empty and mustContain == true push only unfiltered devices if (mustContain) { if (!input[i].requesterAddress || input[i].requesterAddress.length === 0) { - pushRequester = true; + pushRequester = true; } } else { pushRequester = true; } } else { - if(pattern.test(input[i].requesterAddress) || !mustContain && (!input[i].requesterAddress || input[i].requesterAddress.length === 0)){ - pushRequester = true; - } + if (pattern.test(input[i].requesterAddress) || !mustContain && (!input[i].requesterAddress || input[i].requesterAddress.length === 0)) { + pushRequester = true; + } } // Check filter by deviceType @@ -4918,26 +5155,26 @@ app.filter('filterDevicesByRequester', function () { }); app.controller('LoginController', function ($scope, $location, Auth, bridgeService) { - $scope.failed = false; - $scope.isSecure = bridgeService.isSecure(); - $scope.loggedIn = Auth.isLoggedIn(); - $scope.login = function(username, password) { - Auth.login(username, password) - .then(function() { - $location.path("/"); - }, function() { - $scope.failed = true; - }); + $scope.failed = false; + $scope.isSecure = bridgeService.isSecure(); + $scope.loggedIn = Auth.isLoggedIn(); + $scope.login = function (username, password) { + Auth.login(username, password) + .then(function () { + $location.path("/"); + }, function () { + $scope.failed = true; + }); }; - $scope.logout = function() { - Auth.logout(); - $scope.isSecure = bridgeService.isSecure(); - $scope.loggedIn = Auth.isLoggedIn(); - if($scope.isSecure) - $location.path("/login"); - else - $location.path("/"); + $scope.logout = function () { + Auth.logout(); + $scope.isSecure = bridgeService.isSecure(); + $scope.loggedIn = Auth.isLoggedIn(); + if ($scope.isSecure) + $location.path("/login"); + else + $location.path("/"); }; }); @@ -4945,60 +5182,61 @@ app.controller('VersionController', function ($scope, bridgeService) { $scope.bridge = bridgeService.state; }); -app.directive('permission', ['Auth', function(Auth) { - return { - restrict: 'A', - scope: { - permission: '=' - }, - - link: function (scope, elem, attrs) { - scope.$watch(Auth.isLoggedIn, function() { - if (Auth.userHasPermission(scope.permission)) { - elem.show(); - } else { - elem.hide(); - } - }); - } - }; - }]); +app.directive('permission', ['Auth', function (Auth) { + return { + restrict: 'A', + scope: { + permission: '=' + }, -app.factory('Auth', function($resource, $rootScope, $sessionStorage, $http, $base64, bridgeService){ - - var auth = {}; - - /** - * Saves the current user in the root scope - * Call this in the app run() method - */ - auth.init = function(){ - if (auth.isLoggedIn()){ - $rootScope.user = auth.currentUser(); - } - }; - - auth.login = function(username, password){ + link: function (scope, elem, attrs) { + scope.$watch(Auth.isLoggedIn, function () { + if (Auth.userHasPermission(scope.permission)) { + elem.show(); + } else { + elem.hide(); + } + }); + } + }; +}]); + +app.factory('Auth', function ($resource, $rootScope, $sessionStorage, $http, $base64, bridgeService) { + + var auth = {}; + + /** + * Saves the current user in the root scope + * Call this in the app run() method + */ + auth.init = function () { + if (auth.isLoggedIn()) { + $rootScope.user = auth.currentUser(); + } + }; + + auth.login = function (username, password) { var newUserInfo = {}; newUserInfo = { - username: username, - password: password - }; + username: username, + password: password + }; var theEncodedPayload = $base64.encode(angular.toJson(newUserInfo)); - return $http.post(bridgeService.state.systemsbase + "/login", theEncodedPayload ).then( + return $http.post(bridgeService.state.systemsbase + "/login", theEncodedPayload).then( function (response) { var theResult = response.data; - $sessionStorage.user = theResult.user; - $rootScope.user = $sessionStorage.user; - bridgeService.state.loggedInUser = $sessionStorage.user.username; - bridgeService.getHABridgeVersion(); - }, function(error) { - bridgeService.displayWarn("Login Error: ", error); - }); - }; + $sessionStorage.user = theResult.user; + $rootScope.user = $sessionStorage.user; + bridgeService.state.loggedInUser = $sessionStorage.user.username; + bridgeService.getHABridgeVersion(); + }, + function (error) { + bridgeService.displayWarn("Login Error: ", error); + }); + }; - auth.logout = function() { + auth.logout = function () { delete $sessionStorage.user; delete $rootScope.user; delete bridgeService.state.loggedInUser; @@ -5014,60 +5252,60 @@ app.factory('Auth', function($resource, $rootScope, $sessionStorage, $http, $bas }; - auth.checkPermissionForView = function(view) { - if (!view.requiresAuthentication) { - return true; - } - - return userHasPermissionForView(view); - }; - - - var userHasPermissionForView = function(view){ - if(!auth.isLoggedIn()){ - return false; - } - - if(!view.permissions || !view.permissions.length){ - return true; - } - - return auth.userHasPermission(view.permissions); - }; - - - auth.userHasPermission = function(permissions){ - if(!bridgeService.isSecure()) - return true; - if(!auth.isLoggedIn()){ - return false; - } - - var found = false; - angular.forEach(permissions, function(permission, index){ - if ($sessionStorage.user.user_permissions.indexOf(permission) >= 0){ - found = true; - return; - } - }); - - return found; - }; - - - auth.currentUser = function(){ - if(!bridgeService.isSecure()) - return "nouser"; - return $sessionStorage.user; - }; - - - auth.isLoggedIn = function(){ - if(!bridgeService.isSecure()) - return true; - return $sessionStorage.user != null; - }; - - - return auth; + auth.checkPermissionForView = function (view) { + if (!view.requiresAuthentication) { + return true; + } + + return userHasPermissionForView(view); + }; + + + var userHasPermissionForView = function (view) { + if (!auth.isLoggedIn()) { + return false; + } + + if (!view.permissions || !view.permissions.length) { + return true; + } + + return auth.userHasPermission(view.permissions); + }; + + + auth.userHasPermission = function (permissions) { + if (!bridgeService.isSecure()) + return true; + if (!auth.isLoggedIn()) { + return false; + } + + var found = false; + angular.forEach(permissions, function (permission, index) { + if ($sessionStorage.user.user_permissions.indexOf(permission) >= 0) { + found = true; + return; + } + }); + + return found; + }; + + + auth.currentUser = function () { + if (!bridgeService.isSecure()) + return "nouser"; + return $sessionStorage.user; + }; + + + auth.isLoggedIn = function () { + if (!bridgeService.isSecure()) + return true; + return $sessionStorage.user != null; + }; + + + return auth; }); \ No newline at end of file diff --git a/src/main/resources/public/views/moziotdevice.html b/src/main/resources/public/views/moziotdevice.html index 7d35cf4..99acf20 100644 --- a/src/main/resources/public/views/moziotdevice.html +++ b/src/main/resources/public/views/moziotdevice.html @@ -19,7 +19,8 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • - +
  • Broadlink Devices
  • Add/Edit
  • @@ -31,17 +32,18 @@

    For any Mozilla IOT Device, use the build action buttons - to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then + to generate the item addition information into the ha-bridge device and this will put you into the edit + screen. Then you can modify the name to anything you want that will be the keyword - for the Echo or Google Home. Also, you can go back to any helper tab and click a build + for the Echo or Google Home. Also, you can go back to any helper tab and click a build action button to add another item for a multi-command. After you are - done in the edit tab, click the 'Add Bridge Device' to finish that selection + done in the edit tab, click the 'Add Bridge Device' to finish that selection setup. The 'Already Configured Mozilla IOT Devices' list below will show what is already setup for your Mozilla IOT.

    Also, use this select menu for which type of dim control you would - like to be generated: @@ -53,94 +55,91 @@ feature. Select your items and dim control type if wanted, then click bulk add below. Your items will be added with on and off or dim and off if selected with the name of the device from the Mozilla IOT.

    - - - - - - - - - - - - - - - - - - - - -
    Row - NameTypeMozilla IOTColor ActionsBuild Actions
    {{$index+1}} - {{moziotdevice.name}}{{moziotdevice.type}}{{moziotdevice.name}} - - - -
    -
    - + + + + + + + + + + + + + + + + + + + + +
    Row + NameTypeMozilla IOTColor ActionsBuild Actions
    {{$index+1}} + {{moziotdevice.deviceDetail.name}}{{moziotdevice.deviceDetail.type}}{{moziotdevice.gatewayName}} + + + + +
    +
    +

    - Already Configured OpenHAB Devices + Already Configured OpenHAB Devices

    - - - - - - - - - - - - - - - - - - - - - -
    RowNameCategoryMozilla IOTMap IdActions
    {{$index+1}}{{device.name}}{{device.deviceType}}{{device.targetDevice}}{{device.mapId}} -

    - - -

    -
    -
    + + + + + + + + + + + + + + + + + + + + + +
    RowNameCategoryMozilla IOTMap IdActions
    {{$index+1}}{{device.name}}{{device.deviceType}}{{device.targetDevice}}{{device.mapId}} +

    + + +

    +
    +
    + \ No newline at end of file diff --git a/src/main/resources/public/views/openhabdevice.html b/src/main/resources/public/views/openhabdevice.html index d7660d2..4f3081a 100644 --- a/src/main/resources/public/views/openhabdevice.html +++ b/src/main/resources/public/views/openhabdevice.html @@ -151,7 +151,7 @@ value="{{option.value}}">{{option.label}} - From fe0b072b4ec03ad3b042da38df7ff9a137582ab5 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Tue, 4 Jun 2019 16:36:21 -0500 Subject: [PATCH 24/52] Add renumbering and HomeGenie Helper --- pom.xml | 2 +- .../bwssystems/HABridge/BridgeSettings.java | 6 - .../HABridge/BridgeSettingsDescriptor.java | 44 ++++ .../bwssystems/HABridge/DeviceMapTypes.java | 6 +- .../com/bwssystems/HABridge/HABridge.java | 25 +- .../com/bwssystems/HABridge/HomeManager.java | 13 +- .../java/com/bwssystems/HABridge/NamedIP.java | 51 +++- .../HABridge/dao/DeviceRepository.java | 227 +++++++++--------- .../devicemanagmeent/DeviceResource.java | 70 +++--- .../HABridge/plugins/NestBridge/NestHome.java | 2 +- .../plugins/broadlink/BroadlinkHome.java | 2 +- .../plugins/domoticz/DomoticzHome.java | 2 +- .../HABridge/plugins/exec/CommandHome.java | 9 +- .../HABridge/plugins/fhem/FHEMHome.java | 2 +- .../HABridge/plugins/hal/HalHome.java | 2 +- .../HABridge/plugins/harmony/HarmonyHome.java | 2 +- .../HABridge/plugins/hass/HassHome.java | 2 +- .../plugins/homegenie/HomeGenieCommand.java | 40 +++ .../homegenie/HomeGenieCommandDetail.java | 40 +++ .../plugins/homegenie/HomeGenieDevice.java | 29 +++ .../plugins/homegenie/HomeGenieHome.java | 190 +++++++++++++++ .../plugins/homegenie/HomeGenieInstance.java | 144 +++++++++++ .../HABridge/plugins/homegenie/Module.java | 99 ++++++++ .../HABridge/plugins/homegenie/Property.java | 76 ++++++ .../plugins/homewizard/HomeWizardHome.java | 4 +- .../HABridge/plugins/http/HTTPHome.java | 2 +- .../HABridge/plugins/hue/HueHome.java | 2 +- .../HABridge/plugins/lifx/LifxHome.java | 2 +- .../HABridge/plugins/moziot/MozIotHome.java | 2 +- .../HABridge/plugins/mqtt/MQTTHome.java | 2 +- .../HABridge/plugins/openhab/OpenHABHome.java | 2 +- .../HABridge/plugins/somfy/SomfyHome.java | 6 +- .../HABridge/plugins/somfy/SomfyInfo.java | 10 +- .../HABridge/plugins/tcp/TCPHome.java | 2 +- .../HABridge/plugins/udp/UDPHome.java | 2 +- src/main/resources/public/scripts/app.js | 14 ++ .../public/views/homegeniedevice.html | 140 +++++++++++ src/main/resources/public/views/system.html | 72 +++++- 38 files changed, 1147 insertions(+), 200 deletions(-) create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieCommand.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieCommandDetail.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieDevice.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieHome.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieInstance.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/homegenie/Module.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/homegenie/Property.java create mode 100644 src/main/resources/public/views/homegeniedevice.html diff --git a/pom.xml b/pom.xml index 0db4b1e..bcbaba2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 5.2.next_b + 5.2.next_c jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index 2fe3326..076ddbb 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -77,7 +77,6 @@ public class BridgeSettings extends BackupHandler { } String serverPortOverride = System.getProperty("server.port"); String serverIpOverride = System.getProperty("server.ip"); - String upnpStrictOverride = System.getProperty("upnp.strict", "true"); if(configFileProperty != null) { log.info("reading from config file: " + configFileProperty); @@ -224,11 +223,6 @@ public class BridgeSettings extends BackupHandler { theBridgeSettings.setWebaddress(serverIpOverride); theBridgeSettings.setUpnpConfigAddress(serverIpOverride); } - - /* - if(upnpStrictOverride != null) - theBridgeSettings.setUpnpStrict(Boolean.parseBoolean(upnpStrictOverride)); - */ setupParams(Paths.get(theBridgeSettings.getConfigfile()), ".cfgbk", "habridge.config-"); diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java index 41b608e..c43f5cb 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java @@ -111,6 +111,9 @@ public class BridgeSettingsDescriptor { @SerializedName("fhemaddress") @Expose private IpList fhemaddress; + @SerializedName("homegenieaddress") + @Expose + private IpList homegenieaddress; @SerializedName("lifxconfigured") @Expose private boolean lifxconfigured; @@ -123,6 +126,9 @@ public class BridgeSettingsDescriptor { @SerializedName("upnporiginal") @Expose private boolean upnporiginal; + @SerializedName("seedid") + @Expose + private Integer seedid; // @SerializedName("activeloggers") // @Expose // private List activeloggers; @@ -142,6 +148,7 @@ public class BridgeSettingsDescriptor { private boolean openhabconfigured; private boolean fhemconfigured; private boolean moziotconfigured; + private boolean homegenieconfigured; // Deprecated settings private String haltoken; @@ -167,6 +174,7 @@ public class BridgeSettingsDescriptor { this.lifxconfigured = false; this.openhabconfigured = false; this.moziotconfigured = false; + this.homegenieconfigured = false; this.farenheit = true; this.securityData = null; this.settingsChanged = false; @@ -179,6 +187,7 @@ public class BridgeSettingsDescriptor { this.broadlinkconfigured = false; this.tracestate = false; this.upnporiginal = false; + this.seedid = 100; } public String getUpnpConfigAddress() { @@ -791,4 +800,39 @@ public class BridgeSettingsDescriptor { public void setUpnporiginal(boolean upnporiginal) { this.upnporiginal = upnporiginal; } + + public Integer getSeedid() { + return seedid; + } + + public void setSeedid(Integer seedid) { + this.seedid = seedid; + } + + public IpList getHomegenieaddress() { + return homegenieaddress; + } + + public void setHomegenieaddress(IpList homegenieaddress) { + this.homegenieaddress = homegenieaddress; + } + + public boolean isHomegenieconfigured() { + return homegenieconfigured; + } + + public void setHomegenieconfigured(boolean homegenieconfigured) { + this.homegenieconfigured = homegenieconfigured; + } + public Boolean isValidHomeGenie() { + if (this.getHomegenieaddress() == null || this.getHomegenieaddress().getDevices().size() <= 0) + return false; + + List devicesList = this.getHomegenieaddress().getDevices(); + if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + return false; + + return true; + } + } diff --git a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java index 9fc09ad..4664786 100644 --- a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java +++ b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java @@ -32,9 +32,10 @@ public class DeviceMapTypes { public final static String[] SOMFY_DEVICE = { "somfyDevice", "Somfy Device"}; public final static String[] LIFX_DEVICE = { "lifxDevice", "LIFX Device"}; public final static String[] OPENHAB_DEVICE = { "openhabDevice", "OpenHAB Device"}; - public final static String[] MOZIOT_DEVICE = { "moziotDevice", "Mozilla IOT Device"}; public final static String[] FHEM_DEVICE = { "fhemDevice", "FHEM Device"}; public final static String[] BROADLINK_DEVICE = { "broadlinkDevice", "Broadlink Device"}; + public final static String[] MOZIOT_DEVICE = { "moziotDevice", "Mozilla IOT Device"}; + public final static String[] HOMEGENIE_DEVICE = { "homegenieDevice", "HomeGenie Device"}; public final static int typeIndex = 0; public final static int displayIndex = 1; @@ -68,9 +69,10 @@ public class DeviceMapTypes { deviceMapTypes.add(FIBARO_SCENE); deviceMapTypes.add(SOMFY_DEVICE); deviceMapTypes.add(OPENHAB_DEVICE); - deviceMapTypes.add(MOZIOT_DEVICE); deviceMapTypes.add(FHEM_DEVICE); deviceMapTypes.add(BROADLINK_DEVICE); + deviceMapTypes.add(MOZIOT_DEVICE); + deviceMapTypes.add(HOMEGENIE_DEVICE); } public static int getTypeIndex() { return typeIndex; diff --git a/src/main/java/com/bwssystems/HABridge/HABridge.java b/src/main/java/com/bwssystems/HABridge/HABridge.java index 2e93760..5a937fb 100644 --- a/src/main/java/com/bwssystems/HABridge/HABridge.java +++ b/src/main/java/com/bwssystems/HABridge/HABridge.java @@ -56,7 +56,7 @@ public class HABridge { while(!bridgeSettings.getBridgeControl().isStop()) { bridgeSettings.buildSettings(); bridgeSettings.getBridgeSecurity().removeTestUsers(); - log.info("HA Bridge (v" + theVersion.getVersion() + ") initializing...."); + log.info("HA Bridge (v{}) initializing....", theVersion.getVersion() ); // sparkjava config directive to set ip address for the web server to listen on ipAddress(bridgeSettings.getBridgeSettingsDescriptor().getWebaddress()); // sparkjava config directive to set port for the web server to listen on @@ -94,10 +94,13 @@ public class HABridge { // wait for the sparkjava initialization of the rest api classes to be complete awaitInitialization(); - if(bridgeSettings.getBridgeSettingsDescriptor().isTraceupnp()) - log.info("Traceupnp: upnp config address: " + bridgeSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress() + "-useIface:" + - bridgeSettings.getBridgeSettingsDescriptor().isUseupnpiface() + " on web server: " + - bridgeSettings.getBridgeSettingsDescriptor().getWebaddress() + ":" + bridgeSettings.getBridgeSettingsDescriptor().getServerPort()); + if(bridgeSettings.getBridgeSettingsDescriptor().isTraceupnp()) { + log.info("Traceupnp: upnp config address: {} -useIface: {} on web server: {}:{}", + bridgeSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress(), + bridgeSettings.getBridgeSettingsDescriptor().isUseupnpiface(), + bridgeSettings.getBridgeSettingsDescriptor().getWebaddress(), + bridgeSettings.getBridgeSettingsDescriptor().getServerPort()); + } // setup the class to handle the upnp response rest api theSettingResponder = new UpnpSettingsResource(bridgeSettings); theSettingResponder.setupServer(); @@ -111,7 +114,7 @@ public class HABridge { theUpnpListener = null; } if(theUpnpListener != null && theUpnpListener.startListening()) - log.info("HA Bridge (v" + theVersion.getVersion() + ") reinitialization requessted...."); + log.info("HA Bridge (v{}) reinitialization requessted....", theVersion.getVersion()); else bridgeSettings.getBridgeControl().setStop(true); if(bridgeSettings.getBridgeSettingsDescriptor().isSettingsChanged()) @@ -126,7 +129,7 @@ public class HABridge { try { Thread.sleep(5000); } catch (InterruptedException e) { - log.error("Sleep error: " + e.getMessage()); + log.error("Sleep error: {}", e.getMessage()); } } } @@ -136,18 +139,18 @@ public class HABridge { try { HttpClientPool.shutdown(); } catch (InterruptedException e) { - log.warn("Error shutting down http pool: " + e.getMessage());; + log.warn("Error shutting down http pool: {}", e.getMessage());; } catch (IOException e) { - log.warn("Error shutting down http pool: " + e.getMessage());; + log.warn("Error shutting down http pool: {}", e.getMessage());; } thePool = null; - log.info("HA Bridge (v" + theVersion.getVersion() + ") exiting...."); + log.info("HA Bridge (v{}) exiting....", theVersion.getVersion()); System.exit(0); } private static void theExceptionHandler(Exception e, Integer thePort) { Logger log = LoggerFactory.getLogger(HABridge.class); - log.error("Could not start ha-bridge webservice on port [" + thePort + "] due to: " + e.getMessage()); + log.error("Could not start ha-bridge webservice on port [{}] due to: {}", thePort, e.getMessage()); System.exit(0); } } diff --git a/src/main/java/com/bwssystems/HABridge/HomeManager.java b/src/main/java/com/bwssystems/HABridge/HomeManager.java index a9e56fa..dc923c2 100644 --- a/src/main/java/com/bwssystems/HABridge/HomeManager.java +++ b/src/main/java/com/bwssystems/HABridge/HomeManager.java @@ -28,6 +28,7 @@ import com.bwssystems.HABridge.plugins.tcp.TCPHome; import com.bwssystems.HABridge.plugins.udp.UDPHome; import com.bwssystems.HABridge.plugins.vera.VeraHome; import com.bwssystems.HABridge.plugins.fibaro.FibaroHome; +import com.bwssystems.HABridge.plugins.homegenie.HomeGenieHome; import com.bwssystems.HABridge.util.UDPDatagramSender; public class HomeManager { @@ -121,10 +122,6 @@ public class HomeManager { aHome = new OpenHABHome(bridgeSettings); resourceList.put(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex], aHome); homeList.put(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex], aHome); - //setup the Mozilla IOT configuration if available - aHome = new MozIotHome(bridgeSettings); - resourceList.put(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex], aHome); - homeList.put(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex], aHome); //setup the FHEM configuration if available aHome = new FHEMHome(bridgeSettings); resourceList.put(DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex], aHome); @@ -133,6 +130,14 @@ public class HomeManager { aHome = new BroadlinkHome(bridgeSettings); resourceList.put(DeviceMapTypes.BROADLINK_DEVICE[DeviceMapTypes.typeIndex], aHome); homeList.put(DeviceMapTypes.BROADLINK_DEVICE[DeviceMapTypes.typeIndex], aHome); + //setup the Mozilla IOT configuration if available + aHome = new MozIotHome(bridgeSettings); + resourceList.put(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex], aHome); + homeList.put(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex], aHome); + //setup the HomeGenie configuration if available + aHome = new HomeGenieHome(bridgeSettings); + resourceList.put(DeviceMapTypes.HOMEGENIE_DEVICE[DeviceMapTypes.typeIndex], aHome); + homeList.put(DeviceMapTypes.HOMEGENIE_DEVICE[DeviceMapTypes.typeIndex], aHome); } public Home findHome(String type) { diff --git a/src/main/java/com/bwssystems/HABridge/NamedIP.java b/src/main/java/com/bwssystems/HABridge/NamedIP.java index 507ee56..a5f8c89 100644 --- a/src/main/java/com/bwssystems/HABridge/NamedIP.java +++ b/src/main/java/com/bwssystems/HABridge/NamedIP.java @@ -11,53 +11,88 @@ public class NamedIP { private String password; private JsonObject extensions; private Boolean secure; - + private String httpPreamble; + public String getName() { return name; } + public void setName(String name) { this.name = name; } + public String getIp() { return ip; } + public void setIp(String ip) { this.ip = ip; } - public String getWebhook() { - return webhook; - } - public void setWebhook(final String webhook) { - this.webhook = webhook; - } - public String getPort() { + + public String getWebhook() { + return webhook; + } + + public void setWebhook(final String webhook) { + this.webhook = webhook; + } + + public String getPort() { return port; } + public void setPort(String port) { this.port = port; } + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + public String getPassword() { return password; } + public void setPassword(String password) { this.password = password; } + public Boolean getSecure() { return secure; } + public void setSecure(Boolean secure) { this.secure = secure; } + public JsonObject getExtensions() { return extensions; } + public void setExtensions(JsonObject extensions) { this.extensions = extensions; } + + public String getHttpPreamble() { + if (httpPreamble == null || httpPreamble.length() == 0) { + if (getSecure() != null && getSecure()) + httpPreamble = "https://"; + else + httpPreamble = "http://"; + + httpPreamble = httpPreamble + getIp(); + if (getPort() != null && getPort().length() > 0) { + httpPreamble = httpPreamble + ":" + getPort(); + } + } + return httpPreamble; + } + + public void setHttpPreamble(String httpPreamble) { + this.httpPreamble = httpPreamble; + } } diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java index aafc0df..9755138 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java @@ -1,6 +1,5 @@ package com.bwssystems.HABridge.dao; - import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; @@ -38,48 +37,47 @@ import java.util.Arrays; */ public class DeviceRepository extends BackupHandler { private Map devices; - private Path repositoryPath; + private Path repositoryPath; private Gson gson; - private Integer nextId; - private Logger log = LoggerFactory.getLogger(DeviceRepository.class); - - public DeviceRepository(String deviceDb) { + private Integer nextId; + private Integer seedId; + private Logger log = LoggerFactory.getLogger(DeviceRepository.class); + + public DeviceRepository(String deviceDb, Integer seedid) { super(); - gson = - new GsonBuilder() - .excludeFieldsWithoutExposeAnnotation() - .create(); + gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); repositoryPath = null; repositoryPath = Paths.get(deviceDb); setupParams(repositoryPath, ".bk", "device.db-"); - nextId = 0; + nextId = seedid; + seedId = seedid; _loadRepository(repositoryPath); } - - public void loadRepository() { - if(repositoryPath != null) - _loadRepository(repositoryPath); - } - private void _loadRepository(Path aPath){ + + public void loadRepository() { + if (repositoryPath != null) + _loadRepository(repositoryPath); + } + + private void _loadRepository(Path aPath) { String jsonContent = repositoryReader(aPath); devices = new HashMap(); - - if(jsonContent != null) - { + + if (jsonContent != null) { DeviceDescriptor list[] = gson.fromJson(jsonContent, DeviceDescriptor[].class); - for(int i = 0; i < list.length; i++) { - if(list[i].getColorUrl() == null || list[i].getColorUrl().isEmpty()) + for (int i = 0; i < list.length; i++) { + if (list[i].getColorUrl() == null || list[i].getColorUrl().isEmpty()) list[i].setDeviceState(DeviceState.createDeviceState(false)); else list[i].setDeviceState(DeviceState.createDeviceState(true)); put(list[i].getId(), list[i]); - if(Integer.decode(list[i].getId()) > nextId) { + if (Integer.decode(list[i].getId()) > nextId) { nextId = Integer.decode(list[i].getId()); } } - } - } - + } + } + public List findAll() { List list = new ArrayList(devices.values()); return list; @@ -87,8 +85,8 @@ public class DeviceRepository extends BackupHandler { public List findActive() { List list = new ArrayList(); - for(DeviceDescriptor aDevice : new ArrayList(devices.values())) { - if(!aDevice.isInactive()) + for (DeviceDescriptor aDevice : new ArrayList(devices.values())) { + if (!aDevice.isInactive()) list.add(aDevice); } return list; @@ -105,12 +103,12 @@ public class DeviceRepository extends BackupHandler { DeviceDescriptor theDevice; String theRequesterAddress; - HashMap addressMap; + HashMap addressMap; while (anIterator.hasNext()) { theDevice = anIterator.next(); theRequesterAddress = theDevice.getRequesterAddress(); addressMap = new HashMap(); - if(theRequesterAddress != null) { + if (theRequesterAddress != null) { if (theRequesterAddress.contains(",")) { String[] theArray = theRequesterAddress.split(","); for (String v : theArray) { @@ -125,151 +123,164 @@ public class DeviceRepository extends BackupHandler { return theReturnList; } - public Map findAllByGroupWithState(String[] lightsInGroup, String anAddress, HueHome myHueHome, Gson aGsonBuilder) { + public Map findAllByGroupWithState(String[] lightsInGroup, String anAddress, + HueHome myHueHome, Gson aGsonBuilder) { return findAllByGroupWithState(lightsInGroup, anAddress, myHueHome, aGsonBuilder, false); } - public Map findAllByGroupWithState(String[] lightsInGroup, String anAddress, HueHome myHueHome, Gson aGsonBuilder, boolean ignoreAddress) { + public Map findAllByGroupWithState(String[] lightsInGroup, String anAddress, + HueHome myHueHome, Gson aGsonBuilder, boolean ignoreAddress) { Map deviceResponseMap = new HashMap(); Map lights = new HashMap(devices); lights.keySet().retainAll(Arrays.asList(lightsInGroup)); - for (DeviceDescriptor light : (ignoreAddress ? lights.values() : findAllByRequester(anAddress, lights.values()))) { + for (DeviceDescriptor light : (ignoreAddress ? lights.values() + : findAllByRequester(anAddress, lights.values()))) { DeviceResponse deviceResponse = null; - if(!light.isInactive()) { + if (!light.isInactive()) { if (light.containsType(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) { CallItem[] callItems = null; try { - if(light.getOnUrl() != null) + if (light.getOnUrl() != null) callItems = aGsonBuilder.fromJson(light.getOnUrl(), CallItem[].class); - } catch(JsonSyntaxException e) { - log.warn("Could not decode Json for url items to get Hue state for device: " + light.getName()); + } catch (JsonSyntaxException e) { + log.warn("Could not decode Json for url items to get Hue state for device: {}", light.getName()); callItems = null; } for (int i = 0; callItems != null && i < callItems.length; i++) { - if((callItems[i].getType() != null && callItems[i].getType().equals(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) || - (callItems[i].getItem() != null && callItems[i].getItem().getAsString() != null && callItems[i].getItem().getAsString().contains("hueName"))) { + if ((callItems[i].getType() != null + && callItems[i].getType().equals(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) + || (callItems[i].getItem() != null && callItems[i].getItem().getAsString() != null + && callItems[i].getItem().getAsString().contains("hueName"))) { deviceResponse = myHueHome.getHueDeviceInfo(callItems[i], light); i = callItems.length; } } } - + if (deviceResponse == null) { deviceResponse = DeviceResponse.createResponse(light); } - deviceResponseMap.put(light.getId(), deviceResponse); + deviceResponseMap.put(light.getId(), deviceResponse); } } return (deviceResponseMap.size() == 0) ? null : deviceResponseMap; } public DeviceDescriptor findOne(String id) { - return devices.get(id); - } - + return devices.get(id); + } + private void put(String id, DeviceDescriptor aDescriptor) { - devices.put(id, aDescriptor); - } - + devices.put(id, aDescriptor); + } + public void save(DeviceDescriptor[] descriptors) { String theNames = ""; - for(int i = 0; i < descriptors.length; i++) { - if(descriptors[i].getId() != null && descriptors[i].getId().length() > 0) - devices.remove(descriptors[i].getId()); - else { - nextId++; - descriptors[i].setId(String.valueOf(nextId)); - } - if(descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) { - String hexValue = HexLibrary.encodeUsingBigIntegerToString(descriptors[i].getId()); + 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(nextId)); + nextId++; + } + if (descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) { + String hexValue = HexLibrary.encodeUsingBigIntegerToString(descriptors[i].getId()); - descriptors[i].setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); - } - put(descriptors[i].getId(), descriptors[i]); - theNames = theNames + " " + descriptors[i].getName() + ", "; + descriptors[i].setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); + } + put(descriptors[i].getId(), descriptors[i]); + theNames = theNames + " " + descriptors[i].getName() + ", "; } - String jsonValue = gson.toJson(findAll()); - repositoryWriter(jsonValue, repositoryPath); - log.debug("Save device(s): " + theNames); - } - + String jsonValue = gson.toJson(findAll()); + repositoryWriter(jsonValue, repositoryPath); + log.debug("Save device(s): {}", theNames); + } + public void renumber() { List list = new ArrayList(devices.values()); Iterator deviceIterator = list.iterator(); - Map newdevices = new HashMap();; - nextId = 0; - log.debug("Renumber devices."); - while(deviceIterator.hasNext()) { - nextId++; - DeviceDescriptor theDevice = deviceIterator.next(); - theDevice.setId(String.valueOf(nextId)); - String hexValue = HexLibrary.encodeUsingBigIntegerToString(nextId.toString()); - - theDevice.setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); - newdevices.put(theDevice.getId(), theDevice); - } - devices = newdevices; - String jsonValue = gson.toJson(findAll()); - repositoryWriter(jsonValue, repositoryPath); - } - - public String delete(DeviceDescriptor aDescriptor) { - if (aDescriptor != null) { - devices.remove(aDescriptor.getId()); - JsonTransformer aRenderer = new JsonTransformer(); - String jsonValue = aRenderer.render(findAll()); - repositoryWriter(jsonValue, repositoryPath); - return "Device with id '" + aDescriptor.getId() + "' deleted"; - } else { - return "Device not found"; - } + Map newdevices = new HashMap(); + ; + nextId = seedId; + String hexValue; + Integer newValue; + DeviceDescriptor theDevice; + log.debug("Renumber devices with seed: {}", seedId); + while (deviceIterator.hasNext()) { + theDevice = deviceIterator.next(); + theDevice.setId(String.valueOf(nextId)); + newValue = nextId % 256; + if (newValue <= 0) + newValue = 1; + else if (newValue > 255) + newValue = 255; + hexValue = HexLibrary.encodeUsingBigIntegerToString(newValue.toString()); + + theDevice.setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); + newdevices.put(theDevice.getId(), theDevice); + nextId++; + } + devices = newdevices; + String jsonValue = gson.toJson(findAll()); + repositoryWriter(jsonValue, repositoryPath); + } + + public String delete(DeviceDescriptor aDescriptor) { + if (aDescriptor != null) { + devices.remove(aDescriptor.getId()); + JsonTransformer aRenderer = new JsonTransformer(); + String jsonValue = aRenderer.render(findAll()); + repositoryWriter(jsonValue, repositoryPath); + return "Device with id '" + aDescriptor.getId() + "' deleted"; + } else { + return "Device not found"; + } + + } - } - private void repositoryWriter(String content, Path filePath) { - if(Files.exists(filePath) && !Files.isWritable(filePath)){ - log.error("Error file is not writable: " + filePath); + if (Files.exists(filePath) && !Files.isWritable(filePath)) { + log.error("Error file is not writable: {}", filePath); return; } - - if(Files.notExists(filePath.getParent())) { + + if (Files.notExists(filePath.getParent())) { try { Files.createDirectories(filePath.getParent()); } catch (IOException e) { - log.error("Error creating the directory: " + filePath + " message: " + e.getMessage(), e); + log.error("Error creating the directory: {} message: {}", filePath, e.getMessage(), e); } } try { Path target = null; - if(Files.exists(filePath)) { + if (Files.exists(filePath)) { target = FileSystems.getDefault().getPath(filePath.getParent().toString(), "device.db.old"); Files.move(filePath, target); } Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE); - if(target != null) + if (target != null) Files.delete(target); } catch (IOException e) { - log.error("Error writing the file: " + filePath + " message: " + e.getMessage(), e); + log.error("Error writing the file: {} message: {}", filePath, e.getMessage(), e); } } - + private String repositoryReader(Path filePath) { String content = null; - if(Files.notExists(filePath) || !Files.isReadable(filePath)){ - log.warn("Error reading the file: " + filePath + " - Does not exist or is not readable. continuing..."); + if (Files.notExists(filePath) || !Files.isReadable(filePath)) { + log.warn("Error reading the file: {} - Does not exist or is not readable. continuing...", filePath); return null; } - try { content = new String(Files.readAllBytes(filePath)); } catch (IOException e) { - log.error("Error reading the file: " + filePath + " message: " + e.getMessage(), e); + log.error("Error reading the file: {} message: {}", filePath, e.getMessage(), e); } - + return content; } } \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index bad312f..692925b 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -44,13 +44,15 @@ public class DeviceResource { private BridgeSettings bridgeSettings; private Gson aGsonHandler; private static final Set supportedVerbs = new HashSet<>(Arrays.asList("get", "put", "post")); + private String errorMessage; public DeviceResource(BridgeSettings theSettings, HomeManager aHomeManager) { bridgeSettings = theSettings; - this.deviceRepository = new DeviceRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpDeviceDb()); + this.deviceRepository = new DeviceRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpDeviceDb(), bridgeSettings.getBridgeSettingsDescriptor().getSeedid()); this.groupRepository = new GroupRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpGroupDb()); homeManager = aHomeManager; aGsonHandler = new GsonBuilder().create(); + errorMessage = null; setupEndpoints(); } @@ -83,7 +85,7 @@ public class DeviceResource { return ""; }); post(API_CONTEXT, "application/json", (request, response) -> { - log.debug("Create a Device(s) - request body: " + request.body()); + log.debug("Create a Device(s) - request body: {}", request.body()); DeviceDescriptor devices[]; if(request.body().substring(0,1).equalsIgnoreCase("[") == true) { devices = new Gson().fromJson(request.body(), DeviceDescriptor[].class); @@ -93,13 +95,12 @@ public class DeviceResource { } @SuppressWarnings("unused") CallItem[] callItems = null; - String errorMessage = null; for(int i = 0; i < devices.length; i++) { if(devices[i].getContentBody() != null ) { if (devices[i].getContentType() == null || devices[i].getHttpVerb() == null || !supportedVerbs.contains(devices[i].getHttpVerb().toLowerCase())) { response.status(HttpStatus.SC_BAD_REQUEST); errorMessage = "Bad http verb in create device(s) for name: " + devices[i].getName() + " with verb: " + devices[i].getHttpVerb(); - log.debug(errorMessage); + log.warn(errorMessage); return new ErrorMessage(errorMessage); } } @@ -109,7 +110,7 @@ public class DeviceResource { } catch(JsonSyntaxException e) { response.status(HttpStatus.SC_BAD_REQUEST); errorMessage = "Bad on URL JSON in create device(s) for name: " + devices[i].getName() + " with on URL: " + devices[i].getOnUrl(); - log.debug(errorMessage); + log.warn(errorMessage); return new ErrorMessage(errorMessage); } try { @@ -118,7 +119,7 @@ public class DeviceResource { } catch(JsonSyntaxException e) { response.status(HttpStatus.SC_BAD_REQUEST); errorMessage = "Bad dim URL JSON in create device(s) for name: " + devices[i].getName() + " with dim URL: " + devices[i].getDimUrl(); - log.debug(errorMessage); + log.warn(errorMessage); return new ErrorMessage(errorMessage); } try { @@ -127,7 +128,7 @@ public class DeviceResource { } catch(JsonSyntaxException e) { response.status(HttpStatus.SC_BAD_REQUEST); errorMessage = "Bad off URL JSON in create device(s) for name: " + devices[i].getName() + " with off URL: " + devices[i].getOffUrl(); - log.debug(errorMessage); + log.warn(errorMessage); return new ErrorMessage(errorMessage); } try { @@ -136,13 +137,13 @@ public class DeviceResource { } catch(JsonSyntaxException e) { response.status(HttpStatus.SC_BAD_REQUEST); errorMessage = "Bad color URL JSON in create device(s) for name: " + devices[i].getName() + " with color URL: " + devices[i].getColorUrl(); - log.debug(errorMessage); + log.warn(errorMessage); return new ErrorMessage(errorMessage); } } deviceRepository.save(devices); - log.debug("Created a Device(s): " + request.body()); + log.debug("Created a Device(s): {}", request.body()); response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.status(HttpStatus.SC_CREATED); @@ -160,16 +161,17 @@ public class DeviceResource { return ""; }); put (API_CONTEXT + "/:id", "application/json", (request, response) -> { - log.debug("Edit a Device - request body: " + request.body()); + log.debug("Edit a Device - request body: {}", request.body()); DeviceDescriptor device = new Gson().fromJson(request.body(), DeviceDescriptor.class); if(deviceRepository.findOne(request.params(":id")) == null){ - log.debug("Could not save an edited device, Device Id not found: " + request.params(":id")); + errorMessage = "Could not save an edited device, Device Id not found: " + request.params(":id"); + log.warn(errorMessage); response.status(HttpStatus.SC_BAD_REQUEST); - return new ErrorMessage("Could not save an edited device, Device Id not found: " + request.params(":id") + " "); + return new ErrorMessage(errorMessage); } else { - log.debug("Saving an edited Device: " + device.getName()); + log.debug("Saving an edited Device: {}", device.getName()); if (device.getDeviceType() != null) device.setDeviceType(device.getDeviceType()); @@ -187,17 +189,19 @@ public class DeviceResource { log.debug("Get all devices"); JsonTransformer aRenderer = new JsonTransformer(); String theStream = aRenderer.render(deviceList); - log.debug("The Device List: " + theStream); + log.debug("The Device List: {}", theStream); response.status(HttpStatus.SC_OK); return deviceList; }, new JsonTransformer()); get (API_CONTEXT + "/:id", "application/json", (request, response) -> { - log.debug("Get a device"); + log.debug("Get a device: {}", request.params(":id")); DeviceDescriptor descriptor = deviceRepository.findOne(request.params(":id")); if(descriptor == null) { + errorMessage = "Could not find, id: " + request.params(":id"); + log.warn(errorMessage); response.status(HttpStatus.SC_NOT_FOUND); - return new ErrorMessage("Could not find, id: " + request.params(":id") + " "); + return new ErrorMessage(errorMessage); } else response.status(HttpStatus.SC_OK); @@ -206,11 +210,13 @@ public class DeviceResource { delete (API_CONTEXT + "/:id", "application/json", (request, response) -> { String anId = request.params(":id"); - log.debug("Delete a device: " + anId); + log.debug("Delete a device: {}", anId); DeviceDescriptor deleted = deviceRepository.findOne(anId); if(deleted == null) { + errorMessage = "Could not delete, id: " + anId + " not found. "; + log.warn(errorMessage); response.status(HttpStatus.SC_NOT_FOUND); - return new ErrorMessage("Could not delete, id: " + anId + " not found. "); + return new ErrorMessage(errorMessage); } else { @@ -321,12 +327,6 @@ public class DeviceResource { return homeManager.findResource(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex]); }, new JsonTransformer()); - get (API_CONTEXT + "/moziot/devices", "application/json", (request, response) -> { - log.debug("Get MOzilla IOT devices"); - response.status(HttpStatus.SC_OK); - return homeManager.findResource(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex]); - }, new JsonTransformer()); - get (API_CONTEXT + "/fhem/devices", "application/json", (request, response) -> { log.debug("Get FHEM devices"); response.status(HttpStatus.SC_OK); @@ -339,6 +339,18 @@ public class DeviceResource { return homeManager.findResource(DeviceMapTypes.BROADLINK_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.BROADLINK_DEVICE[DeviceMapTypes.typeIndex]); }, new JsonTransformer()); + get (API_CONTEXT + "/moziot/devices", "application/json", (request, response) -> { + log.debug("Get Mozilla IOT devices"); + response.status(HttpStatus.SC_OK); + return homeManager.findResource(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex]); + }, new JsonTransformer()); + + get (API_CONTEXT + "/homegenie/devices", "application/json", (request, response) -> { + log.debug("Get HomeGenie devices"); + response.status(HttpStatus.SC_OK); + return homeManager.findResource(DeviceMapTypes.HOMEGENIE_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.HOMEGENIE_DEVICE[DeviceMapTypes.typeIndex]); + }, new JsonTransformer()); + get (API_CONTEXT + "/map/types", "application/json", (request, response) -> { log.debug("Get map types"); return new DeviceMapTypes().getDeviceMapTypes(); @@ -346,7 +358,7 @@ public class DeviceResource { get (API_CONTEXT + "/refresh/:typeIndex", "application/json", (request, response) -> { String typeIndex = request.params(":typeIndex"); - log.debug("Refresh Home: " + typeIndex); + log.debug("Refresh Home: {}", typeIndex); response.status(HttpStatus.SC_OK); homeManager.findResource(typeIndex).refresh(); return null; @@ -368,7 +380,7 @@ public class DeviceResource { }, new JsonTransformer()); get (API_CONTEXT + "/backup/available", "application/json", (request, response) -> { - log.debug("Get backup filenames"); + log.debug("Get backup filenames."); response.status(HttpStatus.SC_OK); return deviceRepository.getBackups(); }, new JsonTransformer()); @@ -383,7 +395,7 @@ public class DeviceResource { return ""; }); put (API_CONTEXT + "/backup/create", "application/json", (request, response) -> { - log.debug("Create backup: " + request.body()); + log.debug("Create backup: {}", request.body()); BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class); BackupFilename returnFilename = new BackupFilename(); returnFilename.setFilename(deviceRepository.backup(aFilename.getFilename())); @@ -400,7 +412,7 @@ public class DeviceResource { return ""; }); post (API_CONTEXT + "/backup/delete", "application/json", (request, response) -> { - log.debug("Delete backup: " + request.body()); + log.debug("Delete backup: {}", request.body()); BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class); if(aFilename != null) deviceRepository.deleteBackup(aFilename.getFilename()); @@ -419,7 +431,7 @@ public class DeviceResource { return ""; }); post (API_CONTEXT + "/backup/restore", "application/json", (request, response) -> { - log.debug("Restore backup: " + request.body()); + log.debug("Restore backup: {}", request.body()); BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class); if(aFilename != null) { deviceRepository.restoreBackup(aFilename.getFilename()); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java b/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java index 785f751..3abd438 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/NestBridge/NestHome.java @@ -125,7 +125,7 @@ public class NestHome implements com.bwssystems.HABridge.Home { if(anItem.getItem().isJsonObject()) homeAway = aGsonHandler.fromJson(anItem.getItem(), NestInstruction.class); else - homeAway = aGsonHandler.fromJson(anItem.getItem().getAsString(), NestInstruction.class); + homeAway = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), NestInstruction.class); theNest.getHome(homeAway.getName()).setAway(homeAway.getAway()); } else if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_THERMO_SET[DeviceMapTypes.typeIndex])) { NestInstruction thermoSetting = null; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java index 76569a6..4c0b408 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/broadlink/BroadlinkHome.java @@ -113,7 +113,7 @@ public class BroadlinkHome implements Home { if(anItem.getItem().isJsonObject()) broadlinkCommand = new Gson().fromJson(anItem.getItem(), BroadlinkEntry.class); else - broadlinkCommand = new Gson().fromJson(anItem.getItem().getAsString(), BroadlinkEntry.class); + broadlinkCommand = new Gson().fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), BroadlinkEntry.class); BLDevice theDevice = null; if(broadlinkMap != null && !broadlinkMap.isEmpty()) theDevice = broadlinkMap.get(broadlinkCommand.getId()); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java index 57f2afb..a4b7f41 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java @@ -88,7 +88,7 @@ public class DomoticzHome implements Home { Devices theDomoticzApiResponse = null; String responseString = null; - String theUrl = anItem.getItem().getAsString(); + String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); if(theUrl != null && !theUrl.isEmpty () && (theUrl.startsWith("http://") || theUrl.startsWith("https://"))) { String intermediate = theUrl.substring(theUrl.indexOf("://") + 3); String hostPortion = intermediate.substring(0, intermediate.indexOf('/')); 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 26340d1..c77e66e 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/exec/CommandHome.java @@ -31,13 +31,14 @@ public class CommandHome implements Home { @Override public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) { - log.debug("Exec Request called with url: " + anItem.getItem().getAsString() + " and exec Garden: " + (theSettings.getBridgeSecurity().getExecGarden() == null ? "not given" : theSettings.getBridgeSecurity().getExecGarden())); + String theItem = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); + log.debug("Exec Request called with url: {} and exec Garden: {}", theItem, (theSettings.getBridgeSecurity().getExecGarden() == null ? "not given" : theSettings.getBridgeSecurity().getExecGarden())); String responseString = null; String intermediate; - if (anItem.getItem().getAsString().contains("exec://")) - intermediate = anItem.getItem().getAsString().substring(anItem.getItem().getAsString().indexOf("://") + 3); + if (theItem.contains("exec://")) + intermediate = theItem.substring(anItem.getItem().getAsString().indexOf("://") + 3); else - intermediate = anItem.getItem().getAsString(); + intermediate = theItem; intermediate = BrightnessDecode.calculateReplaceIntensityValue(intermediate, intensity, targetBri, targetBriInc, false); if (colorData != null) { intermediate = ColorDecode.replaceColorData(intermediate, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java b/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java index d2d514e..e464c23 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java @@ -58,7 +58,7 @@ public class FHEMHome implements Home { if(anItem.getItem().isJsonObject()) theCommand = new Gson().fromJson(anItem.getItem(), FHEMCommand.class); else - theCommand = new Gson().fromJson(anItem.getItem().getAsString(), FHEMCommand.class); + theCommand = new Gson().fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), FHEMCommand.class); } catch(Exception e) { log.warn("Cannot parse command to FHEM <<<" + theUrl + ">>>", e); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, 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 4c5a091..77ae553 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java @@ -123,7 +123,7 @@ public class HalHome implements Home { Integer targetBri,Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) { boolean halFound = false; String responseString = null; - String theUrl = anItem.getItem().getAsString(); + String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); if(theUrl != null && !theUrl.isEmpty () && theUrl.contains("http")) { String intermediate = theUrl.substring(theUrl.indexOf("://") + 3); String hostPortion = intermediate.substring(0, intermediate.indexOf('/')); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java index 0ed07ce..8927bcc 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyHome.java @@ -194,7 +194,7 @@ public class HarmonyHome implements Home { if (anItem.getItem().isJsonObject()) anActivity = aGsonHandler.fromJson(anItem.getItem(), RunActivity.class); else - anActivity = aGsonHandler.fromJson(anItem.getItem().getAsString(), RunActivity.class); + anActivity = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), RunActivity.class); if (anActivity.getHub() == null || anActivity.getHub().isEmpty()) anActivity.setHub(device.getTargetDevice()); HarmonyHandler myHarmony = getHarmonyHandler(anActivity.getHub()); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java b/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java index 292b32e..090f45d 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hass/HassHome.java @@ -138,7 +138,7 @@ public class HassHome implements Home { if(anItem.getItem().isJsonObject()) hassCommand = aGsonHandler.fromJson(anItem.getItem(), HassCommand.class); else - hassCommand = aGsonHandler.fromJson(anItem.getItem().getAsString(), HassCommand.class); + hassCommand = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), HassCommand.class); hassCommand.setBri(BrightnessDecode.replaceIntensityValue(hassCommand.getBri(), BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false)); HomeAssistant homeAssistant = getHomeAssistant(hassCommand.getHassName()); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieCommand.java b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieCommand.java new file mode 100644 index 0000000..e6f6051 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieCommand.java @@ -0,0 +1,40 @@ +package com.bwssystems.HABridge.plugins.homegenie; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class HomeGenieCommand { + @SerializedName("moduleType") + @Expose + private String moduleType; + @SerializedName("deviceId") + @Expose + private String deviceId; + @SerializedName("command") + @Expose + private HomeGenieCommandDetail command; + + public String getModuleType() { + return moduleType; + } + + public void setModuleType(String moduleType) { + this.moduleType = moduleType; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public HomeGenieCommandDetail getCommand() { + return command; + } + + public void setCommand(HomeGenieCommandDetail command) { + this.command = command; + } +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieCommandDetail.java b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieCommandDetail.java new file mode 100644 index 0000000..4e712ca --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieCommandDetail.java @@ -0,0 +1,40 @@ +package com.bwssystems.HABridge.plugins.homegenie; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class HomeGenieCommandDetail { + @SerializedName("command") + @Expose + private String command; + @SerializedName("level") + @Expose + private String level; + @SerializedName("color") + @Expose + private String color; + + public String getLevel() { + return level; + } + + public void setLevel(String level) { + this.level = level; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String getCommand() { + return command; + } + + public void setCommand(String command) { + this.command = command; + } +} \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieDevice.java b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieDevice.java new file mode 100644 index 0000000..f19ccc3 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieDevice.java @@ -0,0 +1,29 @@ +package com.bwssystems.HABridge.plugins.homegenie; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class HomeGenieDevice { + @SerializedName("gatewayName") + @Expose + private String gatewayName; + @SerializedName("deviceDetail") + @Expose + private Module deviceDetail; + + public String getGatewayName() { + return gatewayName; + } + + public void setGatewayName(String gatewayName) { + this.gatewayName = gatewayName; + } + + public Module getDeviceDetail() { + return deviceDetail; + } + + public void setDeviceDetail(Module deviceDetail) { + this.deviceDetail = deviceDetail; + } +} \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieHome.java b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieHome.java new file mode 100644 index 0000000..bbdaf8d --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieHome.java @@ -0,0 +1,190 @@ +package com.bwssystems.HABridge.plugins.homegenie; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bwssystems.HABridge.BridgeSettings; +import com.bwssystems.HABridge.Home; +import com.bwssystems.HABridge.NamedIP; +import com.bwssystems.HABridge.api.CallItem; +import com.bwssystems.HABridge.api.hue.HueError; +import com.bwssystems.HABridge.api.hue.HueErrorResponse; +import com.bwssystems.HABridge.dao.DeviceDescriptor; +import com.bwssystems.HABridge.hue.BrightnessDecode; +import com.bwssystems.HABridge.hue.ColorData; +import com.bwssystems.HABridge.hue.ColorDecode; +import com.bwssystems.HABridge.hue.DeviceDataDecode; +import com.bwssystems.HABridge.hue.MultiCommandUtil; +import com.bwssystems.HABridge.hue.TimeDecode; +import com.bwssystems.HABridge.plugins.http.HTTPHandler; +import com.bwssystems.HABridge.plugins.http.HTTPHome; +import com.google.gson.Gson; + +public class HomeGenieHome implements Home { + private static final Logger log = LoggerFactory.getLogger(HomeGenieHome.class); + private Map homegenieMap; + private Boolean validHomeGenie; + private HTTPHandler httpClient; + private boolean closed; + + public HomeGenieHome(BridgeSettings bridgeSettings) { + super(); + closed = true; + createHome(bridgeSettings); + closed = false; + } + + @Override + public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, + Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) { + + String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); + String responseString = null; + + if (theUrl != null && !theUrl.isEmpty()) { + String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrl, intensity, targetBri, targetBriInc, + false); + if (colorData != null) { + anUrl = ColorDecode.replaceColorData(anUrl, colorData, + BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true); + } + anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device); + anUrl = TimeDecode.replaceTimeValue(anUrl); + + anUrl = BrightnessDecode.calculateReplaceIntensityValue(anUrl, intensity, targetBri, targetBriInc, false); + if (colorData != null) { + anUrl = ColorDecode.replaceColorData(anUrl, colorData, + BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false); + } + anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device); + anUrl = TimeDecode.replaceTimeValue(anUrl); + + HomeGenieCommand theCommand = null; + try { + theCommand = new Gson().fromJson(anUrl, HomeGenieCommand.class); + } catch (Exception e) { + log.warn("Cannot parse command to HomeGenie <<<" + theUrl + ">>>", e); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, null) + .getTheErrors(), HueError[].class); + return responseString; + } + + HomeGenieInstance theHandler = homegenieMap.get(device.getTargetDevice()); + if (theHandler != null) { + try { + boolean success = theHandler.callCommand(theCommand.getDeviceId(), theCommand.getModuleType(), theCommand.getCommand(), httpClient); + if (!success) { + log.warn("Comand had error to HomeGenie"); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, + null).getTheErrors(), HueError[].class); + } + } catch (Exception e) { + log.warn("Cannot send comand to HomeGenie", e); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, null) + .getTheErrors(), HueError[].class); + } + } else { + log.warn("HomeGenie Call could not complete, no address found: " + theUrl); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, null) + .getTheErrors(), HueError[].class); + } + } else { + log.warn( + "HomeGenie Call to be presented as http(s)://(:)/payload, format of request unknown: " + + theUrl); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + lightId + "/state", null, null) + .getTheErrors(), HueError[].class); + } + return responseString; + } + + @Override + public Object getItems(String type) { + + if (!validHomeGenie) + return null; + log.debug("consolidating devices for HomeGenie"); + List theResponse = null; + Iterator keys = homegenieMap.keySet().iterator(); + List deviceList = new ArrayList(); + while (keys.hasNext()) { + String key = keys.next(); + theResponse = homegenieMap.get(key).getDevices(httpClient); + if (theResponse != null) + addHomeGenieDevices(deviceList, theResponse, key); + else { + log.warn("Cannot get devices for HomeGenie with name: " + key + ", skipping this HomeGenie."); + continue; + } + } + return deviceList; + } + + private Boolean addHomeGenieDevices(List theDeviceList, List theSourceList, + String theKey) { + Iterator hgModules = theSourceList.iterator(); + while (hgModules.hasNext()) { + Module aModule = hgModules.next(); + HomeGenieDevice theDevice = new HomeGenieDevice(); + theDevice.setDeviceDetail(aModule); + theDevice.setGatewayName(theKey); + theDeviceList.add(theDevice); + } + return true; + } + + @Override + public Home createHome(BridgeSettings bridgeSettings) { + homegenieMap = null; + validHomeGenie = bridgeSettings.getBridgeSettingsDescriptor().isValidHomeGenie(); + log.info("HomeGenie Home created." + (validHomeGenie ? "" : " No HomeGenies configured.")); + if (validHomeGenie) { + homegenieMap = new HashMap(); + httpClient = HTTPHome.getHandler(); + Iterator theList = bridgeSettings.getBridgeSettingsDescriptor().getHomegenieaddress().getDevices() + .iterator(); + while (theList.hasNext() && validHomeGenie) { + NamedIP aHomeGenie = theList.next(); + try { + homegenieMap.put(aHomeGenie.getName(), new HomeGenieInstance(aHomeGenie, httpClient)); + } catch (Exception e) { + log.error("Cannot get HomeGenie (" + aHomeGenie.getName() + ") setup, Exiting with message: " + + e.getMessage(), e); + validHomeGenie = false; + } + } + } + return this; + } + + @Override + public void closeHome() { + log.debug("Closing Home."); + if (!closed && validHomeGenie) { + log.debug("Home is already closed...."); + return; + } + + if (httpClient != null) + httpClient.closeHandler(); + + homegenieMap = null; + closed = true; + } + + @Override + public void refresh() { + // noop + } +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieInstance.java b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieInstance.java new file mode 100644 index 0000000..b1ab499 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieInstance.java @@ -0,0 +1,144 @@ +package com.bwssystems.HABridge.plugins.homegenie; + +import java.util.ArrayList; +import java.util.List; + +import com.bwssystems.HABridge.NamedIP; +import com.bwssystems.HABridge.api.NameValue; +import com.bwssystems.HABridge.plugins.http.HTTPHandler; +import com.google.gson.Gson; + +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpPost; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class HomeGenieInstance { + private static final Logger log = LoggerFactory.getLogger(HomeGenieInstance.class); + private NamedIP homegenieIP; + private NameValue[] headers; + + public HomeGenieInstance(NamedIP theNamedIp, HTTPHandler httpClient) { + homegenieIP = theNamedIp; + headers = null; + // gatewayLogin(httpClient); + } + + public Boolean callCommand(String deviceId, String moduleType, HomeGenieCommandDetail commandData, HTTPHandler httpClient) { + log.debug("calling HomeGenie: {}:{}{}{}", homegenieIP.getIp(), homegenieIP.getPort(), moduleType, commandData.getCommand()); + String aUrl = null; + + headers = getAuthHeader(); + + aUrl = homegenieIP.getHttpPreamble() + "/api/" + moduleType + "/" + deviceId + "/" + commandData.getCommand(); + + String theLevel = commandData.getLevel(); + if(commandData.getCommand().contains("Level")) { + if(theLevel != null && theLevel.length() > 0) + aUrl = aUrl + "/" + theLevel; + else + aUrl = aUrl + "100"; + } + + String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", null, headers); + log.debug("call Command return is: <<<{}>>>", theData); + if (!theData.contains("OK")) + return false; + return true; + } + + public List getDevices(HTTPHandler httpClient) { + log.debug("calling HomeGenie: " + homegenieIP.getIp() + ":" + homegenieIP.getPort()); + List deviceList = null; + Module[] hgModules; + String theUrl = null; + String theData; + + headers = getAuthHeader(); + + theUrl = theUrl + homegenieIP.getHttpPreamble() + "/api/HomeAutomation.HomeGenie/Config/Modules.List"; + + theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers); + if (theData != null) { + log.debug("GET HomeGenie Devices - data: " + theData); + try { + hgModules = new Gson().fromJson(theData, Module[].class); + if (hgModules != null && hgModules.length > 0) { + deviceList = new ArrayList(); + for (int i = 0; i < hgModules.length; i++) { + if(hgModules[i].isSwitch() || hgModules[i].isDimmer()) + deviceList.add(hgModules[i]); + } + } + } catch (Exception e) { + log.warn("Cannot get an devices for Homegenie {} Gson Parse Error.", homegenieIP.getName()); + } + } + return deviceList; + } + + private NameValue[] getAuthHeader() { + /* if (headers == null) { + headers = new NameValue[3]; + headers[0] = new NameValue(); + headers[0].setName("Authorization"); + headers[0].setValue("Bearer " + moziotToken.getJwt()); + headers[1] = new NameValue(); + headers[1].setName("Content-Type"); + headers[1].setValue("application/json"); + headers[2] = new NameValue(); + headers[2].setName("Accept"); + headers[2].setValue("application/json"); + } +*/ + return headers; + } + + private void gatewayLogin(HTTPHandler httpClient) { +/* String aUrl = null; + + if (homegenieIP.getSecure() != null && homegenieIP.getSecure()) + aUrl = "https://"; + else + aUrl = "http://"; + + headers = new NameValue[2]; + headers[0] = new NameValue(); + headers[0].setName("Content-Type"); + headers[0].setValue("application/json"); + headers[1] = new NameValue(); + headers[1].setName("Accept"); + headers[1].setValue("application/json"); + aUrl = aUrl + homegenieIP.getIp() + ":" + homegenieIP.getPort() + "/login"; + log.debug("gateway login URL: {}", aUrl); + String commandData = "{\"email\": \"" + homegenieIP.getUsername() + "\", \"password\":\"" + homegenieIP.getPassword() + + "\"}"; + log.debug("The login body: {}", commandData); + String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, headers); + if (theData != null) { + log.debug("GET Mozilla login - data: {}", theData); + try { + moziotToken = new Gson().fromJson(theData, JWT.class); + } catch (Exception e) { + log.warn("Cannot get login for HomeGenie {} Gson Parse Error.", homegenieIP.getName()); + } + } else { + log.warn("Could not login {} error: <<<{}>>>", homegenieIP.getName(), theData); + } + + headers = null; +*/ + } + + public NamedIP getHomegenieIP() { + return homegenieIP; + } + + public void setHomegenieIP(NamedIP homegenieIP) { + this.homegenieIP = homegenieIP; + } + + protected void closeClient() { + } +} \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Module.java b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Module.java new file mode 100644 index 0000000..77f9b5c --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Module.java @@ -0,0 +1,99 @@ + +package com.bwssystems.HABridge.plugins.homegenie; + +import java.util.List; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Module { + + @SerializedName("Name") + @Expose + private String name; + @SerializedName("Description") + @Expose + private String description; + @SerializedName("DeviceType") + @Expose + private String deviceType; + @SerializedName("Domain") + @Expose + private String domain; + @SerializedName("Address") + @Expose + private String address; + @SerializedName("Properties") + @Expose + private List properties = null; + @SerializedName("RoutingNode") + @Expose + private String routingNode; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDomain() { + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public String getRoutingNode() { + return routingNode; + } + + public void setRoutingNode(String routingNode) { + this.routingNode = routingNode; + } + + public boolean isSwitch() { + return isPropertyType("Switch"); + } + + public boolean isDimmer() { + return isPropertyType("Dimmer"); + } + + private boolean isPropertyType(String theType) { + return false; + } +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Property.java b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Property.java new file mode 100644 index 0000000..38f00a3 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Property.java @@ -0,0 +1,76 @@ + +package com.bwssystems.HABridge.plugins.homegenie; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Property { + + @SerializedName("Name") + @Expose + private String name; + @SerializedName("Value") + @Expose + private String value; + @SerializedName("Description") + @Expose + private String description; + @SerializedName("FieldType") + @Expose + private String fieldType; + @SerializedName("UpdateTime") + @Expose + private String updateTime; + @SerializedName("NeedsUpdate") + @Expose + private Boolean needsUpdate; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getFieldType() { + return fieldType; + } + + public void setFieldType(String fieldType) { + this.fieldType = fieldType; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + public Boolean getNeedsUpdate() { + return needsUpdate; + } + + public void setNeedsUpdate(Boolean needsUpdate) { + this.needsUpdate = needsUpdate; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizardHome.java b/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizardHome.java index d13b9a8..b7c5210 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizardHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizardHome.java @@ -54,8 +54,8 @@ public class HomeWizardHome implements Home { if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.HOMEWIZARD_DEVICE[DeviceMapTypes.typeIndex])) { - log.debug("Executing HUE api request to change activity to HomeWizard smart plug: " + anItem.getItem().toString()); - String jsonToPost = anItem.getItem().toString(); + String jsonToPost = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); + log.debug("Executing HUE api request to change activity to HomeWizard smart plug: {}", jsonToPost); HomeWizzardSmartPlugInfo homeWizzardHandler = getHomeWizzardHandler(device.getTargetDevice()); if(homeWizzardHandler == null) { diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java index 0a70ee1..915b4d0 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java @@ -44,7 +44,7 @@ public class HTTPHome implements Home { Integer targetBri,Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) { String responseString = null; - String theUrl = anItem.getItem().getAsString(); + String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); if(theUrl != null && !theUrl.isEmpty () && (theUrl.startsWith("http://") || theUrl.startsWith("https://"))) { //Backwards Compatibility Items if(anItem.getHttpVerb() == null || anItem.getHttpVerb().isEmpty()) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hue/HueHome.java b/src/main/java/com/bwssystems/HABridge/plugins/hue/HueHome.java index 8a57eff..017a868 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hue/HueHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hue/HueHome.java @@ -99,7 +99,7 @@ public class HueHome implements Home { if(anItem.getItem().isJsonObject()) deviceId = aGsonHandler.fromJson(anItem.getItem(), HueDeviceIdentifier.class); else - deviceId = aGsonHandler.fromJson(anItem.getItem().getAsString(), HueDeviceIdentifier.class); + deviceId = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), HueDeviceIdentifier.class); if(deviceId.getHueName() == null || deviceId.getHueName().isEmpty()) deviceId.setHueName(device.getTargetDevice()); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java index 77dd83f..cd687fa 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java @@ -151,7 +151,7 @@ public class LifxHome implements Home { if(anItem.getItem().isJsonObject()) lifxCommand = aGsonHandler.fromJson(anItem.getItem(), LifxEntry.class); else - lifxCommand = aGsonHandler.fromJson(anItem.getItem().getAsString(), LifxEntry.class); + lifxCommand = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), LifxEntry.class); LifxDevice theDevice = getLifxDevice(lifxCommand.getName()); if (theDevice == null) { log.warn("Should not get here, no LifxDevices available"); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java index 082e8a0..be22094 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/moziot/MozIotHome.java @@ -44,7 +44,7 @@ public class MozIotHome implements Home { public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) { - String theUrl = anItem.getItem().getAsString(); + String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); String responseString = null; if (theUrl != null && !theUrl.isEmpty()) { diff --git a/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java b/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java index 46fba41..b4003c3 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java @@ -96,7 +96,7 @@ public class MQTTHome implements Home { mqttObject = aGsonHandler.toJson(anItem.getItem()); } else - mqttObject =anItem.getItem().getAsString(); + mqttObject = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); mqttObject = BrightnessDecode.calculateReplaceIntensityValue(mqttObject, intensity, targetBri, targetBriInc, false); mqttObject = DeviceDataDecode.replaceDeviceData(mqttObject, device); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABHome.java b/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABHome.java index be645f3..b588f6b 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABHome.java @@ -54,7 +54,7 @@ public class OpenHABHome implements Home { if(anItem.getItem().isJsonObject()) theCommand = new Gson().fromJson(anItem.getItem(), OpenHABCommand.class); else - theCommand = new Gson().fromJson(anItem.getItem().getAsString(), OpenHABCommand.class); + theCommand = new Gson().fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), OpenHABCommand.class); } catch(Exception e) { log.warn("Cannot parse command to OpenHAB <<<" + theUrl + ">>>", e); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java index 1ca4130..d786cef 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java @@ -76,8 +76,8 @@ public class SomfyHome implements Home { } else { if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex])) { - log.debug("executing HUE api request to change activity to Somfy: " + anItem.getItem().toString()); - String jsonToPost = anItem.getItem().toString(); + String jsonToPost = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); + log.debug("executing HUE api request to change activity to Somfy: {}", jsonToPost); SomfyInfo somfyHandler = getSomfyHandler(device.getTargetDevice()); if(somfyHandler == null) { @@ -103,7 +103,7 @@ public class SomfyHome implements Home { @Override public Home createHome(BridgeSettings bridgeSettings) { validSomfy = bridgeSettings.getBridgeSettingsDescriptor().isValidSomfy(); - log.info("Somfy Home created." + (validSomfy ? "" : " No Somfys configured.")); + log.info("Somfy Home created. {}", (validSomfy ? "" : " No Somfys configured.")); if(validSomfy) { somfys = new HashMap<>(); Iterator theList = bridgeSettings.getBridgeSettingsDescriptor().getSomfyAddress().getDevices().iterator(); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyInfo.java b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyInfo.java index be1d862..a2db134 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyInfo.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyInfo.java @@ -74,8 +74,8 @@ public class SomfyInfo { ByteArrayOutputStream bos = new ByteArrayOutputStream(); urlEncodedFormEntity.writeTo(bos); String body = bos.toString(); - String response = httpClient.doHttpRequest(BASE_URL + "json/login",HttpPost.METHOD_NAME, "application/x-www-form-urlencoded", body,httpHeader); - log.debug("Somfy login response <<<" + response + ">>>"); + String response = httpClient.doHttpRequest(BASE_URL + "json/login", HttpPost.METHOD_NAME, "application/x-www-form-urlencoded", body,httpHeader); + log.debug("Somfy login response <<<{}>>>", response); } private NameValue[] getHttpHeaders() { @@ -89,16 +89,16 @@ public class SomfyInfo { NameValue[] httpHeader = getHttpHeaders(); log.info("Making SOMFY http setup call"); String response = httpClient.doHttpRequest(BASE_URL + "json/getSetup", HttpGet.METHOD_NAME, "", "", httpHeader ); - log.debug("Somfy getSetup response <<<" + response + ">>>"); + log.debug("Somfy getSetup response <<<{}>>>", response); GetSetup setupData = new Gson().fromJson(response, GetSetup.class); return setupData; } public void execApply(String jsonToPost) throws Exception { login(namedIP.getUsername(), namedIP.getPassword()); - log.info("Making SOMFY http exec call"); + log.info("Making SOMFY http exec call with json: {}", jsonToPost); String response = httpClient.doHttpRequest(BASE_URL_ENDUSER + "exec/apply", HttpPost.METHOD_NAME, "application/json;charset=UTF-8", jsonToPost, getHttpHeaders()); - log.debug("Somfy exec reply response <<<" + response + ">>>"); + log.debug("Somfy exec reply response <<<{}>>>", response); } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java index 21db858..d0e2f04 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java @@ -48,7 +48,7 @@ public class TCPHome implements Home { Integer targetBri,Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) { Socket dataSendSocket = null; log.debug("executing HUE api request to TCP: " + anItem.getItem().getAsString()); - String theUrl = anItem.getItem().getAsString(); + String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); if(theUrl != null && !theUrl.isEmpty () && theUrl.contains("tcp://")) { if(!theUrl.startsWith("{\"tcpDevice\"")) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java index 666521c..b59b8da 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java @@ -40,7 +40,7 @@ public class UDPHome implements Home { public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri,Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) { log.debug("executing HUE api request to UDP: " + anItem.getItem().getAsString()); - String theUrl = anItem.getItem().getAsString(); + String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", ""); if(theUrl != null && !theUrl.isEmpty () && theUrl.startsWith("udp://")) { String intermediate = theUrl.substring(theUrl.indexOf("://") + 3); String hostPortion = intermediate.substring(0, intermediate.indexOf('/')); diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index de16a17..725cf2a 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -5113,6 +5113,20 @@ app.filter('configuredBroadlinkItems', function (bridgeService) { }; }); +app.filter('configuredMozIotItems', function (bridgeService) { + return function (input) { + var out = []; + if (input === undefined || input === null || input.length === undefined) + return out; + for (var i = 0; i < input.length; i++) { + if (bridgeService.deviceContainsType(input[i], "moziot")) { + out.push(input[i]); + } + } + return out; + }; +}); + app.filter('filterDevicesByRequester', function () { return function (input, search, mustContain, deviceType) { var out = []; diff --git a/src/main/resources/public/views/homegeniedevice.html b/src/main/resources/public/views/homegeniedevice.html new file mode 100644 index 0000000..987c0a8 --- /dev/null +++ b/src/main/resources/public/views/homegeniedevice.html @@ -0,0 +1,140 @@ + + +
    +
    +

    HomeGenie show Device List + ({{bridge.homegeniedevices.length}})

    +
    +
    +

    For any HomeGenie Device, use the build action buttons + to generate the item addition information into the ha-bridge device and this will put you into the edit + screen. Then + you can modify the name to anything you want that will be the keyword + for the Echo or Google Home. Also, you can go back to any helper tab and click a build + action button to add another item for a multi-command. After you are + done in the edit tab, click the 'Add Bridge Device' to finish that selection + setup. The 'Already Configured HomeGenie Devices' list below will show what + is already setup for your HomeGenie.

    +

    + Also, use this select menu for which type of dim control you would + like to be generated: +

    +

    Use the check boxes by the names to use the bulk addition + feature. Select your items and dim control type if wanted, then click + bulk add below. Your items will be added with on and off or dim and + off if selected with the name of the device from the HomeGenie.

    + + + + + + + + + + + + + + + + + + +
    Row + NameTypeHomeGenieBuild Actions
    {{$index+1}} + {{homegeniedevice.deviceDetail.Name}}{{homegeniedevice.deviceDetail.DeviceType}}{{homegeniedevice.gatewayName}} + +
    +
    + +
    +
    +
    +
    +

    + Already Configured OpenHAB Devices +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    RowNameCategoryHomeGenieMap IdActions
    {{$index+1}}{{device.name}}{{device.deviceType}}{{device.targetDevice}}{{device.mapId}} +

    + + +

    +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/main/resources/public/views/system.html b/src/main/resources/public/views/system.html index fd4d5f7..5a3b5ec 100644 --- a/src/main/resources/public/views/system.html +++ b/src/main/resources/public/views/system.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • @@ -763,7 +764,7 @@ placeholder="192.168.1.3"> + placeholder="4443"> @@ -785,7 +786,7 @@ placeholder="192.168.1.3"> + placeholder="4443"> @@ -800,6 +801,67 @@ + + HomeGenie Names and IP Addresses + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameIPPort (opt)Username (opt)Password (opt)Use SSLManage
    + Nest @@ -884,6 +946,12 @@ ng-model="bridge.settings.upnpsenddelay" min="100" max="15000"> + + + + + @@ -74,11 +76,12 @@ ng-checked="bulk.devices.indexOf(homegeniedevice.deviceDetail.Name) > -1" ng-click="toggleSelection(homegeniedevice.deviceDetail.Name)"> {{homegeniedevice.deviceDetail.Name}} - + + @@ -111,7 +114,7 @@ - + diff --git a/src/main/resources/public/views/homewizarddevice.html b/src/main/resources/public/views/homewizarddevice.html index 45df646..9a920d0 100644 --- a/src/main/resources/public/views/homewizarddevice.html +++ b/src/main/resources/public/views/homewizarddevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/huedevice.html b/src/main/resources/public/views/huedevice.html index f1fadd3..ba74681 100644 --- a/src/main/resources/public/views/huedevice.html +++ b/src/main/resources/public/views/huedevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/lifxdevice.html b/src/main/resources/public/views/lifxdevice.html index c3462cf..f2e9d8c 100644 --- a/src/main/resources/public/views/lifxdevice.html +++ b/src/main/resources/public/views/lifxdevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/logs.html b/src/main/resources/public/views/logs.html index 8d043ba..3480abe 100644 --- a/src/main/resources/public/views/logs.html +++ b/src/main/resources/public/views/logs.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/moziotdevice.html b/src/main/resources/public/views/moziotdevice.html index 99acf20..b55d104 100644 --- a/src/main/resources/public/views/moziotdevice.html +++ b/src/main/resources/public/views/moziotdevice.html @@ -19,6 +19,7 @@
  • HomeWizard Devices
  • OpenHAB Devices
  • FHEM Devices
  • +
  • HomeGenie Devices
  • Broadlink Devices
  • diff --git a/src/main/resources/public/views/mqttpublish.html b/src/main/resources/public/views/mqttpublish.html index 4bcdac8..6722548 100644 --- a/src/main/resources/public/views/mqttpublish.html +++ b/src/main/resources/public/views/mqttpublish.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/nestactions.html b/src/main/resources/public/views/nestactions.html index 7ce237b..bdede0c 100644 --- a/src/main/resources/public/views/nestactions.html +++ b/src/main/resources/public/views/nestactions.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/openhabdevice.html b/src/main/resources/public/views/openhabdevice.html index 4f3081a..00a6704 100644 --- a/src/main/resources/public/views/openhabdevice.html +++ b/src/main/resources/public/views/openhabdevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/somfydevice.html b/src/main/resources/public/views/somfydevice.html index a0d99a9..ee2ca4f 100644 --- a/src/main/resources/public/views/somfydevice.html +++ b/src/main/resources/public/views/somfydevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/veradevice.html b/src/main/resources/public/views/veradevice.html index ca137b1..5c5a0fc 100644 --- a/src/main/resources/public/views/veradevice.html +++ b/src/main/resources/public/views/veradevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/verascene.html b/src/main/resources/public/views/verascene.html index 37695ae..5531343 100644 --- a/src/main/resources/public/views/verascene.html +++ b/src/main/resources/public/views/verascene.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • From e86b700e939804fb80020e45f0b736cd7225433a Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Mon, 10 Jun 2019 16:35:10 -0500 Subject: [PATCH 26/52] Add lock id to device, adding download of backups --- pom.xml | 2 +- .../HABridge/dao/DeviceDescriptor.java | 13 +- .../HABridge/dao/DeviceRepository.java | 25 +-- .../devicemanagmeent/DeviceResource.java | 16 ++ .../HABridge/util/BackupHandler.java | 17 ++ src/main/resources/public/scripts/app.js | 20 ++ .../resources/public/views/configuration.html | 177 +++++++++--------- .../resources/public/views/editdevice.html | 6 + 8 files changed, 174 insertions(+), 102 deletions(-) diff --git a/pom.xml b/pom.xml index bcbaba2..b765b40 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 5.2.next_c + 5.2.next_d jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java index cef95c6..63dff65 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java @@ -86,7 +86,10 @@ public class DeviceDescriptor{ @SerializedName("onWhenDimPresent") @Expose private boolean onWhenDimPresent; - + @SerializedName("lockDeviceId") + @Expose + private boolean lockDeviceId; + public String getName() { return name; } @@ -333,4 +336,12 @@ public class DeviceDescriptor{ } return color; } + + public boolean isLockDeviceId() { + return lockDeviceId; + } + + public void setLockDeviceId(boolean lockDeviceId) { + this.lockDeviceId = lockDeviceId; + } } \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java index 9755138..4442ade 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java @@ -143,7 +143,8 @@ public class DeviceRepository extends BackupHandler { if (light.getOnUrl() != null) callItems = aGsonBuilder.fromJson(light.getOnUrl(), CallItem[].class); } catch (JsonSyntaxException e) { - log.warn("Could not decode Json for url items to get Hue state for device: {}", light.getName()); + log.warn("Could not decode Json for url items to get Hue state for device: {}", + light.getName()); callItems = null; } @@ -201,7 +202,7 @@ public class DeviceRepository extends BackupHandler { List list = new ArrayList(devices.values()); Iterator deviceIterator = list.iterator(); Map newdevices = new HashMap(); - ; + nextId = seedId; String hexValue; Integer newValue; @@ -209,17 +210,19 @@ public class DeviceRepository extends BackupHandler { log.debug("Renumber devices with seed: {}", seedId); while (deviceIterator.hasNext()) { theDevice = deviceIterator.next(); - theDevice.setId(String.valueOf(nextId)); - newValue = nextId % 256; - if (newValue <= 0) - newValue = 1; - else if (newValue > 255) - newValue = 255; - hexValue = HexLibrary.encodeUsingBigIntegerToString(newValue.toString()); + if (!theDevice.isLockDeviceId()) { + theDevice.setId(String.valueOf(nextId)); + newValue = nextId % 256; + if (newValue <= 0) + newValue = 1; + else if (newValue > 255) + newValue = 255; + hexValue = HexLibrary.encodeUsingBigIntegerToString(newValue.toString()); - theDevice.setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); + theDevice.setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue); + nextId++; + } newdevices.put(theDevice.getId(), theDevice); - nextId++; } devices = newdevices; String jsonValue = gson.toJson(findAll()); diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index 692925b..169312b 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -385,6 +385,22 @@ public class DeviceResource { return deviceRepository.getBackups(); }, new JsonTransformer()); + // http://ip_address:port/api/devices/backup/download CORS request + options(API_CONTEXT + "/backup/download", "application/json", (request, response) -> { + response.status(HttpStatus.SC_OK); + response.header("Access-Control-Allow-Origin", request.headers("Origin")); + response.header("Access-Control-Allow-Methods", "PUT"); + response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers")); + response.header("Content-Type", "text/html; charset=utf-8"); + return ""; + }); + put (API_CONTEXT + "/backup/download", "application/json", (request, response) -> { + log.debug("Create download: {}", request.body()); + BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class); + String backupContent = deviceRepository.downloadBackup(aFilename.getFilename()); + return backupContent; + }, new JsonTransformer()); + // http://ip_address:port/api/devices/backup/create CORS request options(API_CONTEXT + "/backup/create", "application/json", (request, response) -> { response.status(HttpStatus.SC_OK); diff --git a/src/main/java/com/bwssystems/HABridge/util/BackupHandler.java b/src/main/java/com/bwssystems/HABridge/util/BackupHandler.java index 6d9b33c..f2d3f68 100644 --- a/src/main/java/com/bwssystems/HABridge/util/BackupHandler.java +++ b/src/main/java/com/bwssystems/HABridge/util/BackupHandler.java @@ -92,4 +92,21 @@ public abstract class BackupHandler { return theFilenames; } + public String downloadBackup(String aFilename) { + Path filePath = FileSystems.getDefault().getPath(repositoryPath.getParent().toString(), aFilename); + + String content = null; + if (Files.notExists(filePath) || !Files.isReadable(filePath)) { + log.warn("Error reading the file: {} - Does not exist or is not readable. continuing...", aFilename); + return null; + } + + try { + content = new String(Files.readAllBytes(filePath)); + } catch (IOException e) { + log.error("Error reading the file: {} message: {}", aFilename, e.getMessage(), e); + } + + return content; + } } diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 0a70136..ce9e01a 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -1279,6 +1279,22 @@ app.service('bridgeService', function ($rootScope, $http, $base64, $location, ng ); }; + this.downloadBackup = function (afilename) { + return $http.put(this.state.base + "/backup/download", { + filename: afilename + }).then( + function (response) { + self.state.backupContent = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Download Backup Db File Error:", error); + } + ); + }; + this.checkForBridge = function () { return $http.get(this.state.bridgelocation + "/description.xml").then( function (response) { @@ -2256,6 +2272,7 @@ app.controller('ViewingController', function ($scope, $location, bridgeService, bridgeService.viewBackups(); $scope.bridge = bridgeService.state; $scope.optionalbackupname = ""; + $scope.bridge.backupContent = undefined; $scope.visible = false; $scope.imgUrl = "glyphicon glyphicon-plus"; $scope.visibleBk = false; @@ -2320,6 +2337,9 @@ app.controller('ViewingController', function ($scope, $location, bridgeService, $scope.deleteBackup = function (backupname) { bridgeService.deleteBackup(backupname); }; + $scope.downloadBackup = function (backupname) { + bridgeService.downloadBackup(backupname); + }; $scope.toggle = function () { $scope.visible = !$scope.visible; if ($scope.visible) diff --git a/src/main/resources/public/views/configuration.html b/src/main/resources/public/views/configuration.html index d3c6f3d..4fe5520 100644 --- a/src/main/resources/public/views/configuration.html +++ b/src/main/resources/public/views/configuration.html @@ -1,4 +1,3 @@ - -
    -
    -
    -

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

    -
    -
    +
    +
    +
    +

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

    +
    +
    - + - Must contain filter + ng-model="bridge.state.filterDevicesByIpAddress" placeholder=""> + Must contain filter - +
    - - -
    ID Seed (start numbering from this value)
    My Echo URL Date: Wed, 5 Jun 2019 16:08:11 -0500 Subject: [PATCH 25/52] Completed HomeGenie implementation --- .gitignore | 4 + .../bwssystems/HABridge/BridgeSettings.java | 1 + .../java/com/bwssystems/HABridge/NamedIP.java | 19 +- .../plugins/domoticz/DomoticzHandler.java | 29 +-- .../plugins/domoticz/DomoticzHome.java | 2 +- .../HABridge/plugins/fhem/FHEMInstance.java | 11 +- .../HABridge/plugins/fibaro/FibaroInfo.java | 3 +- .../HABridge/plugins/hass/HomeAssistant.java | 6 +- .../plugins/homegenie/HomeGenieInstance.java | 83 +------ .../HABridge/plugins/homegenie/Module.java | 17 +- .../homewizard/HomeWizzardSmartPlugInfo.java | 4 +- .../HABridge/plugins/http/HTTPHandler.java | 30 +++ .../plugins/openhab/OpenHABInstance.java | 7 +- src/main/resources/public/scripts/app.js | 232 +++++++++++++++++- .../public/views/broadlinkdevice.html | 1 + .../resources/public/views/configuration.html | 1 + .../public/views/domoticzdevice.html | 1 + .../resources/public/views/editdevice.html | 1 + .../resources/public/views/fhemdevice.html | 1 + .../resources/public/views/fibarodevice.html | 1 + .../resources/public/views/fibaroscene.html | 1 + .../resources/public/views/haldevice.html | 1 + .../public/views/harmonyactivity.html | 1 + .../resources/public/views/harmonydevice.html | 1 + .../resources/public/views/hassdevice.html | 1 + .../public/views/homegeniedevice.html | 11 +- .../public/views/homewizarddevice.html | 1 + .../resources/public/views/huedevice.html | 1 + .../resources/public/views/lifxdevice.html | 1 + src/main/resources/public/views/logs.html | 1 + .../resources/public/views/moziotdevice.html | 1 + .../resources/public/views/mqttpublish.html | 1 + .../resources/public/views/nestactions.html | 1 + .../resources/public/views/openhabdevice.html | 1 + .../resources/public/views/somfydevice.html | 1 + .../resources/public/views/veradevice.html | 1 + .../resources/public/views/verascene.html | 1 + 37 files changed, 345 insertions(+), 136 deletions(-) diff --git a/.gitignore b/.gitignore index 8397bbb..c27a1e6 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,7 @@ sftp-config\.json .vscode/launch.test.json .vscode/settings.json .vscode/tasks.json +# dependencies +/node_modules + +package-lock.json \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index 076ddbb..e12dc45 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -216,6 +216,7 @@ public class BridgeSettings extends BackupHandler { theBridgeSettings.setOpenhabconfigured(theBridgeSettings.isValidOpenhab()); theBridgeSettings.setFhemconfigured(theBridgeSettings.isValidFhem()); theBridgeSettings.setMoziotconfigured(theBridgeSettings.isValidMozIot()); + theBridgeSettings.setHomegenieconfigured(theBridgeSettings.isValidHomeGenie()); // Lifx is either configured or not, so it does not need an update. if(serverPortOverride != null) theBridgeSettings.setServerPort(serverPortOverride); diff --git a/src/main/java/com/bwssystems/HABridge/NamedIP.java b/src/main/java/com/bwssystems/HABridge/NamedIP.java index a5f8c89..6d3713e 100644 --- a/src/main/java/com/bwssystems/HABridge/NamedIP.java +++ b/src/main/java/com/bwssystems/HABridge/NamedIP.java @@ -2,6 +2,8 @@ package com.bwssystems.HABridge; import com.google.gson.JsonObject; +import org.apache.commons.codec.binary.Base64; + public class NamedIP { private String name; private String ip; @@ -12,6 +14,7 @@ public class NamedIP { private JsonObject extensions; private Boolean secure; private String httpPreamble; + private String encodedLogin; public String getName() { return name; @@ -78,14 +81,14 @@ public class NamedIP { } public String getHttpPreamble() { - if (httpPreamble == null || httpPreamble.length() == 0) { + if (httpPreamble == null || !httpPreamble.trim().isEmpty()) { if (getSecure() != null && getSecure()) httpPreamble = "https://"; else httpPreamble = "http://"; httpPreamble = httpPreamble + getIp(); - if (getPort() != null && getPort().length() > 0) { + if (getPort() != null && !getPort().trim().isEmpty()) { httpPreamble = httpPreamble + ":" + getPort(); } } @@ -95,4 +98,16 @@ public class NamedIP { public void setHttpPreamble(String httpPreamble) { this.httpPreamble = httpPreamble; } + + public String getUserPass64() { + if (encodedLogin == null || !encodedLogin.trim().isEmpty()) { + if (getUsername() != null && !getUsername().isEmpty() && getPassword() != null + && !getPassword().isEmpty()) { + String userPass = getUsername() + ":" + getPassword(); + encodedLogin = new String(Base64.encodeBase64(userPass.getBytes())); + } + } + + return encodedLogin; + } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java index 56ada5a..5ec77ca 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java @@ -3,12 +3,10 @@ package com.bwssystems.HABridge.plugins.domoticz; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bwssystems.HABridge.NamedIP; -import com.bwssystems.HABridge.api.NameValue; import com.bwssystems.HABridge.plugins.http.HTTPHandler; import com.google.gson.Gson; @@ -43,7 +41,7 @@ public class DomoticzHandler { theUrl = buildUrl(rootRequest + type + postpend); else theUrl = buildUrl(rootRequest + type); - theData = httpClient.doHttpRequest(theUrl, null, null, null, buildHeaders()); + theData = httpClient.doHttpRequest(theUrl, null, null, null, httpClient.addBasicAuthHeader(null, domoticzAddress)); if(theData != null) { log.debug("GET " + type + " DomoticzApiResponse - data: " + theData); theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class); @@ -76,15 +74,7 @@ public class DomoticzHandler { String newUrl = null; if(thePayload != null && !thePayload.isEmpty()) { - if(domoticzAddress.getSecure() != null && domoticzAddress.getSecure()) - newUrl = "https://"; - else - newUrl = "http://"; - - newUrl = newUrl + domoticzAddress.getIp(); - - if(domoticzAddress.getPort() != null && !domoticzAddress.getPort().isEmpty()) - newUrl = newUrl + ":" + domoticzAddress.getPort(); + newUrl = domoticzAddress.getHttpPreamble(); if(thePayload.startsWith("/")) newUrl = newUrl + thePayload; @@ -95,21 +85,6 @@ public class DomoticzHandler { return newUrl; } - public NameValue[] buildHeaders() { - NameValue[] headers = null; - - if(domoticzAddress.getUsername() != null && !domoticzAddress.getUsername().isEmpty() - && domoticzAddress.getPassword() != null && !domoticzAddress.getPassword().isEmpty()) { - NameValue theAuth = new NameValue(); - theAuth.setName("Authorization"); - String encoding = Base64.getEncoder().encodeToString((domoticzAddress.getUsername() + ":" + domoticzAddress.getPassword()).getBytes()); - theAuth.setValue("Basic " + encoding); - headers = new NameValue[1]; - headers[0] = theAuth; - } - - return headers; - } public NamedIP getDomoticzAddress() { return domoticzAddress; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java index a4b7f41..5e9cd64 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java @@ -119,7 +119,7 @@ public class DomoticzHome implements Home { aBody = DeviceDataDecode.replaceDeviceData(aBody, device); aBody = TimeDecode.replaceTimeValue(aBody); } - theData = httpClient.doHttpRequest(theHandler.buildUrl(anUrl), null, null, aBody, theHandler.buildHeaders()); + theData = httpClient.doHttpRequest(theHandler.buildUrl(anUrl), null, null, aBody, httpClient.addBasicAuthHeader(null, theHandler.getDomoticzAddress())); try { theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class); if(theDomoticzApiResponse.getStatus().equals("OK")) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMInstance.java b/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMInstance.java index 9c5edda..8e84dbf 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMInstance.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMInstance.java @@ -33,6 +33,7 @@ public class FHEMInstance { public Boolean callCommand(String aCommand, String commandData, HTTPHandler httpClient) { String aUrl = null; NameValue[] headers = null; + /* Trying new code helpers if(theFhem.getSecure() != null && theFhem.getSecure()) aUrl = "https://"; else @@ -41,6 +42,10 @@ public class FHEMInstance { aUrl = aUrl + theFhem.getUsername() + ":" + theFhem.getPassword() + "@"; } aUrl = aUrl + theFhem.getIp() + ":" + theFhem.getPort() + "/" + aCommand + commandData; + */ + // New style http creation + aUrl = theFhem.getHttpPreamble() + "/" + aCommand + commandData; + headers = httpClient.addBasicAuthHeader(null, theFhem); log.debug("calling FHEM: " + aUrl); String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "text/plain", null, headers); if(theData != null) @@ -54,6 +59,7 @@ public class FHEMInstance { String theUrl = null; String theData; NameValue[] headers = null; + /* Trying new code helpers if(theFhem.getSecure() != null && theFhem.getSecure()) theUrl = "https://"; else @@ -61,7 +67,10 @@ public class FHEMInstance { if(theFhem.getUsername() != null && !theFhem.getUsername().isEmpty() && theFhem.getPassword() != null && !theFhem.getPassword().isEmpty()) { theUrl = theUrl + theFhem.getUsername() + ":" + theFhem.getPassword() + "@"; } - theUrl = theUrl + theFhem.getIp() + ":" + theFhem.getPort() + "/fhem?cmd=jsonlist2"; + theUrl = theUrl + theFhem.getIp() + ":" + theFhem.getPort() + "/fhem?cmd=jsonlist2"; + */ + theUrl = theFhem.getHttpPreamble() + "/fhem?cmd=jsonlist2"; + headers = httpClient.addBasicAuthHeader(null, theFhem); if(theFhem.getWebhook() != null && !theFhem.getWebhook().trim().isEmpty()) theUrl = theUrl + "%20room=" + theFhem.getWebhook().trim(); theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/fibaro/FibaroInfo.java b/src/main/java/com/bwssystems/HABridge/plugins/fibaro/FibaroInfo.java index b3fa7c7..684813d 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/fibaro/FibaroInfo.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/fibaro/FibaroInfo.java @@ -6,7 +6,6 @@ import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; -import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +29,7 @@ public class FibaroInfo { super(); fibaroAddress = addressName; - fibaroAuth = "Basic " + new String(Base64.encodeBase64((addressName.getUsername() + ":" + addressName.getPassword()).getBytes())); + fibaroAuth = "Basic " + addressName.getUserPass64(); isDevMode = Boolean.parseBoolean(System.getProperty("dev.mode", "false")); gson = new Gson(); theFilters = null; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hass/HomeAssistant.java b/src/main/java/com/bwssystems/HABridge/plugins/hass/HomeAssistant.java index 3ee57b5..cc66f51 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hass/HomeAssistant.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hass/HomeAssistant.java @@ -38,12 +38,8 @@ public class HomeAssistant { log.debug("calling HomeAssistant: " + aCommand.getHassName() + " - " + aCommand.getEntityId() + " - " + aCommand.getState() + " - " + aCommand.getBri()); String aUrl = null; - if(hassAddress.getSecure() != null && hassAddress.getSecure()) - aUrl = "https"; - else - aUrl = "http"; String domain = aCommand.getEntityId().substring(0, aCommand.getEntityId().indexOf(".")); - aUrl = aUrl + "://" + hassAddress.getIp() + ":" + hassAddress.getPort() + "/api/services/"; + aUrl = hassAddress.getHttpPreamble() + "/api/services/"; if(domain.equals("group")) aUrl = aUrl + "homeassistant"; else diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieInstance.java b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieInstance.java index b1ab499..9040cb0 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieInstance.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/HomeGenieInstance.java @@ -4,44 +4,40 @@ import java.util.ArrayList; import java.util.List; import com.bwssystems.HABridge.NamedIP; -import com.bwssystems.HABridge.api.NameValue; import com.bwssystems.HABridge.plugins.http.HTTPHandler; import com.google.gson.Gson; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPut; -import org.apache.http.client.methods.HttpPost; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HomeGenieInstance { private static final Logger log = LoggerFactory.getLogger(HomeGenieInstance.class); private NamedIP homegenieIP; - private NameValue[] headers; public HomeGenieInstance(NamedIP theNamedIp, HTTPHandler httpClient) { homegenieIP = theNamedIp; - headers = null; - // gatewayLogin(httpClient); } - public Boolean callCommand(String deviceId, String moduleType, HomeGenieCommandDetail commandData, HTTPHandler httpClient) { - log.debug("calling HomeGenie: {}:{}{}{}", homegenieIP.getIp(), homegenieIP.getPort(), moduleType, commandData.getCommand()); + public Boolean callCommand(String deviceId, String moduleType, HomeGenieCommandDetail commandData, + HTTPHandler httpClient) { + log.debug("calling HomeGenie: {}:{}{}{}", homegenieIP.getIp(), homegenieIP.getPort(), moduleType, + commandData.getCommand()); String aUrl = null; - headers = getAuthHeader(); - - aUrl = homegenieIP.getHttpPreamble() + "/api/" + moduleType + "/" + deviceId + "/" + commandData.getCommand(); + aUrl = homegenieIP.getHttpPreamble() + "/api/" + moduleType + "/" + deviceId + "/" + commandData.getCommand(); String theLevel = commandData.getLevel(); - if(commandData.getCommand().contains("Level")) { - if(theLevel != null && theLevel.length() > 0) + if (commandData.getCommand().contains("Level")) { + if (theLevel != null && theLevel.length() > 0) aUrl = aUrl + "/" + theLevel; else aUrl = aUrl + "100"; } - String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", null, headers); + String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", null, httpClient.addBasicAuthHeader(null, homegenieIP)); log.debug("call Command return is: <<<{}>>>", theData); if (!theData.contains("OK")) return false; @@ -55,11 +51,9 @@ public class HomeGenieInstance { String theUrl = null; String theData; - headers = getAuthHeader(); + theUrl = homegenieIP.getHttpPreamble() + "/api/HomeAutomation.HomeGenie/Config/Modules.List"; - theUrl = theUrl + homegenieIP.getHttpPreamble() + "/api/HomeAutomation.HomeGenie/Config/Modules.List"; - - theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers); + theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, httpClient.addBasicAuthHeader(null, homegenieIP)); if (theData != null) { log.debug("GET HomeGenie Devices - data: " + theData); try { @@ -67,7 +61,7 @@ public class HomeGenieInstance { if (hgModules != null && hgModules.length > 0) { deviceList = new ArrayList(); for (int i = 0; i < hgModules.length; i++) { - if(hgModules[i].isSwitch() || hgModules[i].isDimmer()) + if (hgModules[i].isSwitch() || hgModules[i].isDimmer()) deviceList.add(hgModules[i]); } } @@ -78,59 +72,6 @@ public class HomeGenieInstance { return deviceList; } - private NameValue[] getAuthHeader() { - /* if (headers == null) { - headers = new NameValue[3]; - headers[0] = new NameValue(); - headers[0].setName("Authorization"); - headers[0].setValue("Bearer " + moziotToken.getJwt()); - headers[1] = new NameValue(); - headers[1].setName("Content-Type"); - headers[1].setValue("application/json"); - headers[2] = new NameValue(); - headers[2].setName("Accept"); - headers[2].setValue("application/json"); - } -*/ - return headers; - } - - private void gatewayLogin(HTTPHandler httpClient) { -/* String aUrl = null; - - if (homegenieIP.getSecure() != null && homegenieIP.getSecure()) - aUrl = "https://"; - else - aUrl = "http://"; - - headers = new NameValue[2]; - headers[0] = new NameValue(); - headers[0].setName("Content-Type"); - headers[0].setValue("application/json"); - headers[1] = new NameValue(); - headers[1].setName("Accept"); - headers[1].setValue("application/json"); - aUrl = aUrl + homegenieIP.getIp() + ":" + homegenieIP.getPort() + "/login"; - log.debug("gateway login URL: {}", aUrl); - String commandData = "{\"email\": \"" + homegenieIP.getUsername() + "\", \"password\":\"" + homegenieIP.getPassword() - + "\"}"; - log.debug("The login body: {}", commandData); - String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, headers); - if (theData != null) { - log.debug("GET Mozilla login - data: {}", theData); - try { - moziotToken = new Gson().fromJson(theData, JWT.class); - } catch (Exception e) { - log.warn("Cannot get login for HomeGenie {} Gson Parse Error.", homegenieIP.getName()); - } - } else { - log.warn("Could not login {} error: <<<{}>>>", homegenieIP.getName(), theData); - } - - headers = null; -*/ - } - public NamedIP getHomegenieIP() { return homegenieIP; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Module.java b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Module.java index 77f9b5c..87f7a77 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Module.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/homegenie/Module.java @@ -1,7 +1,7 @@ package com.bwssystems.HABridge.plugins.homegenie; -import java.util.List; +// import java.util.List; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; @@ -22,9 +22,11 @@ public class Module { @SerializedName("Address") @Expose private String address; + /* @SerializedName("Properties") @Expose private List properties = null; + */ @SerializedName("RoutingNode") @Expose private String routingNode; @@ -68,7 +70,7 @@ public class Module { public void setAddress(String address) { this.address = address; } - +/* public List getProperties() { return properties; } @@ -76,7 +78,7 @@ public class Module { public void setProperties(List properties) { this.properties = properties; } - +*/ public String getRoutingNode() { return routingNode; } @@ -86,14 +88,17 @@ public class Module { } public boolean isSwitch() { - return isPropertyType("Switch"); + return isDeviceType("Switch"); } public boolean isDimmer() { - return isPropertyType("Dimmer"); + return isDeviceType("Dimmer"); } - private boolean isPropertyType(String theType) { + private boolean isDeviceType(String theType) { + if(deviceType.equals(theType)) { + return true; + } return false; } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizzardSmartPlugInfo.java b/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizzardSmartPlugInfo.java index 9443f0d..0c42d3f 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizzardSmartPlugInfo.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/homewizard/HomeWizzardSmartPlugInfo.java @@ -9,8 +9,6 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +44,7 @@ public class HomeWizzardSmartPlugInfo { super(); - cloudAuth = "Basic " + new String(Base64.encodeBase64((gateway.getUsername() + ":" + DigestUtils.sha1Hex(gateway.getPassword())).getBytes())); + cloudAuth = "Basic " + gateway.getUserPass64(); cloudPlugName = name; gson = new Gson(); } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java index f52e26c..5a88755 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java @@ -18,6 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bwssystems.HABridge.DeviceMapTypes; +import com.bwssystems.HABridge.NamedIP; import com.bwssystems.HABridge.api.NameValue; public class HTTPHandler { @@ -168,6 +169,35 @@ public class HTTPHandler { return theContent; } + public NameValue[] addBasicAuthHeader(NameValue[] theHeaders, NamedIP theTarget) { + NameValue[] headers = null; + int index = 0; + String encodedLogin = theTarget.getUserPass64(); + if (encodedLogin != null && !encodedLogin.trim().isEmpty()) { + if (theHeaders != null && theHeaders.length > 0) { + headers = new NameValue[theHeaders.length + 1]; + for(int i = 0; i < theHeaders.length; i++) { + headers[i] = theHeaders[i]; + } + index = theHeaders.length; + } else { + headers = new NameValue[1]; + } + + log.debug("creating login for {} with username {} password len {}", theTarget.getName(), + theTarget.getUsername(), theTarget.getPassword().length()); + headers[index] = new NameValue(); + headers[index].setName("Authorization"); + // log.debug("Encoded login info {}", encodedLogin); + headers[index].setValue("Basic " + encodedLogin); + } else { + headers = theHeaders; + } + + return headers; + + } + public void setCallType(String callType) { this.callType = callType; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABInstance.java b/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABInstance.java index 4a6aa4e..84be153 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABInstance.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/openhab/OpenHABInstance.java @@ -33,16 +33,13 @@ public class OpenHABInstance { public Boolean callCommand(String aCommand, String commandData, HTTPHandler httpClient) { log.debug("calling OpenHAB: " + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + aCommand); String aUrl = null; - NameValue[] headers = null; if(theOpenHAB.getSecure() != null && theOpenHAB.getSecure()) aUrl = "https://"; else aUrl = "http://"; - if(theOpenHAB.getUsername() != null && !theOpenHAB.getUsername().isEmpty() && theOpenHAB.getPassword() != null && !theOpenHAB.getPassword().isEmpty()) { - aUrl = aUrl + theOpenHAB.getUsername() + ":" + theOpenHAB.getPassword() + "@"; - } + aUrl = aUrl + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + "/" + aCommand; - String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "text/plain", commandData, headers); + String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "text/plain", commandData, httpClient.addBasicAuthHeader(null, theOpenHAB)); log.debug("call Command return is: <" + theData + ">"); if(theData.contains("error") || theData.contains("ERROR") || theData.contains("Error")) return false; diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 725cf2a..0a70136 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -95,6 +95,10 @@ app.config(function ($locationProvider, $routeProvider) { templateUrl: 'views/broadlinkdevice.html', controller: 'BroadlinkController', requiresAuthentication: true + }).when('/homegeniedevices', { + templateUrl: 'views/homegeniedevice.html', + controller: 'HomeGenieController', + requiresAuthentication: true }).when('/login', { templateUrl: 'views/login.html', controller: 'LoginController' @@ -194,6 +198,7 @@ app.service('bridgeService', function ($rootScope, $http, $base64, $location, ng showMozIot: false, showFHEM: false, showBroadlink: false, + showHomeGenie: false, habridgeversion: {}, viewDevId: "", queueDevId: "", @@ -636,6 +641,11 @@ app.service('bridgeService', function ($rootScope, $http, $base64, $location, ng return; }; + this.updateShowHomeGenie = function () { + this.state.showHomeGenie = self.state.settings.homegenieconfigured; + return; + }; + this.loadBridgeSettings = function () { return $http.get(this.state.systemsbase + "/settings").then( function (response) { @@ -656,6 +666,7 @@ app.service('bridgeService', function ($rootScope, $http, $base64, $location, ng self.updateShowMozIot(); self.updateShowFhem(); self.updateShowBroadlink(); + self.updateShowHomeGenie(); }, function (error) { if (error.status === 401) @@ -1022,7 +1033,23 @@ app.service('bridgeService', function ($rootScope, $http, $base64, $location, ng if (error.status === 401) $rootScope.$broadcast('securityReinit', 'done'); else - self.displayWarn("Get broadlink Devices Error: ", error); + self.displayWarn("Get Broadlink Devices Error: ", error); + } + ); + }; + + this.viewHomeGenieDevices = function () { + if (!this.state.showHomeGenie) + return; + return $http.get(this.state.base + "/homegenie/devices").then( + function (response) { + self.state.homegeniedevices = response.data; + }, + function (error) { + if (error.status === 401) + $rootScope.$broadcast('securityReinit', 'done'); + else + self.displayWarn("Get HomeGenie Devices Error: ", error); } ); }; @@ -1885,7 +1912,7 @@ app.controller('SystemController', function ($scope, $location, bridgeService, n } }; - $scope.addMozIottoSettings = function (newmoziotname, newmoziotip, newmoziotport, newmoziotusername, newmoziotpassword, newmoziotsecure) { + $scope.addMozIottoSettings = function (newmoziotname, newmoziotip, newmoziotport, newmoziotusername, newmoziotpassword, newmoziotwebhook, newmoziotsecure) { if ($scope.bridge.settings.moziotaddress === undefined || $scope.bridge.settings.moziotaddress === null) { $scope.bridge.settings.moziotaddress = { devices: [] @@ -1897,6 +1924,7 @@ app.controller('SystemController', function ($scope, $location, bridgeService, n port: newmoziotport, username: newmoziotusername, password: newmoziotpassword, + webhook: newmoziotwebhook, secure: newmoziotsecure }; $scope.bridge.settings.moziotaddress.devices.push(newmoziot); @@ -1905,6 +1933,7 @@ app.controller('SystemController', function ($scope, $location, bridgeService, n $scope.newmoziotport = "4443"; $scope.newmoziotusername = null; $scope.newmoziotpassword = null; + $scope.newmoziotwebhook = null; }; $scope.removeMozIottoSettings = function (moziotname, moziotip) { for (var i = $scope.bridge.settings.moziotaddress.devices.length - 1; i >= 0; i--) { @@ -1945,6 +1974,37 @@ app.controller('SystemController', function ($scope, $location, bridgeService, n } }; + $scope.addHomeGenietoSettings = function (newhomegeniename, newhomegenieip, newhomegenieport, newhomegenieusername, newhomegeniepassword, newhomegeniewebhook, newhomegeniesecure) { + if ($scope.bridge.settings.homegenieaddress === undefined || $scope.bridge.settings.homegenieaddress === null) { + $scope.bridge.settings.homegenieaddress = { + devices: [] + }; + } + var newhomegenie = { + name: newhomegeniename, + ip: newhomegenieip, + port: newhomegenieport, + username: newhomegenieusername, + password: newhomegeniepassword, + secure: newhomegeniesecure, + webhook: newhomegeniewebhook + }; + $scope.bridge.settings.homegenieaddress.devices.push(newhomegenie); + $scope.newhomegeniename = null; + $scope.newhomegenieip = null; + $scope.newhomegenieport = "8080"; + $scope.newhomegenieusername = null; + $scope.newhomegeniepassword = null; + $scope.newhomegeniewebhook = null; + }; + $scope.removeHomeGenietoSettings = function (homegeniename, homegenieip) { + for (var i = $scope.bridge.settings.homegenieaddress.devices.length - 1; i >= 0; i--) { + if ($scope.bridge.settings.homegenieaddress.devices[i].name === homegeniename && $scope.bridge.settings.homegenieaddress.devices[i].ip === homegenieip) { + $scope.bridge.settings.homegenieaddress.devices.splice(i, 1); + } + } + }; + $scope.bridgeReinit = function () { bridgeService.reinit(); }; @@ -3504,7 +3564,7 @@ app.controller('HomeWizardController', function ($scope, $location, bridgeServic function () { $scope.clearDevice(); bridgeService.viewDevices(); - bridgeService.viewHalDevices(); + bridgeService.viewHomeWizardDevices(); }, function (error) { bridgeService.displayWarn("Error adding HomeWizard devices in bulk.", error); @@ -3664,7 +3724,7 @@ app.controller('DomoticzController', function ($scope, $location, bridgeService, function () { $scope.clearDevice(); bridgeService.viewDevices(); - bridgeService.viewHalDevices(); + bridgeService.viewDomoticzDevices(); }, function (error) { bridgeService.displayWarn("Error adding Domoticz devices in bulk.", error); @@ -3797,7 +3857,7 @@ app.controller('LifxController', function ($scope, $location, bridgeService, ngD function () { $scope.clearDevice(); bridgeService.viewDevices(); - bridgeService.viewHalDevices(); + bridgeService.viewLifxDevices(); }, function (error) { bridgeService.displayWarn("Error adding LIFX devices in bulk.", error); @@ -4098,7 +4158,7 @@ app.controller('OpenHABController', function ($scope, $location, bridgeService, function () { $scope.clearDevice(); bridgeService.viewDevices(); - bridgeService.viewHalDevices(); + bridgeService.viewOpenHABDevices(); }, function (error) { bridgeService.displayWarn("Error adding openhab devices in bulk.", error); @@ -4240,7 +4300,7 @@ app.controller('MozIotController', function ($scope, $location, bridgeService, n function () { $scope.clearDevice(); bridgeService.viewDevices(); - bridgeService.viewHalDevices(); + bridgeService.viewMozIotDevices(); }, function (error) { bridgeService.displayWarn("Error adding Mozilla IOT devices in bulk.", error); @@ -4384,7 +4444,7 @@ app.controller('FhemController', function ($scope, $location, bridgeService, ngD function () { $scope.clearDevice(); bridgeService.viewDevices(); - bridgeService.viewHalDevices(); + bridgeService.viewFhemDevices(); }, function (error) { bridgeService.displayWarn("Error adding fhem devices in bulk.", error); @@ -4543,7 +4603,7 @@ app.controller('BroadlinkController', function ($scope, $location, bridgeService function () { $scope.clearDevice(); bridgeService.viewDevices(); - bridgeService.viewHalDevices(); + bridgeService.viewBroadlinkDevices(); }, function (error) { bridgeService.displayWarn("Error adding openhab devices in bulk.", error); @@ -4610,6 +4670,146 @@ app.controller('BroadlinkController', function ($scope, $location, bridgeService }; }); +app.controller('HomeGenieController', function ($scope, $location, bridgeService, ngDialog) { + $scope.bridge = bridgeService.state; + $scope.device = bridgeService.state.device; + $scope.device_dim_control = ""; + $scope.bulk = { + devices: [] + }; + $scope.selectAll = false; + bridgeService.viewHomeGenieDevices(); + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + $scope.buttonsVisible = false; + + $scope.clearDevice = function () { + bridgeService.clearDevice(); + $scope.device = bridgeService.state.device; + }; + + $scope.buildDeviceUrls = function (homegeniedevice, dim_control, coloraction, colordata, buildonly) { + var preCmd = "{\"moduleType\":\"" + homegeniedevice.deviceDetail.Domain + "\",\"deviceId\":\"" + homegeniedevice.deviceDetail.Address + "\",\"command\":"; + onpayload = null; + offpayload = null; + dimpayload = null; + colorpayload = null; + onpayload = preCmd + "{\"command\":\"Control.On\"}}"; + offpayload = preCmd + "{\"command\":\"Control.Off\"}}"; + if (dim_control !== undefined && dim_control !== "") { + dimpayload = preCmd + "{\"command\":\"Control.Level\",\"level\":\"" + dim_control + "\"}}"; + } + // if (coloraction === 'other') + // colorpayload = "{\"url\":\"" + preCmd + "color\",\"command\":{\"color\":\"" + colordata + "\"}}"; + // else if (coloraction !== undefined && coloraction !== null && coloraction !== '') + // colorpayload = "{\"url\":\"" + preCmd + "color\",\"command\":{\"color\":\"" + coloraction + "\"}}"; + + bridgeService.buildUrls(onpayload, dimpayload, offpayload, colorpayload, true, homegeniedevice.deviceDetail.Name + "-" + homegeniedevice.deviceDetail.DeviceType, homegeniedevice.deviceDetail.Name, homegeniedevice.gatewayName, homegeniedevice.deviceDetail.DeviceType, "homegenieDevice", null, null); + $scope.device = bridgeService.state.device; + if (!buildonly) { + bridgeService.editNewDevice($scope.device); + $location.path('/editdevice'); + } + }; + + $scope.bulkAddDevices = function (dim_control) { + var devicesList = []; + $scope.clearDevice(); + for (var i = 0; i < $scope.bulk.devices.length; i++) { + for (var x = 0; x < bridgeService.state.homegeniedevices.length; x++) { + if (bridgeService.state.homegeniedevices[x].devicename === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.homegeniedevices[x], dim_control, null, null, true); + devicesList[i] = { + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + colorUrl: $scope.device.colorUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff + }; + $scope.clearDevice(); + } + } + } + bridgeService.bulkAddDevice(devicesList).then( + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewHomeGenieDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding HomeGenie devices in bulk.", error); + } + ); + $scope.bulk = { + devices: [] + }; + $scope.selectAll = false; + }; + + $scope.toggleSelection = function toggleSelection(deviceId) { + var idx = $scope.bulk.devices.indexOf(deviceId); + + // is currently selected + if (idx > -1) { + $scope.bulk.devices.splice(idx, 1); + if ($scope.bulk.devices.length === 0 && $scope.selectAll) + $scope.selectAll = false; + } + + // is newly selected + else { + $scope.bulk.devices.push(deviceId); + $scope.selectAll = true; + } + }; + + $scope.toggleSelectAll = function toggleSelectAll() { + if ($scope.selectAll) { + $scope.selectAll = false; + $scope.bulk = { + devices: [] + }; + } else { + $scope.selectAll = true; + for (var x = 0; x < bridgeService.state.homegeniedevices.length; x++) { + if ($scope.bulk.devices.indexOf(bridgeService.state.homegeniedevices[x]) < 0) + $scope.bulk.devices.push(bridgeService.state.homegeniedevices[x].devicename); + } + } + }; + + $scope.toggleButtons = function () { + $scope.buttonsVisible = !$scope.buttonsVisible; + if ($scope.buttonsVisible) + $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; + else + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + }; + + $scope.deleteDevice = function (device) { + $scope.bridge.device = device; + ngDialog.open({ + template: 'deleteDialog', + controller: 'DeleteDialogCtrl', + className: 'ngdialog-theme-default' + }); + }; + + $scope.editDevice = function (device) { + bridgeService.editDevice(device); + $location.path('/editdevice'); + }; +}); + app.controller('EditController', function ($scope, $location, bridgeService) { $scope.bridge = bridgeService.state; $scope.device = bridgeService.state.device; @@ -5127,6 +5327,20 @@ app.filter('configuredMozIotItems', function (bridgeService) { }; }); +app.filter('configuredHomeGenieItems', function (bridgeService) { + return function (input) { + var out = []; + if (input === undefined || input === null || input.length === undefined) + return out; + for (var i = 0; i < input.length; i++) { + if (bridgeService.deviceContainsType(input[i], "homegenie")) { + out.push(input[i]); + } + } + return out; + }; +}); + app.filter('filterDevicesByRequester', function () { return function (input, search, mustContain, deviceType) { var out = []; diff --git a/src/main/resources/public/views/broadlinkdevice.html b/src/main/resources/public/views/broadlinkdevice.html index f4ee90f..b2755df 100644 --- a/src/main/resources/public/views/broadlinkdevice.html +++ b/src/main/resources/public/views/broadlinkdevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/configuration.html b/src/main/resources/public/views/configuration.html index d351cac..d3c6f3d 100644 --- a/src/main/resources/public/views/configuration.html +++ b/src/main/resources/public/views/configuration.html @@ -22,6 +22,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/domoticzdevice.html b/src/main/resources/public/views/domoticzdevice.html index c2d365f..f13c50c 100644 --- a/src/main/resources/public/views/domoticzdevice.html +++ b/src/main/resources/public/views/domoticzdevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/editdevice.html b/src/main/resources/public/views/editdevice.html index 09a41cf..34e3ea9 100644 --- a/src/main/resources/public/views/editdevice.html +++ b/src/main/resources/public/views/editdevice.html @@ -22,6 +22,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • diff --git a/src/main/resources/public/views/fhemdevice.html b/src/main/resources/public/views/fhemdevice.html index 61ac469..ab7ad8a 100644 --- a/src/main/resources/public/views/fhemdevice.html +++ b/src/main/resources/public/views/fhemdevice.html @@ -21,6 +21,7 @@
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/fibarodevice.html b/src/main/resources/public/views/fibarodevice.html index da4d4ba..25a12ff 100644 --- a/src/main/resources/public/views/fibarodevice.html +++ b/src/main/resources/public/views/fibarodevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/fibaroscene.html b/src/main/resources/public/views/fibaroscene.html index 9913c3e..1bf5fe0 100644 --- a/src/main/resources/public/views/fibaroscene.html +++ b/src/main/resources/public/views/fibaroscene.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/haldevice.html b/src/main/resources/public/views/haldevice.html index d269a90..7760e81 100644 --- a/src/main/resources/public/views/haldevice.html +++ b/src/main/resources/public/views/haldevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/harmonyactivity.html b/src/main/resources/public/views/harmonyactivity.html index bfd79c3..4c3b16b 100644 --- a/src/main/resources/public/views/harmonyactivity.html +++ b/src/main/resources/public/views/harmonyactivity.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/harmonydevice.html b/src/main/resources/public/views/harmonydevice.html index bef18ca..6ee740c 100644 --- a/src/main/resources/public/views/harmonydevice.html +++ b/src/main/resources/public/views/harmonydevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/hassdevice.html b/src/main/resources/public/views/hassdevice.html index 4144fbb..c569fde 100644 --- a/src/main/resources/public/views/hassdevice.html +++ b/src/main/resources/public/views/hassdevice.html @@ -21,6 +21,7 @@
  • FHEM Devices
  • Mozilla IOT Devices
  • Broadlink Devices
  • +
  • HomeGenie Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/homegeniedevice.html b/src/main/resources/public/views/homegeniedevice.html index 987c0a8..6880d3d 100644 --- a/src/main/resources/public/views/homegeniedevice.html +++ b/src/main/resources/public/views/homegeniedevice.html @@ -21,7 +21,8 @@
  • FHEM Devices
  • HomeGenie Devices
  • Broadlink Devices
  • - +
  • Add/Edit
  • @@ -63,6 +64,7 @@
    NameDomain Type HomeGenie Build Actions{{homegeniedevice.deviceDetail.DeviceType}}{{homegeniedevice.deviceDetail.Domain}}{{homegeniedevice.deviceDetail.DeviceType}} {{homegeniedevice.gatewayName}}
    Actions
    {{$index+1}} {{device.name}} {{device.deviceType}}
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    RowIDNameDescriptionDevice StateTypeTargetInactiveNo StateActions
    {{$index+1}}{{device.id}}{{device.name}}{{device.description}}on={{device.deviceState.on}},bri={{device.deviceState.bri}},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}}{{device.noState}} -

    - - - - - - -

    -
    - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    RowIDNameDescriptionDevice StateTypeTargetInactiveNo StateActions
    {{$index+1}}{{device.id}}{{device.name}}{{device.description}} + on={{device.deviceState.on}},bri={{device.deviceState.bri}},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}}{{device.noState}} +

    + + + + + + +

    +
    +
    + -

    - Bridge Device DB Backup + Bridge Device DB Backup

    @@ -123,11 +125,10 @@ File Name
    - +
    -
    @@ -139,12 +140,10 @@ - {{backup}} + - - + + @@ -152,7 +151,7 @@
    + \ No newline at end of file diff --git a/src/main/resources/public/views/editdevice.html b/src/main/resources/public/views/editdevice.html index 34e3ea9..0edc9ae 100644 --- a/src/main/resources/public/views/editdevice.html +++ b/src/main/resources/public/views/editdevice.html @@ -78,6 +78,12 @@ + + + {{device.lockDeviceId}} + Date: Tue, 11 Jun 2019 15:28:54 -0500 Subject: [PATCH 27/52] Finished upload portion of device db --- pom.xml | 2 +- .../HABridge/dao/BackupFilename.java | 10 ++++ .../devicemanagmeent/DeviceResource.java | 19 ++++++++ .../HABridge/util/BackupHandler.java | 47 ++++++++++++++++++ src/main/resources/public/css/main.css | 14 +++++- src/main/resources/public/index.html | 4 +- .../public/js/ng-file-upload-shim.min.js | 2 + .../resources/public/js/ng-file-upload.min.js | 3 ++ src/main/resources/public/scripts/app.js | 48 +++++++++++++++++-- .../resources/public/views/configuration.html | 18 ++++++- 10 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 src/main/resources/public/js/ng-file-upload-shim.min.js create mode 100644 src/main/resources/public/js/ng-file-upload.min.js diff --git a/pom.xml b/pom.xml index b765b40..18a9cc7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 5.2.next_d + 5.2.next_e jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/dao/BackupFilename.java b/src/main/java/com/bwssystems/HABridge/dao/BackupFilename.java index f1c5cdb..55c0f35 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/BackupFilename.java +++ b/src/main/java/com/bwssystems/HABridge/dao/BackupFilename.java @@ -2,6 +2,7 @@ package com.bwssystems.HABridge.dao; public class BackupFilename { private String filename; + private String file; public String getFilename() { return filename; @@ -10,4 +11,13 @@ public class BackupFilename { public void setFilename(String filename) { this.filename = filename; } + + public String getFile() { + return file; + } + + public void setFile(String file) { + this.file = file; + } + } diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index 169312b..4a8ca49 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -401,6 +401,25 @@ public class DeviceResource { return backupContent; }, new JsonTransformer()); + // http://ip_address:port/api/devices/backup/upload CORS request + options(API_CONTEXT + "/backup/upload/:filename", "application/json", (request, response) -> { + response.status(HttpStatus.SC_OK); + response.header("Access-Control-Allow-Origin", request.headers("Origin")); + response.header("Access-Control-Allow-Methods", "PUT"); + response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers")); + response.header("Content-Type", "text/html; charset=utf-8"); + return ""; + }); + put (API_CONTEXT + "/backup/upload/:filename", "application/json", (request, response) -> { + log.debug("Create upload: {} - {}", request.params(":filename"), request.body()); + String theSuccess = deviceRepository.uploadBackup(request.params(":filename"), request.body()); + if(theSuccess.contains("Error:")) + response.status(HttpStatus.SC_METHOD_FAILURE); + else + response.status(HttpStatus.SC_OK); + return theSuccess; + }, new JsonTransformer()); + // http://ip_address:port/api/devices/backup/create CORS request options(API_CONTEXT + "/backup/create", "application/json", (request, response) -> { response.status(HttpStatus.SC_OK); diff --git a/src/main/java/com/bwssystems/HABridge/util/BackupHandler.java b/src/main/java/com/bwssystems/HABridge/util/BackupHandler.java index f2d3f68..b77827b 100644 --- a/src/main/java/com/bwssystems/HABridge/util/BackupHandler.java +++ b/src/main/java/com/bwssystems/HABridge/util/BackupHandler.java @@ -6,6 +6,7 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -109,4 +110,50 @@ public abstract class BackupHandler { return content; } + + public String uploadBackup(String aFilename, String theContent) { + String successMessage = null; + if(aFilename == null || aFilename.isEmpty()) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); + aFilename = defaultName + "upload-" + dateFormat.format(Calendar.getInstance().getTime()) + fileExtension; + } else { + if(!aFilename.endsWith(fileExtension)) { + aFilename = aFilename +fileExtension; + } + } + Path filePath = FileSystems.getDefault().getPath(repositoryPath.getParent().toString(), aFilename); + + successMessage = uploadWriter(theContent, filePath); + + return successMessage; + } + + private String uploadWriter(String content, Path filePath) { + String aMessage = null; + if (Files.exists(filePath)) { + aMessage = "Error: File exists, cannot write: " + filePath; + log.error(aMessage); + return aMessage; + } + + if (Files.notExists(filePath.getParent())) { + try { + Files.createDirectories(filePath.getParent()); + } catch (IOException e) { + aMessage = "Error: creating the directory: " + filePath + " message: " + e.getMessage(); + log.error(aMessage, e); + return aMessage; + } + } + + try { + Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE); + aMessage = "Success: creating file: " + filePath; + } catch (IOException e) { + aMessage = "Error: writing the file: " + filePath + " message: " + e.getMessage(); + log.error(aMessage, e); + } + + return aMessage; + } } diff --git a/src/main/resources/public/css/main.css b/src/main/resources/public/css/main.css index dd65cb9..d20ddaa 100644 --- a/src/main/resources/public/css/main.css +++ b/src/main/resources/public/css/main.css @@ -60,4 +60,16 @@ legend.form-label { .msg-error { color:#F00; font-size:14px; -} \ No newline at end of file +} + +.progress { + display: inline-block; + width: 100px; + border: 3px groove #CCC; +} + +.progress div { + font-size: smaller; + background: greenyellow; + width: 0; +} diff --git a/src/main/resources/public/index.html b/src/main/resources/public/index.html index afc97f4..108beca 100644 --- a/src/main/resources/public/index.html +++ b/src/main/resources/public/index.html @@ -89,7 +89,9 @@ - + + + \ No newline at end of file diff --git a/src/main/resources/public/js/ng-file-upload-shim.min.js b/src/main/resources/public/js/ng-file-upload-shim.min.js new file mode 100644 index 0000000..9928c83 --- /dev/null +++ b/src/main/resources/public/js/ng-file-upload-shim.min.js @@ -0,0 +1,2 @@ +/*! 12.2.13 */ +!function(){function a(a,b){window.XMLHttpRequest.prototype[a]=b(window.XMLHttpRequest.prototype[a])}function b(a,b,c){try{Object.defineProperty(a,b,{get:c})}catch(d){}}if(window.FileAPI||(window.FileAPI={}),!window.XMLHttpRequest)throw"AJAX is not supported. XMLHttpRequest is not defined.";if(FileAPI.shouldLoad=!window.FormData||FileAPI.forceLoad,FileAPI.shouldLoad){var c=function(a){if(!a.__listeners){a.upload||(a.upload={}),a.__listeners=[];var b=a.upload.addEventListener;a.upload.addEventListener=function(c,d){a.__listeners[c]=d,b&&b.apply(this,arguments)}}};a("open",function(a){return function(b,d,e){c(this),this.__url=d;try{a.apply(this,[b,d,e])}catch(f){f.message.indexOf("Access is denied")>-1&&(this.__origError=f,a.apply(this,[b,"_fix_for_ie_crossdomain__",e]))}}}),a("getResponseHeader",function(a){return function(b){return this.__fileApiXHR&&this.__fileApiXHR.getResponseHeader?this.__fileApiXHR.getResponseHeader(b):null==a?null:a.apply(this,[b])}}),a("getAllResponseHeaders",function(a){return function(){return this.__fileApiXHR&&this.__fileApiXHR.getAllResponseHeaders?this.__fileApiXHR.getAllResponseHeaders():null==a?null:a.apply(this)}}),a("abort",function(a){return function(){return this.__fileApiXHR&&this.__fileApiXHR.abort?this.__fileApiXHR.abort():null==a?null:a.apply(this)}}),a("setRequestHeader",function(a){return function(b,d){if("__setXHR_"===b){c(this);var e=d(this);e instanceof Function&&e(this)}else this.__requestHeaders=this.__requestHeaders||{},this.__requestHeaders[b]=d,a.apply(this,arguments)}}),a("send",function(a){return function(){var c=this;if(arguments[0]&&arguments[0].__isFileAPIShim){var d=arguments[0],e={url:c.__url,jsonp:!1,cache:!0,complete:function(a,d){a&&angular.isString(a)&&-1!==a.indexOf("#2174")&&(a=null),c.__completed=!0,!a&&c.__listeners.load&&c.__listeners.load({type:"load",loaded:c.__loaded,total:c.__total,target:c,lengthComputable:!0}),!a&&c.__listeners.loadend&&c.__listeners.loadend({type:"loadend",loaded:c.__loaded,total:c.__total,target:c,lengthComputable:!0}),"abort"===a&&c.__listeners.abort&&c.__listeners.abort({type:"abort",loaded:c.__loaded,total:c.__total,target:c,lengthComputable:!0}),void 0!==d.status&&b(c,"status",function(){return 0===d.status&&a&&"abort"!==a?500:d.status}),void 0!==d.statusText&&b(c,"statusText",function(){return d.statusText}),b(c,"readyState",function(){return 4}),void 0!==d.response&&b(c,"response",function(){return d.response});var e=d.responseText||(a&&0===d.status&&"abort"!==a?a:void 0);b(c,"responseText",function(){return e}),b(c,"response",function(){return e}),a&&b(c,"err",function(){return a}),c.__fileApiXHR=d,c.onreadystatechange&&c.onreadystatechange(),c.onload&&c.onload()},progress:function(a){if(a.target=c,c.__listeners.progress&&c.__listeners.progress(a),c.__total=a.total,c.__loaded=a.loaded,a.total===a.loaded){var b=this;setTimeout(function(){c.__completed||(c.getAllResponseHeaders=function(){},b.complete(null,{status:204,statusText:"No Content"}))},FileAPI.noContentTimeout||1e4)}},headers:c.__requestHeaders};e.data={},e.files={};for(var f=0;f-1){e=h.substring(0,g+1);break}null==FileAPI.staticPath&&(FileAPI.staticPath=e),i.setAttribute("src",d||e+"FileAPI.min.js"),document.getElementsByTagName("head")[0].appendChild(i)}FileAPI.ngfFixIE=function(d,e,f){if(!b())throw'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';var g=function(){var b=e.parent();d.attr("disabled")?b&&b.removeClass("js-fileapi-wrapper"):(e.attr("__ngf_flash_")||(e.unbind("change"),e.unbind("click"),e.bind("change",function(a){h.apply(this,[a]),f.apply(this,[a])}),e.attr("__ngf_flash_","true")),b.addClass("js-fileapi-wrapper"),a(d)||(b.css("position","absolute").css("top",c(d[0]).top+"px").css("left",c(d[0]).left+"px").css("width",d[0].offsetWidth+"px").css("height",d[0].offsetHeight+"px").css("filter","alpha(opacity=0)").css("display",d.css("display")).css("overflow","hidden").css("z-index","900000").css("visibility","visible"),e.css("width",d[0].offsetWidth+"px").css("height",d[0].offsetHeight+"px").css("position","absolute").css("top","0px").css("left","0px")))};d.bind("mouseenter",g);var h=function(a){for(var b=FileAPI.getFiles(a),c=0;c0},this.rename=function(a,b){return a.ngfName=b,a},this.jsonBlob=function(a){null==a||angular.isString(a)||(a=JSON.stringify(a));var b=new window.Blob([a],{type:"application/json"});return b._ngfBlob=!0,b},this.json=function(a){return angular.toJson(a)},this.isFile=function(a){return null!=a&&(a instanceof window.Blob||a.flashId&&a.name&&a.size)},this.upload=function(a,b){function c(b,c){if(b._ngfBlob)return b;if(a._file=a._file||b,null!=a._start&&g){a._end&&a._end>=b.size&&(a._finished=!0,a._end=b.size);var d=b.slice(a._start,a._end||b.size);return d.name=b.name,d.ngfName=b.ngfName,a._chunkSize&&(c.append("_chunkSize",a._chunkSize),c.append("_currentChunkSize",a._end-a._start),c.append("_chunkNumber",Math.floor(a._start/a._chunkSize)),c.append("_totalSize",a._file.size)),d}return b}function h(b,d,e){if(void 0!==d)if(angular.isDate(d)&&(d=d.toISOString()),angular.isString(d))b.append(e,d);else if(f.isFile(d)){var g=c(d,b),i=e.split(",");i[1]&&(g.ngfName=i[1].replace(/^\s+|\s+$/g,""),e=i[0]),a._fileKey=a._fileKey||e,b.append(e,g,g.ngfName||g.name)}else if(angular.isObject(d)){if(d.$$ngfCircularDetection)throw"ngFileUpload: Circular reference in config.data. Make sure specified data for Upload.upload() has no circular reference: "+e;d.$$ngfCircularDetection=!0;try{for(var j in d)if(d.hasOwnProperty(j)&&"$$ngfCircularDetection"!==j){var k=null==a.objectKey?"[i]":a.objectKey;d.length&&parseInt(j)>-1&&(k=null==a.arrayKey?k:a.arrayKey),h(b,d[j],e+k.replace(/[ik]/g,j))}}finally{delete d.$$ngfCircularDetection}}else b.append(e,d)}function i(){a._chunkSize=f.translateScalars(a.resumeChunkSize),a._chunkSize=a._chunkSize?parseInt(a._chunkSize.toString()):null,a.headers=a.headers||{},a.headers["Content-Type"]=void 0,a.transformRequest=a.transformRequest?angular.isArray(a.transformRequest)?a.transformRequest:[a.transformRequest]:[],a.transformRequest.push(function(b){var c,d=new window.FormData;b=b||a.fields||{},a.file&&(b.file=a.file);for(c in b)if(b.hasOwnProperty(c)){var e=b[c];a.formDataAppender?a.formDataAppender(d,c,e):h(d,e,c)}return d})}return b||(a=e(a)),a._isDigested||(a._isDigested=!0,i()),d(a)},this.http=function(b){return b=e(b),b.transformRequest=b.transformRequest||function(b){return window.ArrayBuffer&&b instanceof window.ArrayBuffer||b instanceof window.Blob?b:a.defaults.transformRequest[0].apply(this,arguments)},b._chunkSize=f.translateScalars(b.resumeChunkSize),b._chunkSize=b._chunkSize?parseInt(b._chunkSize.toString()):null,d(b)},this.translateScalars=function(a){if(angular.isString(a)){if(a.search(/kb/i)===a.length-2)return parseFloat(1024*a.substring(0,a.length-2));if(a.search(/mb/i)===a.length-2)return parseFloat(1048576*a.substring(0,a.length-2));if(a.search(/gb/i)===a.length-2)return parseFloat(1073741824*a.substring(0,a.length-2));if(a.search(/b/i)===a.length-1)return parseFloat(a.substring(0,a.length-1));if(a.search(/s/i)===a.length-1)return parseFloat(a.substring(0,a.length-1));if(a.search(/m/i)===a.length-1)return parseFloat(60*a.substring(0,a.length-1));if(a.search(/h/i)===a.length-1)return parseFloat(3600*a.substring(0,a.length-1))}return a},this.urlToBlob=function(c){var d=b.defer();return a({url:c,method:"get",responseType:"arraybuffer"}).then(function(a){var b=new Uint8Array(a.data),e=a.headers("content-type")||"image/WebP",f=new window.Blob([b],{type:e}),g=c.match(/.*\/(.+?)(\?.*)?$/);g.length>1&&(f.name=g[1]),d.resolve(f)},function(a){d.reject(a)}),d.promise},this.setDefaults=function(a){this.defaults=a||{}},this.defaults={},this.version=ngFileUpload.version}]),ngFileUpload.service("Upload",["$parse","$timeout","$compile","$q","UploadExif",function(a,b,c,d,e){function f(a,b,c){var e=[i.emptyPromise()];return angular.forEach(a,function(d,f){0===d.type.indexOf("image/jpeg")&&i.attrGetter("ngfFixOrientation",b,c,{$file:d})&&e.push(i.happyPromise(i.applyExifRotation(d),d).then(function(b){a.splice(f,1,b)}))}),d.all(e)}function g(a,b,c,e){var f=i.attrGetter("ngfResize",b,c);if(!f||!i.isResizeSupported()||!a.length)return i.emptyPromise();if(f instanceof Function){var g=d.defer();return f(a).then(function(d){h(d,a,b,c,e).then(function(a){g.resolve(a)},function(a){g.reject(a)})},function(a){g.reject(a)})}return h(f,a,b,c,e)}function h(a,b,c,e,f){function g(d,g){if(0===d.type.indexOf("image")){if(a.pattern&&!i.validatePattern(d,a.pattern))return;a.resizeIf=function(a,b){return i.attrGetter("ngfResizeIf",c,e,{$width:a,$height:b,$file:d})};var j=i.resize(d,a);h.push(j),j.then(function(a){b.splice(g,1,a)},function(a){d.$error="resize",(d.$errorMessages=d.$errorMessages||{}).resize=!0,d.$errorParam=(a?(a.message?a.message:a)+": ":"")+(d&&d.name),f.$ngfValidations.push({name:"resize",valid:!1}),i.applyModelValidation(f,b)})}}for(var h=[i.emptyPromise()],j=0;j-1:!0},i.emptyPromise=function(){var a=d.defer(),c=arguments;return b(function(){a.resolve.apply(a,c)}),a.promise},i.rejectPromise=function(){var a=d.defer(),c=arguments;return b(function(){a.reject.apply(a,c)}),a.promise},i.happyPromise=function(a,c){var e=d.defer();return a.then(function(a){e.resolve(a)},function(a){b(function(){throw a}),e.resolve(c)}),e.promise},i.updateModel=function(c,d,e,h,j,k,l){function m(f,g,j,l,m){d.$$ngfPrevValidFiles=f,d.$$ngfPrevInvalidFiles=g;var n=f&&f.length?f[0]:null,o=g&&g.length?g[0]:null;c&&(i.applyModelValidation(c,f),c.$setViewValue(m?n:f)),h&&a(h)(e,{$files:f,$file:n,$newFiles:j,$duplicateFiles:l,$invalidFiles:g,$invalidFile:o,$event:k});var p=i.attrGetter("ngfModelInvalid",d);p&&b(function(){a(p).assign(e,m?o:g)}),b(function(){})}function n(){function a(a,b){return a.name===b.name&&(a.$ngfOrigSize||a.size)===(b.$ngfOrigSize||b.size)&&a.type===b.type}function b(b){var c;for(c=0;c-1&&(v.splice(d,1),u.push(c)),a()}}})}var q,r,s,t=[],u=[],v=[];r=d.$$ngfPrevValidFiles||[],s=d.$$ngfPrevInvalidFiles||[],c&&c.$modelValue&&(r=o(c.$modelValue));var w=i.attrGetter("ngfKeep",d,e);q=(j||[]).slice(0),("distinct"===w||i.attrGetter("ngfKeepDistinct",d,e)===!0)&&n(d,e);var x=!w&&!i.attrGetter("ngfMultiple",d,e)&&!i.attrGetter("multiple",d);if(!w||q.length){i.attrGetter("ngfBeforeModelChange",d,e,{$files:j,$file:j&&j.length?j[0]:null,$newFiles:q,$duplicateFiles:t,$event:k});var y=i.attrGetter("ngfValidateAfterResize",d,e),z=i.attrGetter("ngfModelOptions",d,e);i.validate(q,w?r.length:0,c,d,e).then(function(a){l?m(q,[],j,t,x):(z&&z.allowInvalid||y?v=q:(v=a.validFiles,u=a.invalidFiles),i.attrGetter("ngfFixOrientation",d,e)&&i.isExifSupported()?f(v,d,e).then(function(){p()}):p())})}},i}]),ngFileUpload.directive("ngfSelect",["$parse","$timeout","$compile","Upload",function(a,b,c,d){function e(a){var b=a.match(/Android[^\d]*(\d+)\.(\d+)/);if(b&&b.length>2){var c=d.defaults.androidFixMinorVersion||4;return parseInt(b[1])<4||parseInt(b[1])===c&&parseInt(b[2])'),c=angular.element("");return c.css("visibility","hidden").css("position","absolute").css("overflow","hidden").css("width","0px").css("height","0px").css("border","none").css("margin","0px").css("padding","0px").attr("tabindex","-1"),n(a,c),g.push({el:b,ref:c}),document.body.appendChild(c.append(a)[0]),a}function p(c){if(b.attr("disabled"))return!1;if(!t("ngfSelectDisabled",a)){var d=q(c);if(null!=d)return d;r(c);try{k()||document.body.contains(x[0])||(g.push({el:b,ref:x.parent()}),document.body.appendChild(x.parent()[0]),x.bind("change",m))}catch(f){}return e(navigator.userAgent)?setTimeout(function(){x[0].click()},0):x[0].click(),!1}}function q(a){var b=a.changedTouches||a.originalEvent&&a.originalEvent.changedTouches;if(b){if("touchstart"===a.type)return w=b[0].clientX,v=b[0].clientY,!0;if("touchend"===a.type){var c=b[0].clientX,d=b[0].clientY;if(Math.abs(c-w)>20||Math.abs(d-v)>20)return a.stopPropagation(),a.preventDefault(),!1}return!0}}function r(b){j.shouldUpdateOn("click",c,a)&&x.val()&&(x.val(null),j.updateModel(d,c,a,l(),null,b,!0))}function s(a){if(x&&!x.attr("__ngf_ie10_Fix_")){if(!x[0].parentNode)return void(x=null);a.preventDefault(),a.stopPropagation(),x.unbind("click");var b=x.clone();return x.replaceWith(b),x=b,x.attr("__ngf_ie10_Fix_","true"),x.bind("change",m),x.bind("click",s),x[0].click(),!1}x.removeAttr("__ngf_ie10_Fix_")}var t=function(a,b){return j.attrGetter(a,c,b)};j.registerModelChangeValidator(d,c,a);var u=[];t("ngfMultiple")&&u.push(a.$watch(t("ngfMultiple"),function(){x.attr("multiple",t("ngfMultiple",a))})),t("ngfCapture")&&u.push(a.$watch(t("ngfCapture"),function(){x.attr("capture",t("ngfCapture",a))})),t("ngfAccept")&&u.push(a.$watch(t("ngfAccept"),function(){x.attr("accept",t("ngfAccept",a))})),u.push(c.$observe("accept",function(){x.attr("accept",t("accept"))}));var v=0,w=0,x=b;k()||(x=o()),x.bind("change",m),k()?b.bind("click",r):b.bind("click touchstart touchend",p),-1!==navigator.appVersion.indexOf("MSIE 10")&&x.bind("click",s),d&&d.$formatters.push(function(a){return(null==a||0===a.length)&&x.val()&&x.val(null),a}),a.$on("$destroy",function(){k()||x.parent().remove(),angular.forEach(u,function(a){a()})}),h(function(){for(var a=0;a-1&&l.height&&l.height.indexOf("px")>-1&&(k={width:parseInt(l.width.slice(0,-2)),height:parseInt(l.height.slice(0,-2))})}return angular.isString(c)?(e.removeClass("ng-hide"),i?e.css("background-image","url('"+c+"')"):e.attr("src",c)):void(!c||!c.type||0!==c.type.search(a(e[0]))||i&&0!==c.type.indexOf("image")?e.addClass("ng-hide"):k&&b.isResizeSupported()?(k.resizeIf=function(a,e){return b.attrGetter("ngfResizeIf",f,d,{$width:a,$height:e,$file:c})},b.resize(c,k).then(function(a){j(a)},function(a){throw a})):j(c))});d.$on("$destroy",function(){c()})})}ngFileUpload.service("UploadDataUrl",["UploadBase","$timeout","$q",function(a,b,c){var d=a;return d.base64DataUrl=function(a){if(angular.isArray(a)){var b=c.defer(),e=0;return angular.forEach(a,function(c){d.dataUrl(c,!0)["finally"](function(){if(e++,e===a.length){var c=[];angular.forEach(a,function(a){c.push(a.$ngfDataUrl)}),b.resolve(c,a)}})}),b.promise}return d.dataUrl(a,!0)},d.dataUrl=function(a,e){if(!a)return d.emptyPromise(a,a);if(e&&null!=a.$ngfDataUrl||!e&&null!=a.$ngfBlobUrl)return d.emptyPromise(e?a.$ngfDataUrl:a.$ngfBlobUrl,a);var f=e?a.$$ngfDataUrlPromise:a.$$ngfBlobUrlPromise;if(f)return f;var g=c.defer();return b(function(){if(window.FileReader&&a&&(!window.FileAPI||-1===navigator.userAgent.indexOf("MSIE 8")||a.size<2e4)&&(!window.FileAPI||-1===navigator.userAgent.indexOf("MSIE 9")||a.size<4e6)){var c=window.URL||window.webkitURL;if(c&&c.createObjectURL&&!e){var f;try{f=c.createObjectURL(a)}catch(h){return void b(function(){a.$ngfBlobUrl="",g.reject()})}b(function(){if(a.$ngfBlobUrl=f,f){g.resolve(f,a),d.blobUrls=d.blobUrls||[],d.blobUrlsTotalSize=d.blobUrlsTotalSize||0,d.blobUrls.push({url:f,size:a.size}),d.blobUrlsTotalSize+=a.size||0;for(var b=d.defaults.blobUrlsMaxMemory||268435456,e=d.defaults.blobUrlsMaxQueueSize||200;(d.blobUrlsTotalSize>b||d.blobUrls.length>e)&&d.blobUrls.length>1;){var h=d.blobUrls.splice(0,1)[0];c.revokeObjectURL(h.url),d.blobUrlsTotalSize-=h.size}}})}else{var i=new FileReader;i.onload=function(c){b(function(){a.$ngfDataUrl=c.target.result,g.resolve(c.target.result,a),b(function(){delete a.$ngfDataUrl},1e3)})},i.onerror=function(){b(function(){a.$ngfDataUrl="",g.reject()})},i.readAsDataURL(a)}}else b(function(){a[e?"$ngfDataUrl":"$ngfBlobUrl"]="",g.reject()})}),f=e?a.$$ngfDataUrlPromise=g.promise:a.$$ngfBlobUrlPromise=g.promise,f["finally"](function(){delete a[e?"$$ngfDataUrlPromise":"$$ngfBlobUrlPromise"]}),f},d}]),ngFileUpload.directive("ngfSrc",["Upload","$timeout",function(a,c){return{restrict:"AE",link:function(d,e,f){b(a,c,d,e,f,"ngfSrc",a.attrGetter("ngfResize",f,d),!1)}}}]),ngFileUpload.directive("ngfBackground",["Upload","$timeout",function(a,c){return{restrict:"AE",link:function(d,e,f){b(a,c,d,e,f,"ngfBackground",a.attrGetter("ngfResize",f,d),!0)}}}]),ngFileUpload.directive("ngfThumbnail",["Upload","$timeout",function(a,c){return{restrict:"AE",link:function(d,e,f){var g=a.attrGetter("ngfSize",f,d);b(a,c,d,e,f,"ngfThumbnail",g,a.attrGetter("ngfAsBackground",f,d))}}}]),ngFileUpload.config(["$compileProvider",function(a){a.imgSrcSanitizationWhitelist&&a.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/),a.aHrefSanitizationWhitelist&&a.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|webcal|local|file|data|blob):/)}]),ngFileUpload.filter("ngfDataUrl",["UploadDataUrl","$sce",function(a,b){return function(c,d,e){if(angular.isString(c))return b.trustAsResourceUrl(c);var f=c&&((d?c.$ngfDataUrl:c.$ngfBlobUrl)||c.$ngfDataUrl);return c&&!f?(!c.$ngfDataUrlFilterInProgress&&angular.isObject(c)&&(c.$ngfDataUrlFilterInProgress=!0,a.dataUrl(c,d)),""):(c&&delete c.$ngfDataUrlFilterInProgress,(c&&f?e?b.trustAsResourceUrl(f):f:c)||"")}}])}(),ngFileUpload.service("UploadValidate",["UploadDataUrl","$q","$timeout",function(a,b,c){function d(a){var b="",c=[];if(a.length>2&&"/"===a[0]&&"/"===a[a.length-1])b=a.substring(1,a.length-1);else{var e=a.split(",");if(e.length>1)for(var f=0;f|:\\-]","g"),"\\$&")+"$",b=b.replace(/\\\*/g,".*").replace(/\\\?/g,"."))}return{regexp:b,excludes:c}}function e(a,b){null==b||a.$dirty||(a.$setDirty?a.$setDirty():a.$dirty=!0)}var f=a;return f.validatePattern=function(a,b){if(!b)return!0;var c=d(b),e=!0;if(c.regexp&&c.regexp.length){var f=new RegExp(c.regexp,"i");e=null!=a.type&&f.test(a.type)||null!=a.name&&f.test(a.name)}for(var g=c.excludes.length;g--;){var h=new RegExp(c.excludes[g],"i");e=e&&(null==a.type||h.test(a.type))&&(null==a.name||h.test(a.name))}return e},f.ratioToFloat=function(a){var b=a.toString(),c=b.search(/[x:]/i);return b=c>-1?parseFloat(b.substring(0,c))/parseFloat(b.substring(c+1)):parseFloat(b)},f.registerModelChangeValidator=function(a,b,c){a&&a.$formatters.push(function(d){if(a.$dirty){var e=d;d&&!angular.isArray(d)&&(e=[d]),f.validate(e,0,a,b,c).then(function(){f.applyModelValidation(a,e)})}return d})},f.applyModelValidation=function(a,b){e(a,b),angular.forEach(a.$ngfValidations,function(b){a.$setValidity(b.name,b.valid)})},f.getValidationAttr=function(a,b,c,d,e){var g="ngf"+c[0].toUpperCase()+c.substr(1),h=f.attrGetter(g,a,b,{$file:e});if(null==h&&(h=f.attrGetter("ngfValidate",a,b,{$file:e}))){var i=(d||c).split(".");h=h[i[0]],i.length>1&&(h=h&&h[i[1]])}return h},f.validate=function(a,c,d,e,g){function h(b,c,h){if(a){for(var i=a.length,j=null;i--;){var n=a[i];if(n){var o=f.getValidationAttr(e,g,b,c,n);null!=o&&(h(n,o,i)||(-1===k.indexOf(b)?(n.$error=b,(n.$errorMessages=n.$errorMessages||{})[b]=!0,n.$errorParam=o,-1===m.indexOf(n)&&m.push(n),l||a.splice(i,1),j=!1):a.splice(i,1)))}}null!==j&&d.$ngfValidations.push({name:b,valid:j})}}function i(c,h,i,n,o){function p(b,d,e){function f(f){if(f())if(-1===k.indexOf(c)){if(d.$error=c,(d.$errorMessages=d.$errorMessages||{})[c]=!0,d.$errorParam=e,-1===m.indexOf(d)&&m.push(d),!l){var g=a.indexOf(d);g>-1&&a.splice(g,1)}b.resolve(!1)}else{var h=a.indexOf(d);h>-1&&a.splice(h,1),b.resolve(!0)}else b.resolve(!0)}null!=e?n(d,e).then(function(a){f(function(){return!o(a,e)})},function(){f(function(){return j("ngfValidateForce",{$file:d})})}):b.resolve(!0)}var q=[f.emptyPromise(!0)];a&&(a=void 0===a.length?[a]:a,angular.forEach(a,function(a){var d=b.defer();return q.push(d.promise),!i||null!=a.type&&0===a.type.search(i)?void("dimensions"===c&&null!=f.attrGetter("ngfDimensions",e)?f.imageDimensions(a).then(function(b){p(d,a,j("ngfDimensions",{$file:a,$width:b.width,$height:b.height}))},function(){d.resolve(!1)}):"duration"===c&&null!=f.attrGetter("ngfDuration",e)?f.mediaDuration(a).then(function(b){p(d,a,j("ngfDuration",{$file:a,$duration:b}))},function(){d.resolve(!1)}):p(d,a,f.getValidationAttr(e,g,c,h,a))):void d.resolve(!0)}));var r=b.defer();return b.all(q).then(function(a){for(var b=!0,e=0;e=f.translateScalars(b)}),h("maxSize","size.max",function(a,b){return a.size-.1<=f.translateScalars(b)});var n=0;if(h("maxTotalSize",null,function(b,c){return n+=b.size,n>f.translateScalars(c)?(a.splice(0,a.length),!1):!0}),h("validateFn",null,function(a,b){return b===!0||null===b||""===b}),!a.length)return f.emptyPromise({validFiles:[],invalidFiles:m});var o=b.defer(),p=[];return p.push(i("maxHeight","height.max",/image/,this.imageDimensions,function(a,b){return a.height<=b})),p.push(i("minHeight","height.min",/image/,this.imageDimensions,function(a,b){return a.height>=b})),p.push(i("maxWidth","width.max",/image/,this.imageDimensions,function(a,b){return a.width<=b})),p.push(i("minWidth","width.min",/image/,this.imageDimensions,function(a,b){return a.width>=b})),p.push(i("dimensions",null,/image/,function(a,b){return f.emptyPromise(b)},function(a){return a})),p.push(i("ratio",null,/image/,this.imageDimensions,function(a,b){for(var c=b.toString().split(","),d=!1,e=0;e-1e-4})),p.push(i("maxDuration","duration.max",/audio|video/,this.mediaDuration,function(a,b){return a<=f.translateScalars(b)})),p.push(i("minDuration","duration.min",/audio|video/,this.mediaDuration,function(a,b){return a>=f.translateScalars(b)})),p.push(i("duration",null,/audio|video/,function(a,b){return f.emptyPromise(b)},function(a){return a})),p.push(i("validateAsyncFn",null,null,function(a,b){return b},function(a){return a===!0||null===a||""===a})),b.all(p).then(function(){if(l)for(var b=0;bc+d}),o.resolve({validFiles:a,invalidFiles:m})}),o.promise},f.imageDimensions=function(a){if(a.$ngfWidth&&a.$ngfHeight){var d=b.defer();return c(function(){d.resolve({width:a.$ngfWidth,height:a.$ngfHeight})}),d.promise}if(a.$ngfDimensionPromise)return a.$ngfDimensionPromise;var e=b.defer();return c(function(){return 0!==a.type.indexOf("image")?void e.reject("not image"):void f.dataUrl(a).then(function(b){function d(){var b=h[0].naturalWidth||h[0].clientWidth,c=h[0].naturalHeight||h[0].clientHeight;h.remove(),a.$ngfWidth=b,a.$ngfHeight=c,e.resolve({width:b,height:c})}function f(){h.remove(),e.reject("load error")}function g(){c(function(){h[0].parentNode&&(h[0].clientWidth?d():i++>10?f():g())},1e3)}var h=angular.element("").attr("src",b).css("visibility","hidden").css("position","fixed").css("max-width","none !important").css("max-height","none !important");h.on("load",d),h.on("error",f);var i=0;g(),angular.element(document.getElementsByTagName("body")[0]).append(h)},function(){e.reject("load error")})}),a.$ngfDimensionPromise=e.promise,a.$ngfDimensionPromise["finally"](function(){delete a.$ngfDimensionPromise}),a.$ngfDimensionPromise},f.mediaDuration=function(a){if(a.$ngfDuration){var d=b.defer();return c(function(){d.resolve(a.$ngfDuration)}),d.promise}if(a.$ngfDurationPromise)return a.$ngfDurationPromise;var e=b.defer();return c(function(){return 0!==a.type.indexOf("audio")&&0!==a.type.indexOf("video")?void e.reject("not media"):void f.dataUrl(a).then(function(b){function d(){var b=h[0].duration;a.$ngfDuration=b,h.remove(),e.resolve(b)}function f(){h.remove(),e.reject("load error")}function g(){c(function(){h[0].parentNode&&(h[0].duration?d():i>10?f():g())},1e3)}var h=angular.element(0===a.type.indexOf("audio")?"