diff --git a/pom.xml b/pom.xml index cec7347..3ce2b30 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 2.0.7-hal-c + 2.0.7-hal-d jar HA Bridge @@ -89,7 +89,7 @@ com.google.code.gson gson - 2.2.4 + 2.6.2 com.fasterxml.jackson.core diff --git a/src/main/java/com/bwssystems/hal/DeviceElements.java b/src/main/java/com/bwssystems/hal/DeviceElements.java index 3f6e1e2..9ea4241 100644 --- a/src/main/java/com/bwssystems/hal/DeviceElements.java +++ b/src/main/java/com/bwssystems/hal/DeviceElements.java @@ -1,8 +1,10 @@ package com.bwssystems.hal; import java.util.List; +import com.google.gson.annotations.SerializedName; public class DeviceElements { + @SerializedName(value="DeviceElements", alternate={"SceneElements", "GroupElements", "HVACElements", "MacroElements", "IrElements", "IrButtons"}) private List DeviceElements; public List getDeviceElements() { diff --git a/src/main/java/com/bwssystems/hal/DeviceName.java b/src/main/java/com/bwssystems/hal/DeviceName.java index 948a95a..3344e24 100644 --- a/src/main/java/com/bwssystems/hal/DeviceName.java +++ b/src/main/java/com/bwssystems/hal/DeviceName.java @@ -1,6 +1,9 @@ package com.bwssystems.hal; +import com.google.gson.annotations.SerializedName; + public class DeviceName { + @SerializedName(value="DeviceName", alternate={"SceneName", "GroupName", "HVACName", "MacroName", "IrName", "IrButton"}) private String DeviceName; public String getDeviceName() { diff --git a/src/main/java/com/bwssystems/hal/HVACElements.java b/src/main/java/com/bwssystems/hal/HVACElements.java deleted file mode 100644 index 446ef42..0000000 --- a/src/main/java/com/bwssystems/hal/HVACElements.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.bwssystems.hal; - -import java.util.List; - -public class HVACElements { - private List HVACElements; - - public List getHVACElements() { - return HVACElements; - } - - public void setHVACElements(List hVACElements) { - HVACElements = hVACElements; - } -} diff --git a/src/main/java/com/bwssystems/hal/HVACName.java b/src/main/java/com/bwssystems/hal/HVACName.java deleted file mode 100644 index b4fcd6d..0000000 --- a/src/main/java/com/bwssystems/hal/HVACName.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.bwssystems.hal; - -public class HVACName { - private String HVACName; - - public String getHVACName() { - return HVACName; - } - - public void setHVACName(String hVACName) { - HVACName = hVACName; - } -} diff --git a/src/main/java/com/bwssystems/hal/HalDevice.java b/src/main/java/com/bwssystems/hal/HalDevice.java index 62dd241..24373c0 100644 --- a/src/main/java/com/bwssystems/hal/HalDevice.java +++ b/src/main/java/com/bwssystems/hal/HalDevice.java @@ -5,6 +5,7 @@ public class HalDevice { private String haldevicename; private String haladdress; private String halname; + private DeviceElements buttons; public String getHaldevicetype() { return haldevicetype; } @@ -29,4 +30,10 @@ public class HalDevice { public void setHalname(String halname) { this.halname = halname; } + public DeviceElements getButtons() { + return buttons; + } + public void setButtons(DeviceElements buttons) { + this.buttons = buttons; + } } diff --git a/src/main/java/com/bwssystems/hal/HalHome.java b/src/main/java/com/bwssystems/hal/HalHome.java index 5a35893..0546339 100644 --- a/src/main/java/com/bwssystems/hal/HalHome.java +++ b/src/main/java/com/bwssystems/hal/HalHome.java @@ -69,7 +69,27 @@ public class HalHome { if(theResponse != null) addHalDevices(deviceList, theResponse, key); else - log.warn("Cannot get HVAC for Hal with name: " + key); + log.warn("Cannot get Homes for Hal with name: " + key); + theResponse = hals.get(key).getGroups(); + if(theResponse != null) + addHalDevices(deviceList, theResponse, key); + else + log.warn("Cannot get Groups for Hal with name: " + key); + theResponse = hals.get(key).getMacros(); + if(theResponse != null) + addHalDevices(deviceList, theResponse, key); + else + log.warn("Cannot get Macros for Hal with name: " + key); + theResponse = hals.get(key).getScenes(); + if(theResponse != null) + addHalDevices(deviceList, theResponse, key); + else + log.warn("Cannot get Scenes for Hal with name: " + key); + theResponse = hals.get(key).getButtons(); + if(theResponse != null) + addHalDevices(deviceList, theResponse, key); + else + log.warn("Cannot get Buttons for Hal with name: " + key); } return deviceList; } @@ -81,6 +101,7 @@ public class HalHome { 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); diff --git a/src/main/java/com/bwssystems/hal/HalInfo.java b/src/main/java/com/bwssystems/hal/HalInfo.java index ebaa23e..4acd36b 100644 --- a/src/main/java/com/bwssystems/hal/HalInfo.java +++ b/src/main/java/com/bwssystems/hal/HalInfo.java @@ -15,12 +15,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bwssystems.HABridge.NamedIP; +import com.bwssystems.util.TextStringFormatter; import com.google.gson.Gson; public class HalInfo { private static final Logger log = LoggerFactory.getLogger(HalInfo.class); private static final String DEVICE_REQUEST = "/DeviceData!DeviceCmd=GetNames!DeviceType="; private static final String HVAC_REQUEST = "/HVACData!HVACCmd=GetNames"; + private static final String GROUP_REQUEST = "/GroupData!GroupCmd=GetNames"; + private static final String MACRO_REQUEST = "/MacroData!MacroCmd=GetNames"; + private static final String SCENE_REQUEST = "/SceneData!SceneCmd=GetNames"; + private static final String IRDATA_REQUEST = "/IrData!IRCmd=GetNames"; + private static final String IRBUTTON_REQUEST = "/IrData!IRCmd=GetButtons!IrDevice="; private static final String TOKEN_REQUEST = "?Token="; private static final String LIGHT_REQUEST = "Light"; private static final String APPL_REQUEST = "Appl"; @@ -28,7 +34,11 @@ public class HalInfo { private static final String THEATRE_REQUEST = "Theatre"; private static final String CUSTOM_REQUEST = "Custom"; private static final String HVAC_TYPE = "HVAC"; - private static final String HOME_TYPE = "HOME"; + private static final String HOME_TYPE = "Home"; + private static final String GROUP_TYPE = "Group"; + private static final String MACRO_TYPE = "Macro"; + private static final String SCENE_TYPE = "Scene"; + private static final String IRDATA_TYPE = "IrData"; private HttpClient httpClient; private NamedIP halAddress; private String theToken; @@ -57,7 +67,25 @@ public class HalInfo { } public List getHVAC() { - return getHalHVAC(HVAC_REQUEST + TOKEN_REQUEST, HVAC_TYPE); + return getHalDevices(HVAC_REQUEST + TOKEN_REQUEST, HVAC_TYPE); + } + + public List getGroups() { + return getHalDevices(GROUP_REQUEST + TOKEN_REQUEST, GROUP_TYPE); + } + + public List getMacros() { + return getHalDevices(MACRO_REQUEST + TOKEN_REQUEST, MACRO_TYPE); + } + + public List getScenes() { + return getHalDevices(SCENE_REQUEST + TOKEN_REQUEST, SCENE_TYPE); + } + + public List getButtons() { + List irDataDevices = getHalDevices(IRDATA_REQUEST + TOKEN_REQUEST, IRDATA_TYPE); + + return getDeviceButtons(irDataDevices); } public List getHome(String theDeviceName) { @@ -79,7 +107,7 @@ public class HalInfo { theUrl = "http://" + halAddress.getIp() + apiType + theToken; theData = doHttpGETRequest(theUrl); if(theData != null) { - log.debug("GET HalApiResponse - data: " + theData); + log.debug("GET " + deviceType + " HalApiResponse - data: " + theData); theHalApiResponse = new Gson().fromJson(theData, DeviceElements.class); if(theHalApiResponse.getDeviceElements() == null) { StatusDescription theStatus = new Gson().fromJson(theData, StatusDescription.class); @@ -109,44 +137,43 @@ public class HalInfo { return deviceList; } - private List getHalHVAC(String apiType, String deviceType) { - HVACElements theHalApiResponse = null; + private List getDeviceButtons(List theIrDevices) { + DeviceElements theHalApiResponse = null; List deviceList = null; String theUrl = null; - String theData; - theUrl = "http://" + halAddress.getIp() + apiType + theToken; - theData = doHttpGETRequest(theUrl); - if(theData != null) { - log.debug("GET HalApiResponse - data: " + theData); - theHalApiResponse = new Gson().fromJson(theData, HVACElements.class); - if(theHalApiResponse.getHVACElements() == null) { - StatusDescription theStatus = new Gson().fromJson(theData, StatusDescription.class); - if(theStatus.getStatus() == null) { - log.warn("Cannot get an devices for type " + deviceType + " for hal " + halAddress.getName() + " as response is not parsable."); - } - else { - log.warn("Cannot get an devices for type " + deviceType + " for hal " + halAddress.getName() + ". Status: " + theStatus.getStatus() + ", with description: " + theStatus.getDescription()); - } - return deviceList; - } - deviceList = new ArrayList(); - - Iterator theDeviceNames = theHalApiResponse.getHVACElements().iterator(); - while(theDeviceNames.hasNext()) { - HVACName theDevice = theDeviceNames.next(); - HalDevice aNewHalDevice = new HalDevice(); - aNewHalDevice.setHaldevicetype(deviceType); - aNewHalDevice.setHaldevicename(theDevice.getHVACName()); - deviceList.add(aNewHalDevice); - - } - } - else { - log.warn("Get Hal device types " + deviceType + " for " + halAddress.getName() + " - returned null, no data."); - } - return deviceList; - } + String theData; + Iterator theHalDevices = theIrDevices.iterator(); + deviceList = new ArrayList(); + while (theHalDevices.hasNext()) { + HalDevice theHalDevice = theHalDevices.next(); + theUrl = "http://" + halAddress.getIp() + IRBUTTON_REQUEST + TextStringFormatter.forQuerySpaceUrl(theHalDevice.getHaldevicename()) + TOKEN_REQUEST + theToken; + theData = doHttpGETRequest(theUrl); + if (theData != null) { + log.debug("GET IrData for IR Device " + theHalDevice.getHaldevicename() + " HalApiResponse - data: " + theData); + theHalApiResponse = new Gson().fromJson(theData, DeviceElements.class); + if (theHalApiResponse.getDeviceElements() == null) { + StatusDescription theStatus = new Gson().fromJson(theData, StatusDescription.class); + if (theStatus.getStatus() == null) { + log.warn("Cannot get buttons for IR Device " + theHalDevice.getHaldevicename() + " for hal " + + halAddress.getName() + " as response is not parsable."); + } else { + log.warn("Cannot get buttons for IR Device " + theHalDevice.getHaldevicename() + " for hal " + + halAddress.getName() + ". Status: " + theStatus.getStatus() + ", with description: " + + theStatus.getDescription()); + } + return deviceList; + } + theHalDevice.setButtons(theHalApiResponse); + deviceList.add(theHalDevice); + + } else { + log.warn("Get Hal buttons for IR Device " + theHalDevice.getHaldevicename() + " for " + + halAddress.getName() + " - returned null, no data."); + } + } + return deviceList; + } // This function executes the url against the hal protected String doHttpGETRequest(String url) { diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 72f833e..545e8eb 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -1396,37 +1396,83 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic $scope.buildDeviceUrls = function (haldevice, dim_control) { bridgeService.clearDevice(); $scope.device = $scope.bridge.device; - $scope.device.deviceType = "switch"; + var preOnCmd = ""; + var preDimCmd = ""; + var preOffCmd = ""; + var nameCmd = "" + var postCmd = "?Token=" + $scope.bridge.settings.haltoken; + if(haldevice.haldevicetype == "Group") { + $scope.device.deviceType = "group"; + preOnCmd = "/GroupService!GroupCmd=On"; + preOffCmd = "/GroupService!GroupCmd=Off"; + nameCmd = "!GroupName="; + } + else if(haldevice.haldevicetype == "Macro") { + $scope.device.deviceType = "macro"; + preOnCmd = "/MacroService!MacroCmd=Set!MacroName="; + preOffCmd = preOnCmd; + } + else if(haldevice.haldevicetype == "Scene") { + $scope.device.deviceType = "scene"; + preOnCmd = "/SceneService!SceneCmd=Set!SceneName="; + preOffCmd = preOnCmd; + } + else { + $scope.device.deviceType = "switch"; + preOnCmd = "/DeviceService!DeviceCmd=SetDevice!DeviceValue=On"; + preDimCmd = "/DeviceService!DeviceCmd=SetDevice!DeviceValue=Dim!DevicePercent="; + preOffCmd = "/DeviceService!DeviceCmd=SetDevice!DeviceValue=Off"; + nameCmd = "!DeviceName="; + } $scope.device.name = haldevice.haldevicename; $scope.device.targetDevice = haldevice.halname; $scope.device.mapType = "halDevice"; $scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname; - 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) && $scope.device.deviceType == "switch") $scope.device.dimUrl = "http://" + haldevice.haladdress - + "/DeviceService!DeviceName=" - + haldevice.haldevicename.replaceAll(" ", "%20") - + "!DeviceCmd=SetDevice!DeviceValue=Dim!DevicePercent=" + + preDimCmd + dim_control - + "?Token=" - + $scope.bridge.settings.haltoken; + + nameCmd + + haldevice.haldevicename.replaceAll(" ", "%20") + + postCmd; else $scope.device.dimUrl = "http://" + haldevice.haladdress - + "/DeviceService!DeviceName=" + + preOnCmd + + nameCmd + haldevice.haldevicename.replaceAll(" ", "%20") - + "!DeviceCmd=SetDevice!DeviceValue=On?Token=" - + $scope.bridge.settings.haltoken; + + postCmd; $scope.device.onUrl = "http://" + haldevice.haladdress - + "/DeviceService!DeviceName=" + + preOnCmd + + nameCmd + haldevice.haldevicename.replaceAll(" ", "%20") - + "!DeviceCmd=SetDevice!DeviceValue=On?Token=" - + $scope.bridge.settings.haltoken; + + postCmd; $scope.device.offUrl = "http://" + haldevice.haladdress - + "/DeviceService!DeviceName=" + + preOffCmd + + nameCmd + haldevice.haldevicename.replaceAll(" ", "%20") - + "!DeviceCmd=SetDevice!DeviceValue=Off?Token=" - + $scope.bridge.settings.haltoken; - - + + postCmd; + }; + + $scope.buildButtonUrls = function (haldevice, onbutton, offbutton) { + var currentOn = $scope.device.onUrl; + var currentOff = $scope.device.offUrl; + var actionOn = angular.fromJson(onbutton); + var actionOff = angular.fromJson(offbutton); + if( $scope.device.mapType == "halButton") { + $scope.device.mapId = $scope.device.mapId + "-" + actionOn.DeviceName; + $scope.device.onUrl = currentOn.substr(0, currentOn.indexOf("]")) + ",{\"item\":\"http://" + haldevice.haladdress + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOn.DeviceName.replaceAll(" ", "%20") + "?Token=" + $scope.bridge.settings.haltoken +"\"}]"; + $scope.device.offUrl = currentOff.substr(0, currentOff.indexOf("]")) + ",{\"item\":\"http://" + haldevice.haladdress + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOff.DeviceName.replaceAll(" ", "%20") + "?Token=" + $scope.bridge.settings.haltoken + "\"}]"; + } + else if ($scope.device.mapType == null || $scope.device.mapType == "") { + bridgeService.clearDevice(); + $scope.device.deviceType = "button"; + $scope.device.targetDevice = haldevice.halname; + $scope.device.name = haldevice.haldevicename; + $scope.device.mapType = "halButton"; + $scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-" + actionOn.DeviceName; + $scope.device.onUrl = "[{\"item\":\"http://" + haldevice.haladdress + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOn.DeviceName.replaceAll(" ", "%20") + "?Token=" + $scope.bridge.settings.haltoken + "\"}]"; + $scope.device.offUrl = "[{\"item\":\"http://" + haldevice.haladdress + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOff.DeviceName.replaceAll(" ", "%20") + "?Token=" + $scope.bridge.settings.haltoken + "\"}]"; + } }; $scope.buildHALHomeUrls = function (haldevice) { @@ -1445,7 +1491,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic $scope.device.deviceType = "thermo"; $scope.device.name = haldevice.haldevicename + " Heat"; $scope.device.targetDevice = haldevice.halname; - $scope.device.mapType = "HALThermoSet"; + $scope.device.mapType = "halThermoSet"; $scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-SetHeat"; $scope.device.onUrl = "http://" + haldevice.haladdress + "/HVACService!HVACCmd=Set!HVACName=" @@ -1468,7 +1514,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic $scope.device.deviceType = "thermo"; $scope.device.name = haldevice.haldevicename + " Cool"; $scope.device.targetDevice = haldevice.halname; - $scope.device.mapType = "HALThermoSet"; + $scope.device.mapType = "halThermoSet"; $scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-SetCool"; $scope.device.onUrl = "http://" + haldevice.haladdress + "/HVACService!HVACCmd=Set!HVACName=" @@ -1491,7 +1537,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic $scope.device.deviceType = "thermo"; $scope.device.name = haldevice.haldevicename + " Auto"; $scope.device.targetDevice = haldevice.halname; - $scope.device.mapType = "HALThermoSet"; + $scope.device.mapType = "halThermoSet"; $scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-SetAuto"; $scope.device.onUrl = "http://" + haldevice.haladdress + "/HVACService!HVACCmd=Set!HVACName=" @@ -1509,7 +1555,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic $scope.device.deviceType = "thermo"; $scope.device.name = haldevice.haldevicename + " Thermostat"; $scope.device.targetDevice = haldevice.halname; - $scope.device.mapType = "HALThermoSet"; + $scope.device.mapType = "halThermoSet"; $scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-TurnOff"; $scope.device.onUrl = "http://" + haldevice.haladdress + "/HVACService!HVACCmd=Set!HVACName=" @@ -1527,7 +1573,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic $scope.device.deviceType = "thermo"; $scope.device.name = haldevice.haldevicename + " Fan"; $scope.device.targetDevice = haldevice.halname; - $scope.device.mapType = "HALThermoSet"; + $scope.device.mapType = "halThermoSet"; $scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-SetFan"; $scope.device.onUrl = "http://" + haldevice.haladdress + "/HVACService!HVACCmd=Set!HVACName=" @@ -1638,12 +1684,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; }; - $scope.deleteDeviceByMapId = function (haldevicename, halname, mapType) { - var id = haldevicename + "-" + halname; - if(mapType == "HOME") - id = id + "-HomeAway"; - if(mapType == "HALThermoSet") - id = id + "-SetAuto"; + $scope.deleteDeviceByMapId = function (id, mapType) { $scope.bridge.mapandid = { id, mapType }; ngDialog.open({ template: 'deleteMapandIdDialog', @@ -1906,17 +1947,7 @@ app.filter('unavailableHalDeviceId', function(bridgeService) { if(input == null) return out; for (var i = 0; i < input.length; i++) { - if(bridgeService.findDeviceByMapId(input[i].haldevicename + "-" + input[i].halname, input[i].halname, "halDevice")){ - out.push(input[i]); - } - } - for (var i = 0; i < input.length; i++) { - if(bridgeService.findDeviceByMapId(input[i].haldevicename + "-" + input[i].halname + "-HomeAway", input[i].halname, "halHome")){ - out.push(input[i]); - } - } - for (var i = 0; i < input.length; i++) { - if(input[i].mapType == "HALThermoSet"){ + if(input[i].mapType != null && bridgeService.aContainsB(input[i].mapType, "hal")){ out.push(input[i]); } } diff --git a/src/main/resources/public/views/editdevice.html b/src/main/resources/public/views/editdevice.html index 3ffc52b..0d42a26 100644 --- a/src/main/resources/public/views/editdevice.html +++ b/src/main/resources/public/views/editdevice.html @@ -71,6 +71,8 @@ + + @@ -97,6 +99,8 @@ + + - -
    + +
    • + ng-click="deleteDeviceByMapId(device.mapId, device.mapType)">Delete