From b5e6e3ad6021fb6cd518e716b438f51ea9e07401 Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 27 Jan 2017 15:11:30 -0600 Subject: [PATCH] v4.1.0 Added feature for Domoticz and fixed some major bugs, ie: mqtt, and some enhancements. --- pom.xml | 2 +- .../com/bwssystems/HABridge/HomeManager.java | 2 +- .../HABridge/api/hue/GroupResponse.java | 40 +++- .../HABridge/api/hue/HueApiResponse.java | 6 +- .../HABridge/api/hue/HueConstants.java | 2 +- .../HABridge/dao/DeviceDescriptor.java | 37 +++- .../HABridge/dao/DeviceRepository.java | 2 +- .../bwssystems/HABridge/hue/HueMulator.java | 189 ++++++++++++++++-- .../plugins/domoticz/DomoticzHome.java | 27 +-- .../HABridge/plugins/hal/HalHome.java | 40 +--- .../HABridge/plugins/hal/HalInfo.java | 2 + .../HABridge/plugins/hass/HomeAssistant.java | 4 +- .../HABridge/plugins/mqtt/MQTTHome.java | 20 +- src/main/resources/public/scripts/app.js | 65 ++++-- .../resources/public/views/configuration.html | 2 + .../public/views/domoticzdevice.html | 4 +- .../resources/public/views/editdevice.html | 7 + .../resources/public/views/haldevice.html | 1 + .../public/views/harmonyactivity.html | 1 + .../resources/public/views/harmonydevice.html | 1 + .../resources/public/views/hassdevice.html | 4 +- .../resources/public/views/huedevice.html | 1 + src/main/resources/public/views/logs.html | 1 + .../resources/public/views/mqttpublish.html | 1 + .../resources/public/views/nestactions.html | 1 + src/main/resources/public/views/system.html | 2 +- .../resources/public/views/veradevice.html | 1 + .../resources/public/views/verascene.html | 1 + 28 files changed, 339 insertions(+), 127 deletions(-) diff --git a/pom.xml b/pom.xml index addc4fd..e0c9dbc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.1.0beta5 + 4.1.0 jar diff --git a/src/main/java/com/bwssystems/HABridge/HomeManager.java b/src/main/java/com/bwssystems/HABridge/HomeManager.java index 9596d67..83b1118 100644 --- a/src/main/java/com/bwssystems/HABridge/HomeManager.java +++ b/src/main/java/com/bwssystems/HABridge/HomeManager.java @@ -70,6 +70,7 @@ public class HomeManager { homeList.put(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex], aHome); homeList.put(DeviceMapTypes.VERA_DEVICE[DeviceMapTypes.typeIndex], aHome); homeList.put(DeviceMapTypes.VERA_SCENE[DeviceMapTypes.typeIndex], aHome); + homeList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome); //setup the tcp handler Home aHome = new TCPHome(bridgeSettings); homeList.put(DeviceMapTypes.TCP_DEVICE[DeviceMapTypes.typeIndex], aHome); @@ -85,7 +86,6 @@ public class HomeManager { //setup the HomeAssistant configuration if available aHome = new DomoticzHome(bridgeSettings); resourceList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome); - homeList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome); } public Home findHome(String type) { diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/GroupResponse.java b/src/main/java/com/bwssystems/HABridge/api/hue/GroupResponse.java index f804c14..cdaf02b 100644 --- a/src/main/java/com/bwssystems/HABridge/api/hue/GroupResponse.java +++ b/src/main/java/com/bwssystems/HABridge/api/hue/GroupResponse.java @@ -3,11 +3,20 @@ package com.bwssystems.HABridge.api.hue; import java.util.List; import com.bwssystems.HABridge.dao.DeviceDescriptor; +import com.google.gson.annotations.SerializedName; public class GroupResponse { + @SerializedName("action") private DeviceState action; + @SerializedName("lights") private String[] lights; + @SerializedName("name") private String name; + @SerializedName("type") + private String type; + @SerializedName("class") + String class_name; + public DeviceState getAction() { return action; } @@ -27,7 +36,19 @@ public class GroupResponse { this.name = name; } - public static GroupResponse createGroupResponse(List deviceList) { + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public String getClass_name() { + return class_name; + } + public void setClass_name(String class_name) { + this.class_name = class_name; + } + public static GroupResponse createDefaultGroupResponse(List deviceList) { String[] theList = new String[deviceList.size()]; int i = 0; for (DeviceDescriptor device : deviceList) { @@ -38,6 +59,23 @@ public class GroupResponse { theResponse.setAction(DeviceState.createDeviceState()); theResponse.setName("Lightset 0"); theResponse.setLights(theList); + theResponse.setType("LightGroup"); return theResponse; } + public static GroupResponse createOtherGroupResponse(List deviceList) { + String[] theList = new String[deviceList.size()]; + int i = 0; + for (DeviceDescriptor device : deviceList) { + theList[i] = device.getId(); + i++; + } + GroupResponse theResponse = new GroupResponse(); + theResponse.setAction(DeviceState.createDeviceState()); + theResponse.setName("AGroup"); + theResponse.setLights(theList); + theResponse.setType("Room"); + theResponse.setClass_name("Other"); + + return theResponse; + } } diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/HueApiResponse.java b/src/main/java/com/bwssystems/HABridge/api/hue/HueApiResponse.java index bee621c..fcc0adb 100644 --- a/src/main/java/com/bwssystems/HABridge/api/hue/HueApiResponse.java +++ b/src/main/java/com/bwssystems/HABridge/api/hue/HueApiResponse.java @@ -12,7 +12,7 @@ import com.google.gson.JsonObject; public class HueApiResponse { private Map lights; private Map scenes; - private Map groups; + private Map groups; private Map schedules; private Map sensors; private Map rules; @@ -44,11 +44,11 @@ public class HueApiResponse { this.scenes = scenes; } - public Map getGroups() { + public Map getGroups() { return groups; } - public void setGroups(Map groups) { + public void setGroups(Map groups) { this.groups = groups; } diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/HueConstants.java b/src/main/java/com/bwssystems/HABridge/api/hue/HueConstants.java index a77eca9..26f760f 100644 --- a/src/main/java/com/bwssystems/HABridge/api/hue/HueConstants.java +++ b/src/main/java/com/bwssystems/HABridge/api/hue/HueConstants.java @@ -1,7 +1,7 @@ package com.bwssystems.HABridge.api.hue; public class HueConstants { - public final static String HUB_VERSION = "01036562"; + public final static String HUB_VERSION = "01036659"; public final static String API_VERSION = "1.15.0"; public final static String MODEL_ID = "BSB002"; public final static String UUID_PREFIX = "2f402f80-da50-11e1-9b23-"; diff --git a/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java b/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java index 6e1a5de..75b14cb 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceDescriptor.java @@ -58,7 +58,10 @@ public class DeviceDescriptor{ private String contentBodyDim; @SerializedName("inactive") @Expose - private Boolean inactive; + private boolean inactive; + @SerializedName("noState") + @Expose + private boolean noState; private DeviceState deviceState; @@ -200,12 +203,38 @@ public class DeviceDescriptor{ this.deviceState = deviceState; } - public Boolean getInactive() { + public boolean isInactive() { return inactive; } - public void setInactive(Boolean inactive) { + public void setInactive(boolean inactive) { this.inactive = inactive; } -} + public boolean isNoState() { + return noState; + } + + public void setNoState(boolean noState) { + this.noState = noState; + } + + public boolean containsType(String aType) { + if(this.mapType.contains(aType)) + return true; + + if(this.deviceType.contains(aType)) + return true; + + if(this.onUrl.contains(aType)) + return true; + + if(this.dimUrl.contains(aType)) + return true; + + if(this.offUrl.contains(aType)) + return true; + + return false; + } +} \ 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 67a67de..a06a8d8 100644 --- a/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java +++ b/src/main/java/com/bwssystems/HABridge/dao/DeviceRepository.java @@ -77,7 +77,7 @@ public class DeviceRepository extends BackupHandler { public List findActive() { List list = new ArrayList(); for(DeviceDescriptor aDevice : new ArrayList(devices.values())) { - if(aDevice.getInactive() == null || !aDevice.getInactive()) + if(!aDevice.isInactive()) list.add(aDevice); } return list; diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 3631a1c..4ccadf6 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -9,6 +9,7 @@ import com.bwssystems.HABridge.api.hue.DeviceResponse; import com.bwssystems.HABridge.api.hue.DeviceState; import com.bwssystems.HABridge.api.hue.GroupResponse; import com.bwssystems.HABridge.api.hue.HueApiResponse; +import com.bwssystems.HABridge.api.hue.HueConfig; import com.bwssystems.HABridge.api.hue.HueError; import com.bwssystems.HABridge.api.hue.HueErrorResponse; import com.bwssystems.HABridge.api.hue.HuePublicConfig; @@ -73,16 +74,34 @@ public class HueMulator { response.header("Access-Control-Allow-Origin", request.headers("Origin")); response.type("application/json"); response.status(HttpStatus.SC_OK); - return basicListHandler("groups", request.params(":userid"), request.ip()); - }); + return groupsListHandler(request.params(":userid"), request.ip()); + } , new JsonTransformer()); // http://ip_address:port/api/{userId}/groups/{groupId} returns json // object for specified group. Only 0 is supported 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 groupsListHandler(request.params(":groupid"), request.params(":userid"), request.ip()); + 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); + 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"); + return ""; + }); + // http://ip_address:port/:userid/groups + // dummy handler + post(HUE_CONTEXT + "/:userid/groups", "application/json", (request, response) -> { + response.header("Access-Control-Allow-Origin", request.headers("Origin")); + response.type("application/json"); + response.status(HttpStatus.SC_OK); + log.debug("group add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body()); + return "[{\"success\":{\"id\":\"1\"}}]"; + }); // http://ip_address:port/api/{userId}/scenes returns json objects of // all scenes configured get(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> { @@ -91,6 +110,24 @@ public class HueMulator { response.status(HttpStatus.SC_OK); 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) -> { + 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"); + return ""; + }); + // http://ip_address:port/:userid/scenes + // dummy handler + post(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); + 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 // all schedules configured get(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> { @@ -99,6 +136,24 @@ public class HueMulator { response.status(HttpStatus.SC_OK); 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) -> { + 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"); + return ""; + }); + // http://ip_address:port/:userid/schedules + // dummy handler + post(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> { + 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()); + return "[{\"success\":{\"id\":\"1\"}}]"; + }); // http://ip_address:port/api/{userId}/sensors returns json objects of // all sensors configured get(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> { @@ -107,6 +162,24 @@ public class HueMulator { response.status(HttpStatus.SC_OK); 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) -> { + 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"); + return ""; + }); + // http://ip_address:port/:userid/sensors + // dummy handler + post(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> { + 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()); + return "[{\"success\":{\"id\":\"1\"}}]"; + }); // http://ip_address:port/api/{userId}/rules returns json objects of all // rules configured get(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> { @@ -115,6 +188,24 @@ public class HueMulator { response.status(HttpStatus.SC_OK); 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) -> { + 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"); + return ""; + }); + // http://ip_address:port/:userid/rules + // dummy handler + post(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> { + 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()); + return "[{\"success\":{\"id\":\"1\"}}]"; + }); // http://ip_address:port/api/{userId}/resourcelinks returns json // objects of all resourcelinks configured get(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> { @@ -123,6 +214,24 @@ public class HueMulator { response.status(HttpStatus.SC_OK); 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) -> { + 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"); + return ""; + }); + // http://ip_address:port/:userid/resourcelinks + // dummy handler + post(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> { + 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()); + return "[{\"success\":{\"id\":\"1\"}}]"; + }); // http://ip_address:port/api/{userId}/lights returns json objects of // all lights configured get(HUE_CONTEXT + "/:userid/lights", "application/json", (request, response) -> { @@ -194,6 +303,28 @@ public class HueMulator { response.status(HttpStatus.SC_OK); return getConfig(request.params(":userid"), request.ip()); } , new JsonTransformer()); + // http://ip_address:port/:userid/config CORS request + options(HUE_CONTEXT + "/:userid/config", "application/json", (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"); + return ""; + }); + // http://ip_address:port/:userid/config uses json + // object to set the config. this is to handle swupdates + put(HUE_CONTEXT + "/:userid/config", "application/json", (request, response) -> { + 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()); + HueConfig aConfig = aGsonHandler.fromJson(request.body(), HueConfig.class); + if(aConfig.getPortalservices() != null) { + return "[{\"success\":{\"/config/portalservices\":true}}]"; + } + return "[{\"success\":{\"/config/name\":\"My bridge\"}}]"; + }); // http://ip_address:port/api/{userId} returns json objects for the full // state @@ -463,7 +594,7 @@ public class HueMulator { } if (!found) { - log.debug("Valudate user, No User supplied"); + log.debug("Validate user, No User supplied"); return HueErrorResponse.createResponse("1", "/api/" + aUser, "unauthorized user", null, null, null).getTheErrors(); } @@ -496,14 +627,32 @@ public class HueMulator { return "{}"; } + private Object groupsListHandler(String userId, String requestIp) { + log.debug("hue group list requested: " + userId + " from " + requestIp); + HueError[] theErrors = null; + Map groupResponseMap = null; + theErrors = validateWhitelistUser(userId, false); + if (theErrors == null) { + groupResponseMap = new HashMap(); + groupResponseMap.put("1", (GroupResponse) this.groupsIdHandler("1", userId, requestIp)); + return groupResponseMap; + } - private Object groupsListHandler(String groupId, String userId, String requestIp) { - log.debug("hue group 0 list requested: " + userId + " from " + requestIp); + return theErrors; + } + + + private Object groupsIdHandler(String groupId, String userId, String requestIp) { + log.debug("hue group id: <" + groupId + "> requested: " + userId + " from " + requestIp); HueError[] theErrors = null; theErrors = validateWhitelistUser(userId, false); if (theErrors == null) { if (groupId.equalsIgnoreCase("0")) { - GroupResponse theResponse = GroupResponse.createGroupResponse(repository.findAll()); + GroupResponse theResponse = GroupResponse.createDefaultGroupResponse(repository.findActive()); + return theResponse; + } + if (!groupId.equalsIgnoreCase("0")) { + GroupResponse theResponse = GroupResponse.createOtherGroupResponse(repository.findActive()); return theResponse; } theErrors = HueErrorResponse.createResponse("3", userId + "/groups/" + groupId, "Object not found", null, null, null).getTheErrors(); @@ -582,7 +731,7 @@ public class HueMulator { log.info("Traceupnp: hue api/:userid/config config requested: " + userId + " from " + ipAddress); log.debug("hue api config requested: " + userId + " from " + ipAddress); if (validateWhitelistUser(userId, true) != null) { - log.debug("Valudate user, No User supplied, returning public config"); + log.debug("hue api config requested, No User supplied, returning public config"); HuePublicConfig apiResponse = HuePublicConfig.createConfig("Philips hue", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getHubversion()); return apiResponse; @@ -603,15 +752,8 @@ public class HueMulator { HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getWhitelist(), bridgeSettings.getHubversion()); - Object aReturn = this.lightsListHandler(userId, ipAddress); - Map deviceList = new HashMap(); - if(aReturn.getClass() == deviceList.getClass()) { - deviceList = (Map) aReturn; - apiResponse.setLights(deviceList); - } - else { - return aReturn; - } + apiResponse.setLights((Map) this.lightsListHandler(userId, ipAddress)); + apiResponse.setGroups((Map) this.groupsListHandler(userId, ipAddress)); return apiResponse; } @@ -727,8 +869,10 @@ public class HueMulator { } state = device.getDeviceState(); - if (state == null) + if (state == null) { state = DeviceState.createDeviceState(); + device.setDeviceState(state); + } if (targetBri != null || targetBriInc != null) { url = device.getDimUrl(); @@ -816,8 +960,13 @@ public class HueMulator { } if (responseString == null || !responseString.contains("[{\"error\":")) { - responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, targetBriInc); - device.setDeviceState(state); + if(!device.isNoState()) { + responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, targetBriInc); + device.setDeviceState(state); + } else { + DeviceState dummyState = DeviceState.createDeviceState(); + responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, dummyState, targetBri, targetBriInc); + } } return responseString; 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 bc538af..ebc5af8 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java @@ -13,20 +13,13 @@ import com.bwssystems.HABridge.BridgeSettingsDescriptor; import com.bwssystems.HABridge.Home; import com.bwssystems.HABridge.NamedIP; import com.bwssystems.HABridge.api.CallItem; -import com.bwssystems.HABridge.api.NameValue; -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.MultiCommandUtil; -import com.bwssystems.HABridge.plugins.http.HTTPHandler; -import com.google.gson.Gson; public class DomoticzHome implements Home { private static final Logger log = LoggerFactory.getLogger(DomoticzHome.class); private Map domoticzs; private Boolean validDomoticz; - private HTTPHandler anHttpHandler; public DomoticzHome(BridgeSettingsDescriptor bridgeSettings) { super(); @@ -67,30 +60,14 @@ public class DomoticzHome implements Home { DomoticzDevice theDevice = devices.next(); theDeviceList.add(theDevice); } - anHttpHandler = new HTTPHandler(); return true; } @Override public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) { - log.debug("executing HUE api request to Domoticz Http " + anItem.getItem().getAsString()); - String responseString = null; - - String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(), - intensity, targetBri, targetBriInc, false); - String aBody; - aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(), - intensity, targetBri, targetBriInc, false); - // make call - if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody, - new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) { - 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); - } - return responseString; + // Not a device handler + return null; } @Override 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 78a3045..d8410d2 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalHome.java @@ -13,21 +13,13 @@ import com.bwssystems.HABridge.BridgeSettingsDescriptor; import com.bwssystems.HABridge.Home; import com.bwssystems.HABridge.NamedIP; import com.bwssystems.HABridge.api.CallItem; -import com.bwssystems.HABridge.api.NameValue; -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.MultiCommandUtil; -import com.bwssystems.HABridge.hue.TimeDecode; -import com.bwssystems.HABridge.plugins.http.HTTPHandler; -import com.google.gson.Gson; public class HalHome implements Home { private static final Logger log = LoggerFactory.getLogger(HalHome.class); private Map hals; private Boolean validHal; - private HTTPHandler anHttpHandler; public HalHome(BridgeSettingsDescriptor bridgeSettings) { super(); @@ -106,42 +98,16 @@ public class HalHome implements Home { Iterator devices = theSourceList.iterator(); while(devices.hasNext()) { HalDevice theDevice = devices.next(); - HalDevice aNewHalDevice = new HalDevice(); - aNewHalDevice.setHaldevicetype(theDevice.getHaldevicetype()); - aNewHalDevice.setHaldevicename(theDevice.getHaldevicename()); - aNewHalDevice.setButtons(theDevice.getButtons()); - aNewHalDevice.setHaladdress(hals.get(theKey).getHalAddress().getIp()); - aNewHalDevice.setHalname(theKey); - theDeviceList.add(aNewHalDevice); + theDeviceList.add(theDevice); } - anHttpHandler = new HTTPHandler(); return true; } @Override public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) { - log.debug("executing HUE api request to HAL Http " + anItem.getItem().getAsString()); - String responseString = null; - - String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(), - intensity, targetBri, targetBriInc, false); - anUrl = TimeDecode.replaceTimeValue(anUrl); - String aBody = null; - if(anItem.getHttpBody()!= null && !anItem.getHttpBody().isEmpty()) { - aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(), - intensity, targetBri, targetBriInc, false); - aBody = TimeDecode.replaceTimeValue(aBody); - } - // make call - if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody, - new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) { - 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); - } - return responseString; + // Not a device handler + return null; } @Override diff --git a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalInfo.java b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalInfo.java index 694e2cb..53b716e 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hal/HalInfo.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hal/HalInfo.java @@ -121,6 +121,8 @@ public class HalInfo { HalDevice aNewHalDevice = new HalDevice(); aNewHalDevice.setHaldevicetype(deviceType); aNewHalDevice.setHaldevicename(theDevice.getDeviceName()); + aNewHalDevice.setHaladdress(halAddress.getIp()); + aNewHalDevice.setHalname(halAddress.getName()); deviceList.add(aNewHalDevice); } 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 afc3549..48ae3f2 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/hass/HomeAssistant.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/hass/HomeAssistant.java @@ -37,7 +37,7 @@ public class HomeAssistant { log.debug("calling HomeAssistant: " + aCommand.getHassName() + " - " + aCommand.getEntityId() + " - " + aCommand.getState() + " - " + aCommand.getBri()); String aUrl = null; - if(hassAddress.getSecure()) + if(hassAddress.getSecure() != null && hassAddress.getSecure()) aUrl = "https"; else aUrl = "http"; @@ -80,7 +80,7 @@ public class HomeAssistant { headers = new NameValue[1]; headers[0] = password; } - if(hassAddress.getSecure()) + if(hassAddress.getSecure() != null && hassAddress.getSecure()) theUrl = "https"; else theUrl = "http"; 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 8beb2d4..a3e331a 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/mqtt/MQTTHome.java @@ -97,18 +97,16 @@ public class MQTTHome implements Home { if(mqttMessages[z].getCount() != null && mqttMessages[z].getCount() > 0) theCount = mqttMessages[z].getCount(); for(int y = 0; y < theCount; y++) { - if( y > 0 || z > 0) { - log.debug("publishing message: " + mqttMessages[y].getClientId() + " - " - + mqttMessages[y].getTopic() + " - " + mqttMessages[y].getMessage() - + " - count: " + String.valueOf(z)); + log.debug("publishing message: " + mqttMessages[y].getClientId() + " - " + + mqttMessages[y].getTopic() + " - " + mqttMessages[y].getMessage() + + " - count: " + String.valueOf(z)); - MQTTHandler mqttHandler = getMQTTHandler(mqttMessages[y].getClientId()); - if (mqttHandler == null) { - log.warn("Should not get here, no mqtt hanlder available"); - } else { - mqttHandler.publishMessage(mqttMessages[y].getTopic(), mqttMessages[y].getMessage()); - } - } + MQTTHandler mqttHandler = getMQTTHandler(mqttMessages[y].getClientId()); + if (mqttHandler == null) { + log.warn("Should not get here, no mqtt hanlder available"); + } else { + mqttHandler.publishMessage(mqttMessages[y].getTopic(), mqttMessages[y].getMessage()); + } } } } else { diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 660d256..bc77ffd 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -161,6 +161,25 @@ app.service ('bridgeService', function ($http, $window, ngToast) { return a.indexOf(b) >= 0; } + 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) + return true; + + + return false; + } this.compareHarmonyNumber = function(r1, r2) { if (r1.device !== undefined) { if (r1.device.id === r2.device.id) @@ -2338,8 +2357,10 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi bridgeService.addDevice($scope.device).then( function () { $scope.clearDevice(); + $location.path('/'); }, function (error) { + bridgeService.displayWarn("Error adding/updating device....", error); } ); @@ -2405,13 +2426,13 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi }); -app.filter('configuredVeraDevices', function () { +app.filter('configuredVeraDevices', 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(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "veraDevice"){ + if(bridgeService.deviceContainsType(input[i], "veraDevice")){ out.push(input[i]); } } @@ -2419,13 +2440,13 @@ app.filter('configuredVeraDevices', function () { } }); -app.filter('configuredVeraScenes', function () { +app.filter('configuredVeraScenes', 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(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "veraScene"){ + if(bridgeService.deviceContainsType(input[i], "veraScene")){ out.push(input[i]); } } @@ -2439,7 +2460,7 @@ app.filter('configuredNestItems', function (bridgeService) { if(input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "nest")){ + if(bridgeService.deviceContainsType(input[i], "nest")){ out.push(input[i]); } } @@ -2453,7 +2474,7 @@ app.filter('configuredHueItems', function (bridgeService) { if(input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "hue")){ + if(bridgeService.deviceContainsType(input[i], "hue")){ out.push(input[i]); } } @@ -2467,7 +2488,7 @@ app.filter('configuredHalItems', function (bridgeService) { if(input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "hal")){ + if(bridgeService.deviceContainsType(input[i], "hal")){ out.push(input[i]); } } @@ -2475,13 +2496,13 @@ app.filter('configuredHalItems', function (bridgeService) { } }); -app.filter('configuredHarmonyActivities', function () { +app.filter('configuredHarmonyActivities', 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(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "harmonyActivity"){ + if(bridgeService.deviceContainsType(input[i], "harmonyActivity")){ out.push(input[i]); } } @@ -2489,13 +2510,13 @@ app.filter('configuredHarmonyActivities', function () { } }); -app.filter('configuredHarmonyButtons', function () { - return function(input) { +app.filter('configuredHarmonyButtons', 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(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "harmonyButtons"){ + if (bridgeService.deviceContainsType(input[i], "harmonyButton")) { out.push(input[i]); } } @@ -2503,13 +2524,13 @@ app.filter('configuredHarmonyButtons', function () { } }); -app.filter('configuredMqttMsgs', function () { +app.filter('configuredMqttMsgs', 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(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "mqttMessage"){ + if (bridgeService.deviceContainsType(input[i], "mqtt")) { out.push(input[i]); } } @@ -2523,7 +2544,21 @@ app.filter('configuredHassItems', function (bridgeService) { if(input === undefined || input === null || input.length === undefined) return out; for (var i = 0; i < input.length; i++) { - if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "hass")){ + if (bridgeService.deviceContainsType(input[i], "hass")) { + out.push(input[i]); + } + } + return out; + } +}); + +app.filter('configuredDomoticzItems', 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], "domoticz")) { out.push(input[i]); } } diff --git a/src/main/resources/public/views/configuration.html b/src/main/resources/public/views/configuration.html index 32d6e4b..07a9962 100644 --- a/src/main/resources/public/views/configuration.html +++ b/src/main/resources/public/views/configuration.html @@ -43,6 +43,7 @@ Type Target Inactive + No State Actions @@ -53,6 +54,7 @@ {{device.deviceType}} {{device.targetDevice}} {{device.inactive}} + {{device.noState}}